{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hooks-use-pinch-zoom",
  "title": "usePinchZoom",
  "description": "A hook to handle pinch-to-zoom gestures on touch devices.",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/hooks/use-pinch-zoom/index.ts",
      "content": "// Copyright (c) 2026 raouf.codes - Azemmur\n\n'use client';\nimport { useEffect, useRef } from 'react';\n\nexport type UsePinchZoomOptions = {\n  elementRef: React.RefObject<HTMLElement | null>;\n  onZoom: (zoom: number) => void;\n  minZoom?: number;\n  maxZoom?: number;\n  initialZoom?: number;\n};\n\nfunction getDistance(touches: TouchList): number {\n  if (touches.length < 2) return 0;\n  const touch1 = touches[0];\n  const touch2 = touches[1];\n  if (!touch1 || !touch2) return 0;\n  return Math.hypot(\n    touch2.clientX - touch1.clientX,\n    touch2.clientY - touch1.clientY,\n  );\n}\n\n/**\n * Hook to handle pinch-to-zoom gestures on touch devices.\n *\n * @example\n * ```tsx\n * const elementRef = useRef<HTMLDivElement>(null);\n * const [zoom, setZoom] = useState(1);\n *\n * usePinchZoom({\n *   elementRef,\n *   onZoom: setZoom,\n *   minZoom: 0.5,\n *   maxZoom: 3,\n * });\n *\n * return <div ref={elementRef} style={{ transform: `scale(${zoom})` }}>...</div>;\n * ```\n */\nexport function usePinchZoom({\n  elementRef,\n  onZoom,\n  minZoom = 0.5,\n  maxZoom = 3,\n  initialZoom = 1,\n}: UsePinchZoomOptions) {\n  const currentZoom = useRef(initialZoom);\n  const pinchStartDistance = useRef<number | null>(null);\n  const pinchStartZoom = useRef(initialZoom);\n\n  useEffect(() => {\n    const el = elementRef.current;\n    if (!el) return;\n\n    const onTouchStart = (e: TouchEvent) => {\n      if (e.touches.length === 2) {\n        pinchStartDistance.current = getDistance(e.touches);\n        pinchStartZoom.current = currentZoom.current;\n      }\n    };\n\n    const onTouchMove = (e: TouchEvent) => {\n      if (e.touches.length === 2 && pinchStartDistance.current !== null) {\n        e.preventDefault();\n\n        const currentDistance = getDistance(e.touches);\n        if (currentDistance === 0) return;\n\n        const scale = currentDistance / pinchStartDistance.current;\n        const newZoom = Math.min(\n          maxZoom,\n          Math.max(minZoom, pinchStartZoom.current * scale),\n        );\n\n        currentZoom.current = newZoom;\n        onZoom(newZoom);\n      }\n    };\n\n    const onTouchEnd = (e: TouchEvent) => {\n      if (e.touches.length < 2) {\n        pinchStartDistance.current = null;\n      }\n    };\n\n    el.addEventListener('touchstart', onTouchStart, { passive: false });\n    el.addEventListener('touchmove', onTouchMove, { passive: false });\n    el.addEventListener('touchend', onTouchEnd);\n    el.addEventListener('touchcancel', onTouchEnd);\n\n    return () => {\n      el.removeEventListener('touchstart', onTouchStart);\n      el.removeEventListener('touchmove', onTouchMove);\n      el.removeEventListener('touchend', onTouchEnd);\n      el.removeEventListener('touchcancel', onTouchEnd);\n    };\n  }, [elementRef, onZoom, minZoom, maxZoom]);\n\n  useEffect(() => {\n    currentZoom.current = initialZoom;\n  }, [initialZoom]);\n}\n",
      "type": "registry:hook",
      "target": "hooks/azemmur/use-pinch-zoom.ts"
    }
  ],
  "type": "registry:hook"
}