Files
vfxreview/components/annotations/AnnotationTools.tsx
T
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

147 lines
4.2 KiB
TypeScript

"use client";
import { useReviewStore } from "@/hooks/use-review-player";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { AnnotationTool } from "@/types";
import {
Pencil,
ArrowUpRight,
Square,
Circle,
Minus,
Plus,
} from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
const TOOLS: { tool: AnnotationTool; icon: React.ElementType; label: string }[] = [
{ tool: "freehand", icon: Pencil, label: "Freehand" },
{ tool: "arrow", icon: ArrowUpRight, label: "Arrow" },
{ tool: "rectangle", icon: Square, label: "Rectangle" },
{ tool: "circle", icon: Circle, label: "Circle" },
];
const COLORS = [
{ value: "#ef4444", label: "Red" },
{ value: "#f59e0b", label: "Amber" },
{ value: "#22c55e", label: "Green" },
{ value: "#3b82f6", label: "Blue" },
{ value: "#a855f7", label: "Purple" },
{ value: "#ffffff", label: "White" },
{ value: "#000000", label: "Black" },
];
export function AnnotationTools() {
const {
isAnnotating,
selectedTool,
selectedColor,
strokeWidth,
setSelectedTool,
setSelectedColor,
setStrokeWidth,
setAnnotating,
} = useReviewStore();
if (!isAnnotating) return null;
return (
<div className="flex items-center gap-3 px-3 py-2 bg-zinc-900/95 border-b border-white/5">
{/* Tool selector */}
<div className="flex items-center gap-1">
{TOOLS.map(({ tool, icon: Icon, label }) => (
<Tooltip key={tool}>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon-sm"
className={cn(
"text-zinc-400 hover:text-white",
selectedTool === tool &&
"bg-primary/20 text-primary hover:bg-primary/30"
)}
onClick={() => setSelectedTool(tool)}
>
<Icon className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
))}
</div>
<div className="h-5 w-px bg-white/10" />
{/* Color picker */}
<div className="flex items-center gap-1.5">
{COLORS.map((c) => (
<Tooltip key={c.value}>
<TooltipTrigger asChild>
<button
className={cn(
"h-5 w-5 rounded-full border-2 transition-transform hover:scale-110",
selectedColor === c.value
? "border-white scale-110"
: "border-transparent"
)}
style={{ backgroundColor: c.value }}
onClick={() => setSelectedColor(c.value)}
title={c.label}
/>
</TooltipTrigger>
<TooltipContent>{c.label}</TooltipContent>
</Tooltip>
))}
</div>
<div className="h-5 w-px bg-white/10" />
{/* Stroke width */}
<div className="flex items-center gap-1.5">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon-sm"
className="text-zinc-400 hover:text-white h-6 w-6"
onClick={() => setStrokeWidth(Math.max(1, strokeWidth - 1))}
>
<Minus className="h-3 w-3" />
</Button>
</TooltipTrigger>
<TooltipContent>Thinner</TooltipContent>
</Tooltip>
<div
className="rounded-full bg-current"
style={{
width: Math.min(16, strokeWidth * 3),
height: Math.min(16, strokeWidth * 3),
backgroundColor: selectedColor,
}}
/>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon-sm"
className="text-zinc-400 hover:text-white h-6 w-6"
onClick={() => setStrokeWidth(Math.min(8, strokeWidth + 1))}
>
<Plus className="h-3 w-3" />
</Button>
</TooltipTrigger>
<TooltipContent>Thicker</TooltipContent>
</Tooltip>
<span className="text-xs text-zinc-500 font-mono w-4">{strokeWidth}</span>
</div>
</div>
);
}