"use client"; import { usePreviewViewport } from "@/components/editor/panels/preview/preview-viewport"; import { useMaskHandles } from "@/hooks/use-mask-handles"; import { masksRegistry } from "@/lib/masks"; import type { SnapLine } from "@/lib/preview/preview-snap"; import type { ParamValues } from "@/lib/params"; import type { RectangleMaskParams } from "@/lib/masks/types"; import { CornerHandle, EdgeHandle, IconHandle, LineOverlay, BoundingBoxOutline, ShapeOutline, } from "./handle-primitives"; import { Rotate01Icon, FeatherIcon } from "@hugeicons/core-free-icons"; function hasRectangleOutlineParams( params: ParamValues, ): params is RectangleMaskParams { return ( typeof params.centerX === "number" && typeof params.centerY === "number" && typeof params.width === "number" && typeof params.height === "number" ); } export function MaskHandles({ onSnapLinesChange, }: { onSnapLinesChange?: (lines: SnapLine[]) => void; }) { const viewport = usePreviewViewport(); const { selectedWithMask, handlePositions, linePoints, handlePointerDown, handlePointerMove, handlePointerUp, } = useMaskHandles({ onSnapLinesChange }); if (!selectedWithMask) return null; const toOverlay = ({ canvasX, canvasY, }: { canvasX: number; canvasY: number; }) => viewport.canvasToOverlay({ canvasX, canvasY, }); const def = masksRegistry.get(selectedWithMask.mask.type); const { bounds } = selectedWithMask; const maskRotation = selectedWithMask.mask.params.rotation; const { x: scaleX, y: scaleY } = viewport.getDisplayScale(); const rectangleOutlineProps = hasRectangleOutlineParams( selectedWithMask.mask.params, ) ? { center: toOverlay({ canvasX: bounds.cx + selectedWithMask.mask.params.centerX * bounds.width, canvasY: bounds.cy + selectedWithMask.mask.params.centerY * bounds.height, }), outlineWidth: selectedWithMask.mask.params.width * bounds.width * scaleX, outlineHeight: selectedWithMask.mask.params.height * bounds.height * scaleY, rotation: maskRotation, } : null; const onPointerMove = (event: React.PointerEvent) => handlePointerMove({ event }); const onPointerUp = () => handlePointerUp(); return (