{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-canvas-pan",
  "title": "useCanvasPan",
  "author": "Stickies <https://stickies.live>",
  "description": "Dragging a surface to look around it.",
  "files": [
    {
      "path": "registry/stickies/hooks/use-canvas-pan.ts",
      "content": "\"use client\"\n\nimport { useRef, useState } from \"react\"\n\nexport interface Pan {\n  x: number\n  y: number\n}\n\n/**\n * Dragging a surface to look around it. Spread `handlers` on the surface and move its\n * contents by `pan`. Only presses on the surface itself pan, so what's on it keeps its own\n * dragging; give anything else that should pan, like a background layer, `data-pan-surface`.\n */\nexport function useCanvasPan({ defaultPan = { x: 0, y: 0 } }: { defaultPan?: Pan } = {}) {\n  const [pan, setPan] = useState<Pan>(defaultPan)\n  const [panning, setPanning] = useState(false)\n  const start = useRef<{ x: number; y: number; id: number; from: Pan } | null>(null)\n\n  function end() {\n    start.current = null\n    setPanning(false)\n  }\n\n  const handlers = {\n    onPointerDown(e: React.PointerEvent<HTMLElement>) {\n      if (e.button !== 0) return\n      const target = e.target as HTMLElement\n      if (target !== e.currentTarget && !target.hasAttribute(\"data-pan-surface\")) return\n      e.currentTarget.setPointerCapture(e.pointerId)\n      start.current = { x: e.clientX, y: e.clientY, id: e.pointerId, from: pan }\n      setPanning(true)\n    },\n    onPointerMove(e: React.PointerEvent<HTMLElement>) {\n      const s = start.current\n      if (!s || e.pointerId !== s.id) return\n      setPan({ x: s.from.x + e.clientX - s.x, y: s.from.y + e.clientY - s.y })\n    },\n    onPointerUp: end,\n    onPointerCancel: end,\n  }\n\n  /** A point on screen (as from a pointer event) in the surface's own coordinates. */\n  function toCanvas(point: { clientX: number; clientY: number }, surface: HTMLElement | null): Pan {\n    const rect = surface?.getBoundingClientRect()\n    return { x: point.clientX - (rect?.left ?? 0) - pan.x, y: point.clientY - (rect?.top ?? 0) - pan.y }\n  }\n\n  return { pan, setPan, panning, handlers, toCanvas }\n}\n",
      "type": "registry:hook"
    }
  ],
  "docs": "See https://stickies.live/docs#use-canvas-pan for usage.",
  "categories": [
    "stickies"
  ],
  "type": "registry:hook"
}