Files
paint-ui/components/editor/tool-options.tsx
Sebastian Krüger b7b072f6d2 feat: improve UI and transparency support
UI Improvements:
- Style scrollbars with primary color accent
- Scrollbar thumb transitions on hover (40% → 60% → 80% opacity)
- Add fill tool options to toolbar (color picker + opacity)
- Support for Firefox with scrollbar-color property

Transparency Support:
- Set default canvas background to transparent
- First layer now transparent instead of white fill
- Enables creating images with transparency
- Checkerboard pattern shows through transparent areas
- Proper PNG export support with alpha channel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 09:17:12 +01:00

214 lines
7.4 KiB
TypeScript

'use client';
import { useToolStore } from '@/store';
import { useShapeStore } from '@/store/shape-store';
import { useSelectionStore } from '@/store/selection-store';
export function ToolOptions() {
const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore();
const { settings: shapeSettings, setShapeType } = useShapeStore();
const { selectionType, setSelectionType } = useSelectionStore();
// Drawing tools: brush, pencil, eraser
const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool);
const showHardness = ['brush'].includes(activeTool);
const showColor = ['brush', 'pencil'].includes(activeTool);
const showFlow = ['brush'].includes(activeTool);
// Fill tool
const isFillTool = activeTool === 'fill';
// Shape tool
const isShapeTool = activeTool === 'shape';
// Selection tool
const isSelectionTool = activeTool === 'select';
// Don't show options bar if no options available
if (!isDrawingTool && !isFillTool && !isShapeTool && !isSelectionTool) {
return null;
}
return (
<div className="flex items-center gap-6 px-4 flex-1">
{/* Drawing Tools Options */}
{isDrawingTool && (
<>
{showColor && (
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Color:
</label>
<input
type="color"
value={settings.color}
onChange={(e) => setColor(e.target.value)}
className="h-8 w-16 rounded border border-border cursor-pointer"
/>
<input
type="text"
value={settings.color}
onChange={(e) => setColor(e.target.value)}
className="w-24 px-2 py-1 text-xs rounded border border-border bg-background text-foreground"
/>
</div>
)}
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Size:
</label>
<input
type="range"
min="1"
max="200"
value={settings.size}
onChange={(e) => setSize(Number(e.target.value))}
className="w-32"
/>
<span className="text-sm text-muted-foreground w-12">
{settings.size}px
</span>
</div>
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Opacity:
</label>
<input
type="range"
min="0"
max="100"
value={settings.opacity * 100}
onChange={(e) => setOpacity(Number(e.target.value) / 100)}
className="w-32"
/>
<span className="text-sm text-muted-foreground w-10">
{Math.round(settings.opacity * 100)}%
</span>
</div>
{showHardness && (
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Hardness:
</label>
<input
type="range"
min="0"
max="100"
value={settings.hardness * 100}
onChange={(e) => setHardness(Number(e.target.value) / 100)}
className="w-32"
/>
<span className="text-sm text-muted-foreground w-10">
{Math.round(settings.hardness * 100)}%
</span>
</div>
)}
{showFlow && (
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Flow:
</label>
<input
type="range"
min="0"
max="100"
value={settings.flow * 100}
onChange={(e) => setFlow(Number(e.target.value) / 100)}
className="w-32"
/>
<span className="text-sm text-muted-foreground w-10">
{Math.round(settings.flow * 100)}%
</span>
</div>
)}
</>
)}
{/* Fill Tool Options */}
{isFillTool && (
<>
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Color:
</label>
<input
type="color"
value={settings.color}
onChange={(e) => setColor(e.target.value)}
className="h-8 w-16 rounded border border-border cursor-pointer"
/>
<input
type="text"
value={settings.color}
onChange={(e) => setColor(e.target.value)}
className="w-24 px-2 py-1 text-xs rounded border border-border bg-background text-foreground"
/>
</div>
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Opacity:
</label>
<input
type="range"
min="0"
max="100"
value={settings.opacity * 100}
onChange={(e) => setOpacity(Number(e.target.value) / 100)}
className="w-32"
/>
<span className="text-sm text-muted-foreground w-10">
{Math.round(settings.opacity * 100)}%
</span>
</div>
</>
)}
{/* Shape Tool Options */}
{isShapeTool && (
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Shape:
</label>
<select
value={shapeSettings.type}
onChange={(e) => setShapeType(e.target.value as any)}
className="px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground"
>
<option value="rectangle">Rectangle</option>
<option value="ellipse">Ellipse</option>
<option value="line">Line</option>
<option value="arrow">Arrow</option>
<option value="polygon">Polygon</option>
<option value="star">Star</option>
<option value="triangle">Triangle</option>
</select>
</div>
)}
{/* Selection Tool Options */}
{isSelectionTool && (
<div className="flex items-center gap-2">
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
Mode:
</label>
<select
value={selectionType}
onChange={(e) => setSelectionType(e.target.value as any)}
className="px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground"
>
<option value="rectangular">Rectangular</option>
<option value="elliptical">Elliptical</option>
<option value="lasso">Lasso</option>
<option value="magic-wand">Magic Wand</option>
</select>
</div>
)}
</div>
);
}