import { useZoom } from "./plugins/zoomPlugin/ZoomContext.js"; interface Props { x: number; y: number; /** Called with new position in pixels (relative to container). */ onChange: (x: number, y: number) => void; containerWidth: number; containerHeight: number; } /** * Absolutely-positioned draggable corner handle. * Position is in CSS pixels relative to the nearest `position: relative` ancestor. */ export function DragHandle({ x, y, onChange, containerWidth, containerHeight }: Props) { let { zoom } = useZoom(); function onPointerDown(e: React.PointerEvent) { e.currentTarget.setPointerCapture(e.pointerId); } function onPointerMove(e: React.PointerEvent) { if (!(e.buttons & 1)) return; let container = e.currentTarget.parentElement; if (!container) return; // getBoundingClientRect() returns screen-space coords (affected by CSS transform/zoom). // Divide by zoom to convert back to CSS-pixel space (the space onChange expects). let rect = container.getBoundingClientRect(); let newX = Math.max(0, Math.min(containerWidth, (e.clientX - rect.left) / zoom)); let newY = Math.max(0, Math.min(containerHeight, (e.clientY - rect.top) / zoom)); onChange(newX, newY); } return (
); }