import { useRef } from "react"; import { useZoom } from "./plugins/zoomPlugin/ZoomContext.js"; interface Props { /** CSS-pixel position of the handle center, relative to the crop-inner container. */ x: number; y: number; /** Controls cursor style and handle orientation only — movement is unconstrained (delta-based). */ axis: "x" | "y"; /** Called with the pointer delta in CSS pixels so both corners can be shifted equally. */ onChange: (dx: number, dy: number) => void; } /** * Absolutely-positioned draggable edge handle. * Tracks the pointer delta so both corners on this edge move by the same amount, * preserving the edge angle. */ export function EdgeHandle({ x, y, axis, onChange }: Props) { let { zoom } = useZoom(); let lastPos = useRef<{ x: number; y: number } | null>(null); function onPointerDown(e: React.PointerEvent) { e.currentTarget.setPointerCapture(e.pointerId); lastPos.current = { x: e.clientX, y: e.clientY }; } function onPointerMove(e: React.PointerEvent) { if (!(e.buttons & 1) || !lastPos.current) return; // Convert screen-space delta to CSS-pixel delta by dividing by zoom. let dx = (e.clientX - lastPos.current.x) / zoom; let dy = (e.clientY - lastPos.current.y) / zoom; lastPos.current = { x: e.clientX, y: e.clientY }; onChange(dx, dy); } function onPointerUp() { lastPos.current = null; } return (
); }