@sitebytom/use-zoom-pan 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -518,7 +518,10 @@ var useZoomPan = ({
518
518
  const contentStyle = React__default.default.useMemo(() => {
519
519
  const style = {
520
520
  transformOrigin: "center",
521
- transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : "none"
521
+ transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : "none",
522
+ touchAction: "none",
523
+ userSelect: "none",
524
+ WebkitUserSelect: "none"
522
525
  };
523
526
  if (config.manageCursor) {
524
527
  if (isDragging) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useZoomPan.ts","../src/ZoomPan.tsx"],"names":["React","useCallback","useState","useRef","useEffect","config"],"mappings":"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","file":"index.js","sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\n\ninterface Position {\n x: number\n y: number\n}\n\nexport interface ZoomPanOptions {\n /** Minimum zoom scale (default: 1) */\n minScale?: number\n /** Maximum zoom scale (default: 4) */\n maxScale?: number\n /** Initial zoom scale (default: minScale) */\n initialScale?: number\n /** Initial x/y position (default: {x:0, y:0}) */\n initialPosition?: Position\n /** Mouse wheel zoom sensitivity (default: 0.002) */\n zoomSensitivity?: number\n /** Zoom level when clicking to zoom (default: 2.5) */\n clickZoomScale?: number\n /** Pixels moved before drag is detected on mouse (default: 5) */\n dragThresholdMouse?: number\n /** Pixels moved before drag is detected on touch (default: 10) */\n dragThresholdTouch?: number\n /** Pixels swiped before navigation triggers (default: 50) */\n swipeThreshold?: number\n /** Extra pan space beyond image edges in pixels (default: 80) */\n boundsBuffer?: number\n /** Whether to automatically manage cursor states (default: true) */\n manageCursor?: boolean\n /** Whether to enable swipe navigation (default: true) */\n enableSwipe?: boolean\n}\n\ninterface ZoomPanProps {\n /** Reference to the container element (div, section, etc.) */\n containerRef: React.RefObject<HTMLElement | null>\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n// Default configuration\nconst DEFAULT_OPTIONS: Required<Omit<ZoomPanOptions, 'initialScale' | 'initialPosition'>> & { initialScale?: number, initialPosition?: Position } = {\n minScale: 1,\n maxScale: 6,\n zoomSensitivity: 0.002,\n clickZoomScale: 2.5,\n dragThresholdMouse: 5,\n dragThresholdTouch: 10,\n swipeThreshold: 50,\n boundsBuffer: 80,\n manageCursor: true,\n enableSwipe: true,\n initialScale: undefined,\n initialPosition: undefined,\n}\n\nconst TRANSITION_DURATION = 400\nconst TRANSITION_CURVE = 'cubic-bezier(0.2, 0, 0, 1)'\n\ninterface DragState {\n /** Current cumulative X position relative to start position */\n x: number\n /** Current cumulative Y position relative to start position */\n y: number\n /** Flag to prevent click events if a drag occurred */\n hasDragged: boolean\n /** Initial clientX when interaction started */\n startX: number\n /** Initial clientY when interaction started */\n startY: number\n}\n\ninterface PinchState {\n /** Distance between two fingers when pinch started */\n startDist: number\n /** Zoom level when pinch started */\n initialScale: number\n /** Center X between two fingers when pinch started */\n startX: number\n /** Center Y between two fingers when pinch started */\n startY: number\n /** Content position when pinch started */\n startPos: Position\n /** Cached container rect for performant coordinate mapping */\n containerRect?: DOMRect\n}\n\n// Helper functions for boundary calculations\ninterface Bounds {\n xLimit: number\n yLimit: number\n}\n\nconst calculateBounds = (\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Bounds => {\n if (!container || !element) return { xLimit: 0, yLimit: 0 }\n\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const elementWidth = element.offsetWidth || containerWidth\n const elementHeight = element.offsetHeight || containerHeight\n\n const scaledWidth = elementWidth * targetScale\n const scaledHeight = elementHeight * targetScale\n\n const xLimit = (scaledWidth <= containerWidth ? 0 : (scaledWidth - containerWidth) / 2) + boundsBuffer\n const yLimit = (scaledHeight <= containerHeight ? 0 : (scaledHeight - containerHeight) / 2) + boundsBuffer\n\n return { xLimit, yLimit }\n}\n\nconst clampPosition = (\n pos: Position,\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Position => {\n const { xLimit, yLimit } = calculateBounds(targetScale, container, element, boundsBuffer)\n return {\n x: Math.max(-xLimit, Math.min(xLimit, pos.x)),\n y: Math.max(-yLimit, Math.min(yLimit, pos.y)),\n }\n}\n\n/** \n * Normalizes wheel delta across browsers and input devices.\n * Trackpads send small deltas, physical wheels send large ones mapped by deltaMode.\n */\nconst normalizeWheelDelta = (e: WheelEvent, sensitivity: number): number => {\n // deltaMode 1 is 'lines' (physical wheels), 0 is 'pixels' (trackpads)\n const factor = e.deltaMode === 1 ? 20 : 1 \n return -e.deltaY * factor * sensitivity\n}\n\n/**\n * A highly optimized hook for zoom and pan interactions.\n * Supports mouse wheel, dragging, double-click to focal zoom, and pinch-to-zoom on touch.\n */\nexport const useZoomPan = ({\n containerRef,\n enableZoom = true,\n onNext,\n onPrev,\n options = {}\n}: ZoomPanProps) => {\n // Memoize the merged config to ensure stability\n const config = React.useMemo(() => ({\n ...DEFAULT_OPTIONS,\n ...options\n }), [\n options.minScale,\n options.maxScale,\n options.zoomSensitivity,\n options.clickZoomScale,\n options.dragThresholdMouse,\n options.dragThresholdTouch,\n options.swipeThreshold,\n options.boundsBuffer,\n options.manageCursor,\n options.initialScale,\n options.initialPosition\n ])\n\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Internal helper to get content element\n const getContentElement = useCallback(() => {\n return (contentRef.current || containerRef.current?.firstElementChild) as HTMLElement | null\n }, [containerRef])\n const [scale, setScale] = useState(config.initialScale ?? config.minScale)\n const [position, setPosition] = useState<Position>(config.initialPosition ?? { x: 0, y: 0 })\n const [isDragging, setIsDragging] = useState(false)\n const [isTransitioning, setIsTransitioning] = useState(false)\n\n const dragStartRef = useRef<DragState>({\n x: 0,\n y: 0,\n hasDragged: false,\n startX: 0,\n startY: 0,\n })\n\n const pinchRef = useRef<PinchState>({\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n })\n\n const touchStartXRef = useRef<number>(0)\n const swipeBlockedRef = useRef<boolean>(false)\n\n // Track state for stable event listeners (non-passive wheel)\n const stateRef = useRef({ scale, position, enableZoom, isDragging, config })\n useEffect(() => {\n stateRef.current = { scale, position, enableZoom, isDragging, config }\n }, [scale, position, enableZoom, isDragging, config])\n\n // Cleanup on unmount and global window listeners for robustness\n useEffect(() => {\n const handleGlobalUp = () => {\n if (stateRef.current.isDragging) {\n setIsDragging(false)\n }\n }\n\n const handleBlur = () => {\n setIsDragging(false)\n }\n\n window.addEventListener('mouseup', handleGlobalUp)\n window.addEventListener('touchend', handleGlobalUp)\n window.addEventListener('touchcancel', handleGlobalUp)\n window.addEventListener('blur', handleBlur)\n\n return () => {\n window.removeEventListener('mouseup', handleGlobalUp)\n window.removeEventListener('touchend', handleGlobalUp)\n window.removeEventListener('touchcancel', handleGlobalUp)\n window.removeEventListener('blur', handleBlur)\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n setIsTransitioning(false)\n }\n }, [])\n\n\n // Handle container resize and content load\n const updateBoundsAndClamp = useCallback(() => {\n const container = containerRef.current\n const content = getContentElement()\n if (!container || !content) return\n const currentPos = { x: stateRef.current.position.x, y: stateRef.current.position.y }\n const clamped = clampPosition(currentPos, stateRef.current.scale, container, content, config.boundsBuffer)\n if (clamped.x !== currentPos.x || clamped.y !== currentPos.y) {\n setPosition(clamped)\n }\n }, [containerRef, config.boundsBuffer, getContentElement])\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver(() => {\n updateBoundsAndClamp()\n })\n\n observer.observe(container)\n \n // Also listen for image loads in the content\n const content = getContentElement()\n if (content instanceof HTMLImageElement && !content.complete) {\n content.addEventListener('load', updateBoundsAndClamp)\n }\n\n return () => {\n observer.disconnect()\n if (content instanceof HTMLImageElement) {\n content.removeEventListener('load', updateBoundsAndClamp)\n }\n }\n }, [containerRef, updateBoundsAndClamp, getContentElement])\n\n // Internal clamp helper that uses current config and container\n const getClampedPosition = useCallback(\n (pos: Position, targetScale: number, element: HTMLElement): Position => {\n return clampPosition(\n pos,\n targetScale,\n containerRef.current,\n element,\n config.boundsBuffer\n )\n },\n [containerRef, config.boundsBuffer],\n )\n\n const handleWheelManual = useCallback(\n (e: WheelEvent) => {\n if (!stateRef.current.enableZoom) return\n setIsTransitioning(false) // Cancel any active transition\n e.preventDefault()\n\n const { scale: currentScale, position: currentPosition, config } = stateRef.current\n \n // Normalize deltaY: Trackpads often send small deltas, physical wheels send large ones.\n const delta = normalizeWheelDelta(e, config.zoomSensitivity)\n const newScale = Math.min(Math.max(config.minScale, currentScale + delta), config.maxScale)\n\n if (newScale === config.minScale) {\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n } else {\n const container = containerRef.current\n const content = getContentElement()\n if (container && content) {\n const rect = container.getBoundingClientRect()\n const containerWidth = rect.width\n const containerHeight = rect.height\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n // Content coordinate at mouse position\n const contentX = (mouseX - currentPosition.x) / currentScale\n const contentY = (mouseY - currentPosition.y) / currentScale\n\n // New position maintaining the mouse over the same content point\n const newPosition = {\n x: mouseX - contentX * newScale,\n y: mouseY - contentY * newScale,\n }\n\n const clampedPosition = getClampedPosition(newPosition, newScale, content)\n setPosition(clampedPosition)\n setScale(newScale)\n }\n }\n },\n [getClampedPosition, containerRef, getContentElement, config.zoomSensitivity, config.minScale, config.maxScale],\n )\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n container.addEventListener('wheel', handleWheelManual, { passive: false })\n return () => container.removeEventListener('wheel', handleWheelManual)\n }, [containerRef, handleWheelManual])\n\n const reset = useCallback(() => {\n setIsTransitioning(true)\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n pinchRef.current = {\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n }\n }, [config.minScale])\n\n const handleFocalZoom = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const target = e.currentTarget\n if (!container || !target) return\n\n const rect = container.getBoundingClientRect()\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n const newPosition = {\n x: mouseX * (1 - config.clickZoomScale),\n y: mouseY * (1 - config.clickZoomScale),\n }\n\n const clampedPosition = getClampedPosition(newPosition, config.clickZoomScale, target)\n\n setScale(config.clickZoomScale)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n const onImageClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n // Prevent zoom if user was dragging\n if (dragStartRef.current.hasDragged) {\n dragStartRef.current.hasDragged = false\n return\n }\n\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const onImageDoubleClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const getPinchPosition = useCallback((centerX: number, centerY: number, newScale: number): Position => {\n const { containerRect, startX, startY, initialScale, startPos } = pinchRef.current\n if (!containerRect) return { x: 0, y: 0 }\n\n const containerCenterX = containerRect.width / 2\n const containerCenterY = containerRect.height / 2\n\n // Pinch center relative to container center\n const currentPinchX = centerX - (containerRect.left + containerCenterX)\n const currentPinchY = centerY - (containerRect.top + containerCenterY)\n \n // Initial pinch center relative to container center\n const startPinchX = startX - (containerRect.left + containerCenterX)\n const startPinchY = startY - (containerRect.top + containerCenterY)\n\n const scaleRatio = newScale / initialScale\n const pinchImageX = startPinchX - startPos.x\n const pinchImageY = startPinchY - startPos.y\n\n return {\n x: currentPinchX - pinchImageX * scaleRatio,\n y: currentPinchY - pinchImageY * scaleRatio,\n }\n }, [])\n\n const onImageTouchStart = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n swipeBlockedRef.current = e.touches.length === 2\n\n if (e.touches.length === 2) {\n // Pinch zoom\n const container = containerRef.current\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n pinchRef.current = {\n startDist: dist,\n initialScale: scale,\n startX: centerX,\n startY: centerY,\n startPos: { x: position.x, y: position.y },\n containerRect: container?.getBoundingClientRect()\n }\n } else if (e.touches.length === 1 && scale > config.minScale) {\n // Swipe navigation disabled when zoomed\n setIsDragging(true)\n dragStartRef.current = {\n x: e.touches[0].clientX - position.x,\n y: e.touches[0].clientY - position.y,\n hasDragged: false,\n startX: e.touches[0].clientX,\n startY: e.touches[0].clientY,\n }\n }\n },\n [scale, position, config.minScale, containerRef],\n )\n\n const onImageTouchMove = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n if (e.touches.length === 2) {\n // Pinch zoom\n e.preventDefault()\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n const ratio = dist / pinchRef.current.startDist\n const newScale = Math.min(Math.max(config.minScale, pinchRef.current.initialScale * ratio), config.maxScale)\n\n if (pinchRef.current.containerRect && newScale > config.minScale) {\n const newPosition = getPinchPosition(\n centerX, \n centerY, \n newScale, \n )\n \n const clampedPosition = getClampedPosition(\n newPosition,\n newScale,\n getContentElement() as HTMLElement,\n )\n setPosition(clampedPosition)\n } else {\n setPosition({ x: 0, y: 0 })\n }\n setScale(newScale)\n } else if (e.touches.length === 1 && isDragging && scale > config.minScale) {\n // Pan when zoomed\n e.preventDefault()\n const touchX = e.touches[0].clientX\n const touchY = e.touches[0].clientY\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n touchX - dragStartRef.current.startX,\n touchY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdTouch) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: touchX - dragStartRef.current.x,\n y: touchY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, getContentElement, getPinchPosition, config.minScale, config.maxScale, config.dragThresholdTouch],\n )\n\n const onImageTouchEnd = useCallback(() => {\n setIsDragging(false)\n // Reset pinch state to avoid stale calculations\n pinchRef.current = {\n startDist: 0,\n initialScale: scale,\n startX: 0,\n startY: 0,\n startPos: { x: position.x, y: position.y },\n }\n }, [scale, position])\n\n const onImageMouseDown = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n if (scale > config.minScale) {\n e.preventDefault()\n setIsDragging(true)\n dragStartRef.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n hasDragged: false,\n startX: e.clientX,\n startY: e.clientY,\n }\n }\n },\n [scale, position, config.minScale],\n )\n\n const handleSwipe = useCallback(\n (targetX: number, targetY: number) => {\n if (!config.enableSwipe) return\n\n const distanceX = Math.abs(targetX - dragStartRef.current.startX)\n const distanceY = Math.abs(targetY - dragStartRef.current.startY)\n\n // Only consider as swipe if movement is predominantly horizontal\n if (distanceX > config.swipeThreshold && distanceX > distanceY) {\n if (targetX < dragStartRef.current.startX) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [config.enableSwipe, config.swipeThreshold, onNext, onPrev]\n )\n\n const onImageMouseMove = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (isDragging && scale > config.minScale) {\n e.preventDefault()\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n e.clientX - dragStartRef.current.startX,\n e.clientY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdMouse) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: e.clientX - dragStartRef.current.x,\n y: e.clientY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, config.minScale, config.dragThresholdMouse],\n )\n\n const onImageMouseUp = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onImageMouseLeave = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onContainerTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n touchStartXRef.current = touch.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerTouchEnd = useCallback(\n (e: React.TouchEvent) => {\n if (swipeBlockedRef.current) {\n swipeBlockedRef.current = false\n return\n }\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n const startX = touchStartXRef.current\n const endX = touch.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const onContainerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n touchStartXRef.current = e.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerMouseUp = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n const startX = touchStartXRef.current\n const endX = e.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const zoomTo = useCallback(\n (x: number, y: number, targetScale?: number) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const content = contentRef.current || container?.firstElementChild as HTMLElement\n if (!container || !content) return\n\n const scaleToUse = targetScale ?? config.clickZoomScale\n const contentWidth = content.offsetWidth\n const contentHeight = content.offsetHeight\n \n // Calculate position to center the (x, y) point\n // Since transform-origin is center (default), the offset to center a point (x,y) is:\n // (CenterOfContent - TargetPoint) * Scale\n const newPosition = {\n x: (contentWidth / 2 - x) * scaleToUse,\n y: (contentHeight / 2 - y) * scaleToUse,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scaleToUse, content)\n\n setScale(scaleToUse)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n // Clear transition state after duration completes\n useEffect(() => {\n if (!isTransitioning) return\n const timer = setTimeout(() => setIsTransitioning(false), TRANSITION_DURATION)\n return () => clearTimeout(timer)\n }, [isTransitioning])\n\n // Cleanup handled in main effect hook above\n\n const contentStyle = React.useMemo(() => {\n const style: React.CSSProperties = {\n transformOrigin: 'center',\n transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : 'none'\n }\n\n if (config.manageCursor) {\n if (isDragging) {\n style.cursor = 'grabbing'\n } else if (scale > config.minScale) {\n style.cursor = 'grab'\n } else if (enableZoom) {\n style.cursor = 'zoom-in'\n } else {\n style.cursor = 'default'\n }\n }\n\n return style\n }, [isTransitioning, config.manageCursor, isDragging, scale, config.minScale, enableZoom])\n\n const contentProps = React.useMemo(() => ({\n ref: contentRef as React.Ref<any>, // Cast to compatible ref type\n style: contentStyle,\n onClick: onImageClick,\n onDoubleClick: onImageDoubleClick,\n onTouchStart: onImageTouchStart,\n onTouchMove: onImageTouchMove,\n onTouchEnd: onImageTouchEnd,\n onMouseDown: onImageMouseDown,\n onMouseMove: onImageMouseMove,\n onMouseUp: onImageMouseUp,\n onMouseLeave: onImageMouseLeave,\n }), [\n contentStyle,\n onImageClick,\n onImageDoubleClick,\n onImageTouchStart,\n onImageTouchMove,\n onImageTouchEnd,\n onImageMouseDown,\n onImageMouseMove,\n onImageMouseUp,\n onImageMouseLeave\n ])\n\n const containerProps = React.useMemo(() => ({\n onTouchStart: onContainerTouchStart,\n onTouchEnd: onContainerTouchEnd,\n onMouseDown: onContainerMouseDown,\n onMouseUp: onContainerMouseUp,\n }), [\n onContainerTouchStart,\n onContainerTouchEnd,\n onContainerMouseDown,\n onContainerMouseUp\n ])\n\n return {\n scale,\n position,\n isDragging,\n reset,\n zoomTo,\n contentProps,\n containerProps,\n }\n}","'use client'\n\nimport React, { useRef, CSSProperties } from 'react'\nimport { useZoomPan, ZoomPanOptions } from './useZoomPan'\n\ninterface ZoomPanProps {\n children: React.ReactNode\n className?: string\n style?: CSSProperties\n contentClassName?: string\n contentStyle?: CSSProperties\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n/**\n * A simple component wrapper for zoom and pan functionality.\n * Wrap any content (images, SVG, canvas, etc.) to make it zoomable and pannable.\n * \n * @example\n * ```tsx\n * <ZoomPan>\n * <img src=\"photo.jpg\" alt=\"Zoomable\" />\n * </ZoomPan>\n * ```\n * \n * @example With custom options\n * ```tsx\n * <ZoomPan options={{ maxScale: 6, clickZoomScale: 3 }}>\n * <canvas ref={canvasRef} />\n * </ZoomPan>\n * ```\n */\nexport const ZoomPan: React.FC<ZoomPanProps> = ({\n children,\n className = '',\n style = {},\n contentClassName = '',\n contentStyle = {},\n enableZoom = true,\n onNext,\n onPrev,\n options,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null)\n\n const { scale, position, contentProps, containerProps } = useZoomPan({\n containerRef,\n enableZoom,\n onNext,\n onPrev,\n options,\n })\n\n const defaultContainerStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: scale > 1 ? 'grab' : enableZoom ? 'zoom-in' : 'default',\n position: 'relative',\n ...style,\n }\n\n const defaultContentStyle: CSSProperties = {\n transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,\n ...contentProps.style,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n touchAction: 'none',\n maxWidth: '100%',\n maxHeight: '100%',\n ...contentStyle,\n }\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={defaultContainerStyle}\n {...containerProps}\n >\n <div\n className={contentClassName}\n {...contentProps}\n style={{\n ...defaultContentStyle,\n ...contentProps.style,\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport default ZoomPan"]}
1
+ {"version":3,"sources":["../src/useZoomPan.ts","../src/ZoomPan.tsx"],"names":["React","useCallback","useState","useRef","useEffect","config"],"mappings":"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","file":"index.js","sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\n\ninterface Position {\n x: number\n y: number\n}\n\nexport interface ZoomPanOptions {\n /** Minimum zoom scale (default: 1) */\n minScale?: number\n /** Maximum zoom scale (default: 4) */\n maxScale?: number\n /** Initial zoom scale (default: minScale) */\n initialScale?: number\n /** Initial x/y position (default: {x:0, y:0}) */\n initialPosition?: Position\n /** Mouse wheel zoom sensitivity (default: 0.002) */\n zoomSensitivity?: number\n /** Zoom level when clicking to zoom (default: 2.5) */\n clickZoomScale?: number\n /** Pixels moved before drag is detected on mouse (default: 5) */\n dragThresholdMouse?: number\n /** Pixels moved before drag is detected on touch (default: 10) */\n dragThresholdTouch?: number\n /** Pixels swiped before navigation triggers (default: 50) */\n swipeThreshold?: number\n /** Extra pan space beyond image edges in pixels (default: 80) */\n boundsBuffer?: number\n /** Whether to automatically manage cursor states (default: true) */\n manageCursor?: boolean\n /** Whether to enable swipe navigation (default: true) */\n enableSwipe?: boolean\n}\n\ninterface ZoomPanProps {\n /** Reference to the container element (div, section, etc.) */\n containerRef: React.RefObject<HTMLElement | null>\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n// Default configuration\nconst DEFAULT_OPTIONS: Required<Omit<ZoomPanOptions, 'initialScale' | 'initialPosition'>> & { initialScale?: number, initialPosition?: Position } = {\n minScale: 1,\n maxScale: 6,\n zoomSensitivity: 0.002,\n clickZoomScale: 2.5,\n dragThresholdMouse: 5,\n dragThresholdTouch: 10,\n swipeThreshold: 50,\n boundsBuffer: 80,\n manageCursor: true,\n enableSwipe: true,\n initialScale: undefined,\n initialPosition: undefined,\n}\n\nconst TRANSITION_DURATION = 400\nconst TRANSITION_CURVE = 'cubic-bezier(0.2, 0, 0, 1)'\n\ninterface DragState {\n /** Current cumulative X position relative to start position */\n x: number\n /** Current cumulative Y position relative to start position */\n y: number\n /** Flag to prevent click events if a drag occurred */\n hasDragged: boolean\n /** Initial clientX when interaction started */\n startX: number\n /** Initial clientY when interaction started */\n startY: number\n}\n\ninterface PinchState {\n /** Distance between two fingers when pinch started */\n startDist: number\n /** Zoom level when pinch started */\n initialScale: number\n /** Center X between two fingers when pinch started */\n startX: number\n /** Center Y between two fingers when pinch started */\n startY: number\n /** Content position when pinch started */\n startPos: Position\n /** Cached container rect for performant coordinate mapping */\n containerRect?: DOMRect\n}\n\n// Helper functions for boundary calculations\ninterface Bounds {\n xLimit: number\n yLimit: number\n}\n\nconst calculateBounds = (\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Bounds => {\n if (!container || !element) return { xLimit: 0, yLimit: 0 }\n\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const elementWidth = element.offsetWidth || containerWidth\n const elementHeight = element.offsetHeight || containerHeight\n\n const scaledWidth = elementWidth * targetScale\n const scaledHeight = elementHeight * targetScale\n\n const xLimit = (scaledWidth <= containerWidth ? 0 : (scaledWidth - containerWidth) / 2) + boundsBuffer\n const yLimit = (scaledHeight <= containerHeight ? 0 : (scaledHeight - containerHeight) / 2) + boundsBuffer\n\n return { xLimit, yLimit }\n}\n\nconst clampPosition = (\n pos: Position,\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Position => {\n const { xLimit, yLimit } = calculateBounds(targetScale, container, element, boundsBuffer)\n return {\n x: Math.max(-xLimit, Math.min(xLimit, pos.x)),\n y: Math.max(-yLimit, Math.min(yLimit, pos.y)),\n }\n}\n\n/** \n * Normalizes wheel delta across browsers and input devices.\n * Trackpads send small deltas, physical wheels send large ones mapped by deltaMode.\n */\nconst normalizeWheelDelta = (e: WheelEvent, sensitivity: number): number => {\n // deltaMode 1 is 'lines' (physical wheels), 0 is 'pixels' (trackpads)\n const factor = e.deltaMode === 1 ? 20 : 1 \n return -e.deltaY * factor * sensitivity\n}\n\n/**\n * A highly optimized hook for zoom and pan interactions.\n * Supports mouse wheel, dragging, double-click to focal zoom, and pinch-to-zoom on touch.\n */\nexport const useZoomPan = ({\n containerRef,\n enableZoom = true,\n onNext,\n onPrev,\n options = {}\n}: ZoomPanProps) => {\n // Memoize the merged config to ensure stability\n const config = React.useMemo(() => ({\n ...DEFAULT_OPTIONS,\n ...options\n }), [\n options.minScale,\n options.maxScale,\n options.zoomSensitivity,\n options.clickZoomScale,\n options.dragThresholdMouse,\n options.dragThresholdTouch,\n options.swipeThreshold,\n options.boundsBuffer,\n options.manageCursor,\n options.initialScale,\n options.initialPosition\n ])\n\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Internal helper to get content element\n const getContentElement = useCallback(() => {\n return (contentRef.current || containerRef.current?.firstElementChild) as HTMLElement | null\n }, [containerRef])\n const [scale, setScale] = useState(config.initialScale ?? config.minScale)\n const [position, setPosition] = useState<Position>(config.initialPosition ?? { x: 0, y: 0 })\n const [isDragging, setIsDragging] = useState(false)\n const [isTransitioning, setIsTransitioning] = useState(false)\n\n const dragStartRef = useRef<DragState>({\n x: 0,\n y: 0,\n hasDragged: false,\n startX: 0,\n startY: 0,\n })\n\n const pinchRef = useRef<PinchState>({\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n })\n\n const touchStartXRef = useRef<number>(0)\n const swipeBlockedRef = useRef<boolean>(false)\n\n // Track state for stable event listeners (non-passive wheel)\n const stateRef = useRef({ scale, position, enableZoom, isDragging, config })\n useEffect(() => {\n stateRef.current = { scale, position, enableZoom, isDragging, config }\n }, [scale, position, enableZoom, isDragging, config])\n\n // Cleanup on unmount and global window listeners for robustness\n useEffect(() => {\n const handleGlobalUp = () => {\n if (stateRef.current.isDragging) {\n setIsDragging(false)\n }\n }\n\n const handleBlur = () => {\n setIsDragging(false)\n }\n\n window.addEventListener('mouseup', handleGlobalUp)\n window.addEventListener('touchend', handleGlobalUp)\n window.addEventListener('touchcancel', handleGlobalUp)\n window.addEventListener('blur', handleBlur)\n\n return () => {\n window.removeEventListener('mouseup', handleGlobalUp)\n window.removeEventListener('touchend', handleGlobalUp)\n window.removeEventListener('touchcancel', handleGlobalUp)\n window.removeEventListener('blur', handleBlur)\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n setIsTransitioning(false)\n }\n }, [])\n\n\n // Handle container resize and content load\n const updateBoundsAndClamp = useCallback(() => {\n const container = containerRef.current\n const content = getContentElement()\n if (!container || !content) return\n const currentPos = { x: stateRef.current.position.x, y: stateRef.current.position.y }\n const clamped = clampPosition(currentPos, stateRef.current.scale, container, content, config.boundsBuffer)\n if (clamped.x !== currentPos.x || clamped.y !== currentPos.y) {\n setPosition(clamped)\n }\n }, [containerRef, config.boundsBuffer, getContentElement])\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver(() => {\n updateBoundsAndClamp()\n })\n\n observer.observe(container)\n \n // Also listen for image loads in the content\n const content = getContentElement()\n if (content instanceof HTMLImageElement && !content.complete) {\n content.addEventListener('load', updateBoundsAndClamp)\n }\n\n return () => {\n observer.disconnect()\n if (content instanceof HTMLImageElement) {\n content.removeEventListener('load', updateBoundsAndClamp)\n }\n }\n }, [containerRef, updateBoundsAndClamp, getContentElement])\n\n // Internal clamp helper that uses current config and container\n const getClampedPosition = useCallback(\n (pos: Position, targetScale: number, element: HTMLElement): Position => {\n return clampPosition(\n pos,\n targetScale,\n containerRef.current,\n element,\n config.boundsBuffer\n )\n },\n [containerRef, config.boundsBuffer],\n )\n\n const handleWheelManual = useCallback(\n (e: WheelEvent) => {\n if (!stateRef.current.enableZoom) return\n setIsTransitioning(false) // Cancel any active transition\n e.preventDefault()\n\n const { scale: currentScale, position: currentPosition, config } = stateRef.current\n \n // Normalize deltaY: Trackpads often send small deltas, physical wheels send large ones.\n const delta = normalizeWheelDelta(e, config.zoomSensitivity)\n const newScale = Math.min(Math.max(config.minScale, currentScale + delta), config.maxScale)\n\n if (newScale === config.minScale) {\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n } else {\n const container = containerRef.current\n const content = getContentElement()\n if (container && content) {\n const rect = container.getBoundingClientRect()\n const containerWidth = rect.width\n const containerHeight = rect.height\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n // Content coordinate at mouse position\n const contentX = (mouseX - currentPosition.x) / currentScale\n const contentY = (mouseY - currentPosition.y) / currentScale\n\n // New position maintaining the mouse over the same content point\n const newPosition = {\n x: mouseX - contentX * newScale,\n y: mouseY - contentY * newScale,\n }\n\n const clampedPosition = getClampedPosition(newPosition, newScale, content)\n setPosition(clampedPosition)\n setScale(newScale)\n }\n }\n },\n [getClampedPosition, containerRef, getContentElement, config.zoomSensitivity, config.minScale, config.maxScale],\n )\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n container.addEventListener('wheel', handleWheelManual, { passive: false })\n return () => container.removeEventListener('wheel', handleWheelManual)\n }, [containerRef, handleWheelManual])\n\n const reset = useCallback(() => {\n setIsTransitioning(true)\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n pinchRef.current = {\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n }\n }, [config.minScale])\n\n const handleFocalZoom = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const target = e.currentTarget\n if (!container || !target) return\n\n const rect = container.getBoundingClientRect()\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n const newPosition = {\n x: mouseX * (1 - config.clickZoomScale),\n y: mouseY * (1 - config.clickZoomScale),\n }\n\n const clampedPosition = getClampedPosition(newPosition, config.clickZoomScale, target)\n\n setScale(config.clickZoomScale)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n const onImageClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n // Prevent zoom if user was dragging\n if (dragStartRef.current.hasDragged) {\n dragStartRef.current.hasDragged = false\n return\n }\n\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const onImageDoubleClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const getPinchPosition = useCallback((centerX: number, centerY: number, newScale: number): Position => {\n const { containerRect, startX, startY, initialScale, startPos } = pinchRef.current\n if (!containerRect) return { x: 0, y: 0 }\n\n const containerCenterX = containerRect.width / 2\n const containerCenterY = containerRect.height / 2\n\n // Pinch center relative to container center\n const currentPinchX = centerX - (containerRect.left + containerCenterX)\n const currentPinchY = centerY - (containerRect.top + containerCenterY)\n \n // Initial pinch center relative to container center\n const startPinchX = startX - (containerRect.left + containerCenterX)\n const startPinchY = startY - (containerRect.top + containerCenterY)\n\n const scaleRatio = newScale / initialScale\n const pinchImageX = startPinchX - startPos.x\n const pinchImageY = startPinchY - startPos.y\n\n return {\n x: currentPinchX - pinchImageX * scaleRatio,\n y: currentPinchY - pinchImageY * scaleRatio,\n }\n }, [])\n\n const onImageTouchStart = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n swipeBlockedRef.current = e.touches.length === 2\n\n if (e.touches.length === 2) {\n // Pinch zoom\n const container = containerRef.current\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n pinchRef.current = {\n startDist: dist,\n initialScale: scale,\n startX: centerX,\n startY: centerY,\n startPos: { x: position.x, y: position.y },\n containerRect: container?.getBoundingClientRect()\n }\n } else if (e.touches.length === 1 && scale > config.minScale) {\n // Swipe navigation disabled when zoomed\n setIsDragging(true)\n dragStartRef.current = {\n x: e.touches[0].clientX - position.x,\n y: e.touches[0].clientY - position.y,\n hasDragged: false,\n startX: e.touches[0].clientX,\n startY: e.touches[0].clientY,\n }\n }\n },\n [scale, position, config.minScale, containerRef],\n )\n\n const onImageTouchMove = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n if (e.touches.length === 2) {\n // Pinch zoom\n e.preventDefault()\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n const ratio = dist / pinchRef.current.startDist\n const newScale = Math.min(Math.max(config.minScale, pinchRef.current.initialScale * ratio), config.maxScale)\n\n if (pinchRef.current.containerRect && newScale > config.minScale) {\n const newPosition = getPinchPosition(\n centerX, \n centerY, \n newScale, \n )\n \n const clampedPosition = getClampedPosition(\n newPosition,\n newScale,\n getContentElement() as HTMLElement,\n )\n setPosition(clampedPosition)\n } else {\n setPosition({ x: 0, y: 0 })\n }\n setScale(newScale)\n } else if (e.touches.length === 1 && isDragging && scale > config.minScale) {\n // Pan when zoomed\n e.preventDefault()\n const touchX = e.touches[0].clientX\n const touchY = e.touches[0].clientY\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n touchX - dragStartRef.current.startX,\n touchY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdTouch) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: touchX - dragStartRef.current.x,\n y: touchY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, getContentElement, getPinchPosition, config.minScale, config.maxScale, config.dragThresholdTouch],\n )\n\n const onImageTouchEnd = useCallback(() => {\n setIsDragging(false)\n // Reset pinch state to avoid stale calculations\n pinchRef.current = {\n startDist: 0,\n initialScale: scale,\n startX: 0,\n startY: 0,\n startPos: { x: position.x, y: position.y },\n }\n }, [scale, position])\n\n const onImageMouseDown = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n if (scale > config.minScale) {\n e.preventDefault()\n setIsDragging(true)\n dragStartRef.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n hasDragged: false,\n startX: e.clientX,\n startY: e.clientY,\n }\n }\n },\n [scale, position, config.minScale],\n )\n\n const handleSwipe = useCallback(\n (targetX: number, targetY: number) => {\n if (!config.enableSwipe) return\n\n const distanceX = Math.abs(targetX - dragStartRef.current.startX)\n const distanceY = Math.abs(targetY - dragStartRef.current.startY)\n\n // Only consider as swipe if movement is predominantly horizontal\n if (distanceX > config.swipeThreshold && distanceX > distanceY) {\n if (targetX < dragStartRef.current.startX) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [config.enableSwipe, config.swipeThreshold, onNext, onPrev]\n )\n\n const onImageMouseMove = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (isDragging && scale > config.minScale) {\n e.preventDefault()\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n e.clientX - dragStartRef.current.startX,\n e.clientY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdMouse) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: e.clientX - dragStartRef.current.x,\n y: e.clientY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, config.minScale, config.dragThresholdMouse],\n )\n\n const onImageMouseUp = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onImageMouseLeave = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onContainerTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n touchStartXRef.current = touch.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerTouchEnd = useCallback(\n (e: React.TouchEvent) => {\n if (swipeBlockedRef.current) {\n swipeBlockedRef.current = false\n return\n }\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n const startX = touchStartXRef.current\n const endX = touch.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const onContainerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n touchStartXRef.current = e.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerMouseUp = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n const startX = touchStartXRef.current\n const endX = e.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const zoomTo = useCallback(\n (x: number, y: number, targetScale?: number) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const content = contentRef.current || container?.firstElementChild as HTMLElement\n if (!container || !content) return\n\n const scaleToUse = targetScale ?? config.clickZoomScale\n const contentWidth = content.offsetWidth\n const contentHeight = content.offsetHeight\n \n // Calculate position to center the (x, y) point\n // Since transform-origin is center (default), the offset to center a point (x,y) is:\n // (CenterOfContent - TargetPoint) * Scale\n const newPosition = {\n x: (contentWidth / 2 - x) * scaleToUse,\n y: (contentHeight / 2 - y) * scaleToUse,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scaleToUse, content)\n\n setScale(scaleToUse)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n // Clear transition state after duration completes\n useEffect(() => {\n if (!isTransitioning) return\n const timer = setTimeout(() => setIsTransitioning(false), TRANSITION_DURATION)\n return () => clearTimeout(timer)\n }, [isTransitioning])\n\n // Cleanup handled in main effect hook above\n\n const contentStyle = React.useMemo(() => {\n const style: React.CSSProperties = {\n transformOrigin: 'center',\n transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : 'none',\n touchAction: 'none',\n userSelect: 'none',\n WebkitUserSelect: 'none',\n }\n\n if (config.manageCursor) {\n if (isDragging) {\n style.cursor = 'grabbing'\n } else if (scale > config.minScale) {\n style.cursor = 'grab'\n } else if (enableZoom) {\n style.cursor = 'zoom-in'\n } else {\n style.cursor = 'default'\n }\n }\n\n return style\n }, [isTransitioning, config.manageCursor, isDragging, scale, config.minScale, enableZoom])\n\n const contentProps = React.useMemo(() => ({\n ref: contentRef as React.Ref<any>, // Cast to compatible ref type\n style: contentStyle,\n onClick: onImageClick,\n onDoubleClick: onImageDoubleClick,\n onTouchStart: onImageTouchStart,\n onTouchMove: onImageTouchMove,\n onTouchEnd: onImageTouchEnd,\n onMouseDown: onImageMouseDown,\n onMouseMove: onImageMouseMove,\n onMouseUp: onImageMouseUp,\n onMouseLeave: onImageMouseLeave,\n }), [\n contentStyle,\n onImageClick,\n onImageDoubleClick,\n onImageTouchStart,\n onImageTouchMove,\n onImageTouchEnd,\n onImageMouseDown,\n onImageMouseMove,\n onImageMouseUp,\n onImageMouseLeave\n ])\n\n const containerProps = React.useMemo(() => ({\n onTouchStart: onContainerTouchStart,\n onTouchEnd: onContainerTouchEnd,\n onMouseDown: onContainerMouseDown,\n onMouseUp: onContainerMouseUp,\n }), [\n onContainerTouchStart,\n onContainerTouchEnd,\n onContainerMouseDown,\n onContainerMouseUp\n ])\n\n return {\n scale,\n position,\n isDragging,\n reset,\n zoomTo,\n contentProps,\n containerProps,\n }\n}","'use client'\n\nimport React, { useRef, CSSProperties } from 'react'\nimport { useZoomPan, ZoomPanOptions } from './useZoomPan'\n\ninterface ZoomPanProps {\n children: React.ReactNode\n className?: string\n style?: CSSProperties\n contentClassName?: string\n contentStyle?: CSSProperties\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n/**\n * A simple component wrapper for zoom and pan functionality.\n * Wrap any content (images, SVG, canvas, etc.) to make it zoomable and pannable.\n * \n * @example\n * ```tsx\n * <ZoomPan>\n * <img src=\"photo.jpg\" alt=\"Zoomable\" />\n * </ZoomPan>\n * ```\n * \n * @example With custom options\n * ```tsx\n * <ZoomPan options={{ maxScale: 6, clickZoomScale: 3 }}>\n * <canvas ref={canvasRef} />\n * </ZoomPan>\n * ```\n */\nexport const ZoomPan: React.FC<ZoomPanProps> = ({\n children,\n className = '',\n style = {},\n contentClassName = '',\n contentStyle = {},\n enableZoom = true,\n onNext,\n onPrev,\n options,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null)\n\n const { scale, position, contentProps, containerProps } = useZoomPan({\n containerRef,\n enableZoom,\n onNext,\n onPrev,\n options,\n })\n\n const defaultContainerStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: scale > 1 ? 'grab' : enableZoom ? 'zoom-in' : 'default',\n position: 'relative',\n ...style,\n }\n\n const defaultContentStyle: CSSProperties = {\n transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,\n ...contentProps.style,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n touchAction: 'none',\n maxWidth: '100%',\n maxHeight: '100%',\n ...contentStyle,\n }\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={defaultContainerStyle}\n {...containerProps}\n >\n <div\n className={contentClassName}\n {...contentProps}\n style={{\n ...defaultContentStyle,\n ...contentProps.style,\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport default ZoomPan"]}
package/dist/index.mjs CHANGED
@@ -512,7 +512,10 @@ var useZoomPan = ({
512
512
  const contentStyle = React.useMemo(() => {
513
513
  const style = {
514
514
  transformOrigin: "center",
515
- transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : "none"
515
+ transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : "none",
516
+ touchAction: "none",
517
+ userSelect: "none",
518
+ WebkitUserSelect: "none"
516
519
  };
517
520
  if (config.manageCursor) {
518
521
  if (isDragging) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useZoomPan.ts","../src/ZoomPan.tsx"],"names":["config","useRef","React"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\n\ninterface Position {\n x: number\n y: number\n}\n\nexport interface ZoomPanOptions {\n /** Minimum zoom scale (default: 1) */\n minScale?: number\n /** Maximum zoom scale (default: 4) */\n maxScale?: number\n /** Initial zoom scale (default: minScale) */\n initialScale?: number\n /** Initial x/y position (default: {x:0, y:0}) */\n initialPosition?: Position\n /** Mouse wheel zoom sensitivity (default: 0.002) */\n zoomSensitivity?: number\n /** Zoom level when clicking to zoom (default: 2.5) */\n clickZoomScale?: number\n /** Pixels moved before drag is detected on mouse (default: 5) */\n dragThresholdMouse?: number\n /** Pixels moved before drag is detected on touch (default: 10) */\n dragThresholdTouch?: number\n /** Pixels swiped before navigation triggers (default: 50) */\n swipeThreshold?: number\n /** Extra pan space beyond image edges in pixels (default: 80) */\n boundsBuffer?: number\n /** Whether to automatically manage cursor states (default: true) */\n manageCursor?: boolean\n /** Whether to enable swipe navigation (default: true) */\n enableSwipe?: boolean\n}\n\ninterface ZoomPanProps {\n /** Reference to the container element (div, section, etc.) */\n containerRef: React.RefObject<HTMLElement | null>\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n// Default configuration\nconst DEFAULT_OPTIONS: Required<Omit<ZoomPanOptions, 'initialScale' | 'initialPosition'>> & { initialScale?: number, initialPosition?: Position } = {\n minScale: 1,\n maxScale: 6,\n zoomSensitivity: 0.002,\n clickZoomScale: 2.5,\n dragThresholdMouse: 5,\n dragThresholdTouch: 10,\n swipeThreshold: 50,\n boundsBuffer: 80,\n manageCursor: true,\n enableSwipe: true,\n initialScale: undefined,\n initialPosition: undefined,\n}\n\nconst TRANSITION_DURATION = 400\nconst TRANSITION_CURVE = 'cubic-bezier(0.2, 0, 0, 1)'\n\ninterface DragState {\n /** Current cumulative X position relative to start position */\n x: number\n /** Current cumulative Y position relative to start position */\n y: number\n /** Flag to prevent click events if a drag occurred */\n hasDragged: boolean\n /** Initial clientX when interaction started */\n startX: number\n /** Initial clientY when interaction started */\n startY: number\n}\n\ninterface PinchState {\n /** Distance between two fingers when pinch started */\n startDist: number\n /** Zoom level when pinch started */\n initialScale: number\n /** Center X between two fingers when pinch started */\n startX: number\n /** Center Y between two fingers when pinch started */\n startY: number\n /** Content position when pinch started */\n startPos: Position\n /** Cached container rect for performant coordinate mapping */\n containerRect?: DOMRect\n}\n\n// Helper functions for boundary calculations\ninterface Bounds {\n xLimit: number\n yLimit: number\n}\n\nconst calculateBounds = (\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Bounds => {\n if (!container || !element) return { xLimit: 0, yLimit: 0 }\n\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const elementWidth = element.offsetWidth || containerWidth\n const elementHeight = element.offsetHeight || containerHeight\n\n const scaledWidth = elementWidth * targetScale\n const scaledHeight = elementHeight * targetScale\n\n const xLimit = (scaledWidth <= containerWidth ? 0 : (scaledWidth - containerWidth) / 2) + boundsBuffer\n const yLimit = (scaledHeight <= containerHeight ? 0 : (scaledHeight - containerHeight) / 2) + boundsBuffer\n\n return { xLimit, yLimit }\n}\n\nconst clampPosition = (\n pos: Position,\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Position => {\n const { xLimit, yLimit } = calculateBounds(targetScale, container, element, boundsBuffer)\n return {\n x: Math.max(-xLimit, Math.min(xLimit, pos.x)),\n y: Math.max(-yLimit, Math.min(yLimit, pos.y)),\n }\n}\n\n/** \n * Normalizes wheel delta across browsers and input devices.\n * Trackpads send small deltas, physical wheels send large ones mapped by deltaMode.\n */\nconst normalizeWheelDelta = (e: WheelEvent, sensitivity: number): number => {\n // deltaMode 1 is 'lines' (physical wheels), 0 is 'pixels' (trackpads)\n const factor = e.deltaMode === 1 ? 20 : 1 \n return -e.deltaY * factor * sensitivity\n}\n\n/**\n * A highly optimized hook for zoom and pan interactions.\n * Supports mouse wheel, dragging, double-click to focal zoom, and pinch-to-zoom on touch.\n */\nexport const useZoomPan = ({\n containerRef,\n enableZoom = true,\n onNext,\n onPrev,\n options = {}\n}: ZoomPanProps) => {\n // Memoize the merged config to ensure stability\n const config = React.useMemo(() => ({\n ...DEFAULT_OPTIONS,\n ...options\n }), [\n options.minScale,\n options.maxScale,\n options.zoomSensitivity,\n options.clickZoomScale,\n options.dragThresholdMouse,\n options.dragThresholdTouch,\n options.swipeThreshold,\n options.boundsBuffer,\n options.manageCursor,\n options.initialScale,\n options.initialPosition\n ])\n\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Internal helper to get content element\n const getContentElement = useCallback(() => {\n return (contentRef.current || containerRef.current?.firstElementChild) as HTMLElement | null\n }, [containerRef])\n const [scale, setScale] = useState(config.initialScale ?? config.minScale)\n const [position, setPosition] = useState<Position>(config.initialPosition ?? { x: 0, y: 0 })\n const [isDragging, setIsDragging] = useState(false)\n const [isTransitioning, setIsTransitioning] = useState(false)\n\n const dragStartRef = useRef<DragState>({\n x: 0,\n y: 0,\n hasDragged: false,\n startX: 0,\n startY: 0,\n })\n\n const pinchRef = useRef<PinchState>({\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n })\n\n const touchStartXRef = useRef<number>(0)\n const swipeBlockedRef = useRef<boolean>(false)\n\n // Track state for stable event listeners (non-passive wheel)\n const stateRef = useRef({ scale, position, enableZoom, isDragging, config })\n useEffect(() => {\n stateRef.current = { scale, position, enableZoom, isDragging, config }\n }, [scale, position, enableZoom, isDragging, config])\n\n // Cleanup on unmount and global window listeners for robustness\n useEffect(() => {\n const handleGlobalUp = () => {\n if (stateRef.current.isDragging) {\n setIsDragging(false)\n }\n }\n\n const handleBlur = () => {\n setIsDragging(false)\n }\n\n window.addEventListener('mouseup', handleGlobalUp)\n window.addEventListener('touchend', handleGlobalUp)\n window.addEventListener('touchcancel', handleGlobalUp)\n window.addEventListener('blur', handleBlur)\n\n return () => {\n window.removeEventListener('mouseup', handleGlobalUp)\n window.removeEventListener('touchend', handleGlobalUp)\n window.removeEventListener('touchcancel', handleGlobalUp)\n window.removeEventListener('blur', handleBlur)\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n setIsTransitioning(false)\n }\n }, [])\n\n\n // Handle container resize and content load\n const updateBoundsAndClamp = useCallback(() => {\n const container = containerRef.current\n const content = getContentElement()\n if (!container || !content) return\n const currentPos = { x: stateRef.current.position.x, y: stateRef.current.position.y }\n const clamped = clampPosition(currentPos, stateRef.current.scale, container, content, config.boundsBuffer)\n if (clamped.x !== currentPos.x || clamped.y !== currentPos.y) {\n setPosition(clamped)\n }\n }, [containerRef, config.boundsBuffer, getContentElement])\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver(() => {\n updateBoundsAndClamp()\n })\n\n observer.observe(container)\n \n // Also listen for image loads in the content\n const content = getContentElement()\n if (content instanceof HTMLImageElement && !content.complete) {\n content.addEventListener('load', updateBoundsAndClamp)\n }\n\n return () => {\n observer.disconnect()\n if (content instanceof HTMLImageElement) {\n content.removeEventListener('load', updateBoundsAndClamp)\n }\n }\n }, [containerRef, updateBoundsAndClamp, getContentElement])\n\n // Internal clamp helper that uses current config and container\n const getClampedPosition = useCallback(\n (pos: Position, targetScale: number, element: HTMLElement): Position => {\n return clampPosition(\n pos,\n targetScale,\n containerRef.current,\n element,\n config.boundsBuffer\n )\n },\n [containerRef, config.boundsBuffer],\n )\n\n const handleWheelManual = useCallback(\n (e: WheelEvent) => {\n if (!stateRef.current.enableZoom) return\n setIsTransitioning(false) // Cancel any active transition\n e.preventDefault()\n\n const { scale: currentScale, position: currentPosition, config } = stateRef.current\n \n // Normalize deltaY: Trackpads often send small deltas, physical wheels send large ones.\n const delta = normalizeWheelDelta(e, config.zoomSensitivity)\n const newScale = Math.min(Math.max(config.minScale, currentScale + delta), config.maxScale)\n\n if (newScale === config.minScale) {\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n } else {\n const container = containerRef.current\n const content = getContentElement()\n if (container && content) {\n const rect = container.getBoundingClientRect()\n const containerWidth = rect.width\n const containerHeight = rect.height\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n // Content coordinate at mouse position\n const contentX = (mouseX - currentPosition.x) / currentScale\n const contentY = (mouseY - currentPosition.y) / currentScale\n\n // New position maintaining the mouse over the same content point\n const newPosition = {\n x: mouseX - contentX * newScale,\n y: mouseY - contentY * newScale,\n }\n\n const clampedPosition = getClampedPosition(newPosition, newScale, content)\n setPosition(clampedPosition)\n setScale(newScale)\n }\n }\n },\n [getClampedPosition, containerRef, getContentElement, config.zoomSensitivity, config.minScale, config.maxScale],\n )\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n container.addEventListener('wheel', handleWheelManual, { passive: false })\n return () => container.removeEventListener('wheel', handleWheelManual)\n }, [containerRef, handleWheelManual])\n\n const reset = useCallback(() => {\n setIsTransitioning(true)\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n pinchRef.current = {\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n }\n }, [config.minScale])\n\n const handleFocalZoom = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const target = e.currentTarget\n if (!container || !target) return\n\n const rect = container.getBoundingClientRect()\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n const newPosition = {\n x: mouseX * (1 - config.clickZoomScale),\n y: mouseY * (1 - config.clickZoomScale),\n }\n\n const clampedPosition = getClampedPosition(newPosition, config.clickZoomScale, target)\n\n setScale(config.clickZoomScale)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n const onImageClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n // Prevent zoom if user was dragging\n if (dragStartRef.current.hasDragged) {\n dragStartRef.current.hasDragged = false\n return\n }\n\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const onImageDoubleClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const getPinchPosition = useCallback((centerX: number, centerY: number, newScale: number): Position => {\n const { containerRect, startX, startY, initialScale, startPos } = pinchRef.current\n if (!containerRect) return { x: 0, y: 0 }\n\n const containerCenterX = containerRect.width / 2\n const containerCenterY = containerRect.height / 2\n\n // Pinch center relative to container center\n const currentPinchX = centerX - (containerRect.left + containerCenterX)\n const currentPinchY = centerY - (containerRect.top + containerCenterY)\n \n // Initial pinch center relative to container center\n const startPinchX = startX - (containerRect.left + containerCenterX)\n const startPinchY = startY - (containerRect.top + containerCenterY)\n\n const scaleRatio = newScale / initialScale\n const pinchImageX = startPinchX - startPos.x\n const pinchImageY = startPinchY - startPos.y\n\n return {\n x: currentPinchX - pinchImageX * scaleRatio,\n y: currentPinchY - pinchImageY * scaleRatio,\n }\n }, [])\n\n const onImageTouchStart = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n swipeBlockedRef.current = e.touches.length === 2\n\n if (e.touches.length === 2) {\n // Pinch zoom\n const container = containerRef.current\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n pinchRef.current = {\n startDist: dist,\n initialScale: scale,\n startX: centerX,\n startY: centerY,\n startPos: { x: position.x, y: position.y },\n containerRect: container?.getBoundingClientRect()\n }\n } else if (e.touches.length === 1 && scale > config.minScale) {\n // Swipe navigation disabled when zoomed\n setIsDragging(true)\n dragStartRef.current = {\n x: e.touches[0].clientX - position.x,\n y: e.touches[0].clientY - position.y,\n hasDragged: false,\n startX: e.touches[0].clientX,\n startY: e.touches[0].clientY,\n }\n }\n },\n [scale, position, config.minScale, containerRef],\n )\n\n const onImageTouchMove = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n if (e.touches.length === 2) {\n // Pinch zoom\n e.preventDefault()\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n const ratio = dist / pinchRef.current.startDist\n const newScale = Math.min(Math.max(config.minScale, pinchRef.current.initialScale * ratio), config.maxScale)\n\n if (pinchRef.current.containerRect && newScale > config.minScale) {\n const newPosition = getPinchPosition(\n centerX, \n centerY, \n newScale, \n )\n \n const clampedPosition = getClampedPosition(\n newPosition,\n newScale,\n getContentElement() as HTMLElement,\n )\n setPosition(clampedPosition)\n } else {\n setPosition({ x: 0, y: 0 })\n }\n setScale(newScale)\n } else if (e.touches.length === 1 && isDragging && scale > config.minScale) {\n // Pan when zoomed\n e.preventDefault()\n const touchX = e.touches[0].clientX\n const touchY = e.touches[0].clientY\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n touchX - dragStartRef.current.startX,\n touchY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdTouch) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: touchX - dragStartRef.current.x,\n y: touchY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, getContentElement, getPinchPosition, config.minScale, config.maxScale, config.dragThresholdTouch],\n )\n\n const onImageTouchEnd = useCallback(() => {\n setIsDragging(false)\n // Reset pinch state to avoid stale calculations\n pinchRef.current = {\n startDist: 0,\n initialScale: scale,\n startX: 0,\n startY: 0,\n startPos: { x: position.x, y: position.y },\n }\n }, [scale, position])\n\n const onImageMouseDown = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n if (scale > config.minScale) {\n e.preventDefault()\n setIsDragging(true)\n dragStartRef.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n hasDragged: false,\n startX: e.clientX,\n startY: e.clientY,\n }\n }\n },\n [scale, position, config.minScale],\n )\n\n const handleSwipe = useCallback(\n (targetX: number, targetY: number) => {\n if (!config.enableSwipe) return\n\n const distanceX = Math.abs(targetX - dragStartRef.current.startX)\n const distanceY = Math.abs(targetY - dragStartRef.current.startY)\n\n // Only consider as swipe if movement is predominantly horizontal\n if (distanceX > config.swipeThreshold && distanceX > distanceY) {\n if (targetX < dragStartRef.current.startX) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [config.enableSwipe, config.swipeThreshold, onNext, onPrev]\n )\n\n const onImageMouseMove = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (isDragging && scale > config.minScale) {\n e.preventDefault()\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n e.clientX - dragStartRef.current.startX,\n e.clientY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdMouse) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: e.clientX - dragStartRef.current.x,\n y: e.clientY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, config.minScale, config.dragThresholdMouse],\n )\n\n const onImageMouseUp = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onImageMouseLeave = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onContainerTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n touchStartXRef.current = touch.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerTouchEnd = useCallback(\n (e: React.TouchEvent) => {\n if (swipeBlockedRef.current) {\n swipeBlockedRef.current = false\n return\n }\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n const startX = touchStartXRef.current\n const endX = touch.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const onContainerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n touchStartXRef.current = e.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerMouseUp = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n const startX = touchStartXRef.current\n const endX = e.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const zoomTo = useCallback(\n (x: number, y: number, targetScale?: number) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const content = contentRef.current || container?.firstElementChild as HTMLElement\n if (!container || !content) return\n\n const scaleToUse = targetScale ?? config.clickZoomScale\n const contentWidth = content.offsetWidth\n const contentHeight = content.offsetHeight\n \n // Calculate position to center the (x, y) point\n // Since transform-origin is center (default), the offset to center a point (x,y) is:\n // (CenterOfContent - TargetPoint) * Scale\n const newPosition = {\n x: (contentWidth / 2 - x) * scaleToUse,\n y: (contentHeight / 2 - y) * scaleToUse,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scaleToUse, content)\n\n setScale(scaleToUse)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n // Clear transition state after duration completes\n useEffect(() => {\n if (!isTransitioning) return\n const timer = setTimeout(() => setIsTransitioning(false), TRANSITION_DURATION)\n return () => clearTimeout(timer)\n }, [isTransitioning])\n\n // Cleanup handled in main effect hook above\n\n const contentStyle = React.useMemo(() => {\n const style: React.CSSProperties = {\n transformOrigin: 'center',\n transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : 'none'\n }\n\n if (config.manageCursor) {\n if (isDragging) {\n style.cursor = 'grabbing'\n } else if (scale > config.minScale) {\n style.cursor = 'grab'\n } else if (enableZoom) {\n style.cursor = 'zoom-in'\n } else {\n style.cursor = 'default'\n }\n }\n\n return style\n }, [isTransitioning, config.manageCursor, isDragging, scale, config.minScale, enableZoom])\n\n const contentProps = React.useMemo(() => ({\n ref: contentRef as React.Ref<any>, // Cast to compatible ref type\n style: contentStyle,\n onClick: onImageClick,\n onDoubleClick: onImageDoubleClick,\n onTouchStart: onImageTouchStart,\n onTouchMove: onImageTouchMove,\n onTouchEnd: onImageTouchEnd,\n onMouseDown: onImageMouseDown,\n onMouseMove: onImageMouseMove,\n onMouseUp: onImageMouseUp,\n onMouseLeave: onImageMouseLeave,\n }), [\n contentStyle,\n onImageClick,\n onImageDoubleClick,\n onImageTouchStart,\n onImageTouchMove,\n onImageTouchEnd,\n onImageMouseDown,\n onImageMouseMove,\n onImageMouseUp,\n onImageMouseLeave\n ])\n\n const containerProps = React.useMemo(() => ({\n onTouchStart: onContainerTouchStart,\n onTouchEnd: onContainerTouchEnd,\n onMouseDown: onContainerMouseDown,\n onMouseUp: onContainerMouseUp,\n }), [\n onContainerTouchStart,\n onContainerTouchEnd,\n onContainerMouseDown,\n onContainerMouseUp\n ])\n\n return {\n scale,\n position,\n isDragging,\n reset,\n zoomTo,\n contentProps,\n containerProps,\n }\n}","'use client'\n\nimport React, { useRef, CSSProperties } from 'react'\nimport { useZoomPan, ZoomPanOptions } from './useZoomPan'\n\ninterface ZoomPanProps {\n children: React.ReactNode\n className?: string\n style?: CSSProperties\n contentClassName?: string\n contentStyle?: CSSProperties\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n/**\n * A simple component wrapper for zoom and pan functionality.\n * Wrap any content (images, SVG, canvas, etc.) to make it zoomable and pannable.\n * \n * @example\n * ```tsx\n * <ZoomPan>\n * <img src=\"photo.jpg\" alt=\"Zoomable\" />\n * </ZoomPan>\n * ```\n * \n * @example With custom options\n * ```tsx\n * <ZoomPan options={{ maxScale: 6, clickZoomScale: 3 }}>\n * <canvas ref={canvasRef} />\n * </ZoomPan>\n * ```\n */\nexport const ZoomPan: React.FC<ZoomPanProps> = ({\n children,\n className = '',\n style = {},\n contentClassName = '',\n contentStyle = {},\n enableZoom = true,\n onNext,\n onPrev,\n options,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null)\n\n const { scale, position, contentProps, containerProps } = useZoomPan({\n containerRef,\n enableZoom,\n onNext,\n onPrev,\n options,\n })\n\n const defaultContainerStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: scale > 1 ? 'grab' : enableZoom ? 'zoom-in' : 'default',\n position: 'relative',\n ...style,\n }\n\n const defaultContentStyle: CSSProperties = {\n transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,\n ...contentProps.style,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n touchAction: 'none',\n maxWidth: '100%',\n maxHeight: '100%',\n ...contentStyle,\n }\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={defaultContainerStyle}\n {...containerProps}\n >\n <div\n className={contentClassName}\n {...contentProps}\n style={{\n ...defaultContentStyle,\n ...contentProps.style,\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport default ZoomPan"]}
1
+ {"version":3,"sources":["../src/useZoomPan.ts","../src/ZoomPan.tsx"],"names":["config","useRef","React"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client'\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\n\ninterface Position {\n x: number\n y: number\n}\n\nexport interface ZoomPanOptions {\n /** Minimum zoom scale (default: 1) */\n minScale?: number\n /** Maximum zoom scale (default: 4) */\n maxScale?: number\n /** Initial zoom scale (default: minScale) */\n initialScale?: number\n /** Initial x/y position (default: {x:0, y:0}) */\n initialPosition?: Position\n /** Mouse wheel zoom sensitivity (default: 0.002) */\n zoomSensitivity?: number\n /** Zoom level when clicking to zoom (default: 2.5) */\n clickZoomScale?: number\n /** Pixels moved before drag is detected on mouse (default: 5) */\n dragThresholdMouse?: number\n /** Pixels moved before drag is detected on touch (default: 10) */\n dragThresholdTouch?: number\n /** Pixels swiped before navigation triggers (default: 50) */\n swipeThreshold?: number\n /** Extra pan space beyond image edges in pixels (default: 80) */\n boundsBuffer?: number\n /** Whether to automatically manage cursor states (default: true) */\n manageCursor?: boolean\n /** Whether to enable swipe navigation (default: true) */\n enableSwipe?: boolean\n}\n\ninterface ZoomPanProps {\n /** Reference to the container element (div, section, etc.) */\n containerRef: React.RefObject<HTMLElement | null>\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n// Default configuration\nconst DEFAULT_OPTIONS: Required<Omit<ZoomPanOptions, 'initialScale' | 'initialPosition'>> & { initialScale?: number, initialPosition?: Position } = {\n minScale: 1,\n maxScale: 6,\n zoomSensitivity: 0.002,\n clickZoomScale: 2.5,\n dragThresholdMouse: 5,\n dragThresholdTouch: 10,\n swipeThreshold: 50,\n boundsBuffer: 80,\n manageCursor: true,\n enableSwipe: true,\n initialScale: undefined,\n initialPosition: undefined,\n}\n\nconst TRANSITION_DURATION = 400\nconst TRANSITION_CURVE = 'cubic-bezier(0.2, 0, 0, 1)'\n\ninterface DragState {\n /** Current cumulative X position relative to start position */\n x: number\n /** Current cumulative Y position relative to start position */\n y: number\n /** Flag to prevent click events if a drag occurred */\n hasDragged: boolean\n /** Initial clientX when interaction started */\n startX: number\n /** Initial clientY when interaction started */\n startY: number\n}\n\ninterface PinchState {\n /** Distance between two fingers when pinch started */\n startDist: number\n /** Zoom level when pinch started */\n initialScale: number\n /** Center X between two fingers when pinch started */\n startX: number\n /** Center Y between two fingers when pinch started */\n startY: number\n /** Content position when pinch started */\n startPos: Position\n /** Cached container rect for performant coordinate mapping */\n containerRect?: DOMRect\n}\n\n// Helper functions for boundary calculations\ninterface Bounds {\n xLimit: number\n yLimit: number\n}\n\nconst calculateBounds = (\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Bounds => {\n if (!container || !element) return { xLimit: 0, yLimit: 0 }\n\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const elementWidth = element.offsetWidth || containerWidth\n const elementHeight = element.offsetHeight || containerHeight\n\n const scaledWidth = elementWidth * targetScale\n const scaledHeight = elementHeight * targetScale\n\n const xLimit = (scaledWidth <= containerWidth ? 0 : (scaledWidth - containerWidth) / 2) + boundsBuffer\n const yLimit = (scaledHeight <= containerHeight ? 0 : (scaledHeight - containerHeight) / 2) + boundsBuffer\n\n return { xLimit, yLimit }\n}\n\nconst clampPosition = (\n pos: Position,\n targetScale: number,\n container: HTMLElement | null,\n element: HTMLElement | null,\n boundsBuffer: number\n): Position => {\n const { xLimit, yLimit } = calculateBounds(targetScale, container, element, boundsBuffer)\n return {\n x: Math.max(-xLimit, Math.min(xLimit, pos.x)),\n y: Math.max(-yLimit, Math.min(yLimit, pos.y)),\n }\n}\n\n/** \n * Normalizes wheel delta across browsers and input devices.\n * Trackpads send small deltas, physical wheels send large ones mapped by deltaMode.\n */\nconst normalizeWheelDelta = (e: WheelEvent, sensitivity: number): number => {\n // deltaMode 1 is 'lines' (physical wheels), 0 is 'pixels' (trackpads)\n const factor = e.deltaMode === 1 ? 20 : 1 \n return -e.deltaY * factor * sensitivity\n}\n\n/**\n * A highly optimized hook for zoom and pan interactions.\n * Supports mouse wheel, dragging, double-click to focal zoom, and pinch-to-zoom on touch.\n */\nexport const useZoomPan = ({\n containerRef,\n enableZoom = true,\n onNext,\n onPrev,\n options = {}\n}: ZoomPanProps) => {\n // Memoize the merged config to ensure stability\n const config = React.useMemo(() => ({\n ...DEFAULT_OPTIONS,\n ...options\n }), [\n options.minScale,\n options.maxScale,\n options.zoomSensitivity,\n options.clickZoomScale,\n options.dragThresholdMouse,\n options.dragThresholdTouch,\n options.swipeThreshold,\n options.boundsBuffer,\n options.manageCursor,\n options.initialScale,\n options.initialPosition\n ])\n\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Internal helper to get content element\n const getContentElement = useCallback(() => {\n return (contentRef.current || containerRef.current?.firstElementChild) as HTMLElement | null\n }, [containerRef])\n const [scale, setScale] = useState(config.initialScale ?? config.minScale)\n const [position, setPosition] = useState<Position>(config.initialPosition ?? { x: 0, y: 0 })\n const [isDragging, setIsDragging] = useState(false)\n const [isTransitioning, setIsTransitioning] = useState(false)\n\n const dragStartRef = useRef<DragState>({\n x: 0,\n y: 0,\n hasDragged: false,\n startX: 0,\n startY: 0,\n })\n\n const pinchRef = useRef<PinchState>({\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n })\n\n const touchStartXRef = useRef<number>(0)\n const swipeBlockedRef = useRef<boolean>(false)\n\n // Track state for stable event listeners (non-passive wheel)\n const stateRef = useRef({ scale, position, enableZoom, isDragging, config })\n useEffect(() => {\n stateRef.current = { scale, position, enableZoom, isDragging, config }\n }, [scale, position, enableZoom, isDragging, config])\n\n // Cleanup on unmount and global window listeners for robustness\n useEffect(() => {\n const handleGlobalUp = () => {\n if (stateRef.current.isDragging) {\n setIsDragging(false)\n }\n }\n\n const handleBlur = () => {\n setIsDragging(false)\n }\n\n window.addEventListener('mouseup', handleGlobalUp)\n window.addEventListener('touchend', handleGlobalUp)\n window.addEventListener('touchcancel', handleGlobalUp)\n window.addEventListener('blur', handleBlur)\n\n return () => {\n window.removeEventListener('mouseup', handleGlobalUp)\n window.removeEventListener('touchend', handleGlobalUp)\n window.removeEventListener('touchcancel', handleGlobalUp)\n window.removeEventListener('blur', handleBlur)\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n setIsTransitioning(false)\n }\n }, [])\n\n\n // Handle container resize and content load\n const updateBoundsAndClamp = useCallback(() => {\n const container = containerRef.current\n const content = getContentElement()\n if (!container || !content) return\n const currentPos = { x: stateRef.current.position.x, y: stateRef.current.position.y }\n const clamped = clampPosition(currentPos, stateRef.current.scale, container, content, config.boundsBuffer)\n if (clamped.x !== currentPos.x || clamped.y !== currentPos.y) {\n setPosition(clamped)\n }\n }, [containerRef, config.boundsBuffer, getContentElement])\n\n React.useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver(() => {\n updateBoundsAndClamp()\n })\n\n observer.observe(container)\n \n // Also listen for image loads in the content\n const content = getContentElement()\n if (content instanceof HTMLImageElement && !content.complete) {\n content.addEventListener('load', updateBoundsAndClamp)\n }\n\n return () => {\n observer.disconnect()\n if (content instanceof HTMLImageElement) {\n content.removeEventListener('load', updateBoundsAndClamp)\n }\n }\n }, [containerRef, updateBoundsAndClamp, getContentElement])\n\n // Internal clamp helper that uses current config and container\n const getClampedPosition = useCallback(\n (pos: Position, targetScale: number, element: HTMLElement): Position => {\n return clampPosition(\n pos,\n targetScale,\n containerRef.current,\n element,\n config.boundsBuffer\n )\n },\n [containerRef, config.boundsBuffer],\n )\n\n const handleWheelManual = useCallback(\n (e: WheelEvent) => {\n if (!stateRef.current.enableZoom) return\n setIsTransitioning(false) // Cancel any active transition\n e.preventDefault()\n\n const { scale: currentScale, position: currentPosition, config } = stateRef.current\n \n // Normalize deltaY: Trackpads often send small deltas, physical wheels send large ones.\n const delta = normalizeWheelDelta(e, config.zoomSensitivity)\n const newScale = Math.min(Math.max(config.minScale, currentScale + delta), config.maxScale)\n\n if (newScale === config.minScale) {\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n } else {\n const container = containerRef.current\n const content = getContentElement()\n if (container && content) {\n const rect = container.getBoundingClientRect()\n const containerWidth = rect.width\n const containerHeight = rect.height\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n // Content coordinate at mouse position\n const contentX = (mouseX - currentPosition.x) / currentScale\n const contentY = (mouseY - currentPosition.y) / currentScale\n\n // New position maintaining the mouse over the same content point\n const newPosition = {\n x: mouseX - contentX * newScale,\n y: mouseY - contentY * newScale,\n }\n\n const clampedPosition = getClampedPosition(newPosition, newScale, content)\n setPosition(clampedPosition)\n setScale(newScale)\n }\n }\n },\n [getClampedPosition, containerRef, getContentElement, config.zoomSensitivity, config.minScale, config.maxScale],\n )\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n container.addEventListener('wheel', handleWheelManual, { passive: false })\n return () => container.removeEventListener('wheel', handleWheelManual)\n }, [containerRef, handleWheelManual])\n\n const reset = useCallback(() => {\n setIsTransitioning(true)\n setScale(config.minScale)\n setPosition({ x: 0, y: 0 })\n setIsDragging(false)\n dragStartRef.current.hasDragged = false\n pinchRef.current = {\n startDist: 0,\n initialScale: config.minScale,\n startX: 0,\n startY: 0,\n startPos: { x: 0, y: 0 },\n }\n }, [config.minScale])\n\n const handleFocalZoom = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const target = e.currentTarget\n if (!container || !target) return\n\n const rect = container.getBoundingClientRect()\n const containerWidth = container.clientWidth\n const containerHeight = container.clientHeight\n const centerX = containerWidth / 2\n const centerY = containerHeight / 2\n\n // Mouse position relative to container center\n const mouseX = e.clientX - (rect.left + centerX)\n const mouseY = e.clientY - (rect.top + centerY)\n\n const newPosition = {\n x: mouseX * (1 - config.clickZoomScale),\n y: mouseY * (1 - config.clickZoomScale),\n }\n\n const clampedPosition = getClampedPosition(newPosition, config.clickZoomScale, target)\n\n setScale(config.clickZoomScale)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n const onImageClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n // Prevent zoom if user was dragging\n if (dragStartRef.current.hasDragged) {\n dragStartRef.current.hasDragged = false\n return\n }\n\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const onImageDoubleClick = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (scale > config.minScale) {\n reset()\n } else {\n handleFocalZoom(e)\n }\n },\n [scale, reset, handleFocalZoom, config.minScale],\n )\n\n const getPinchPosition = useCallback((centerX: number, centerY: number, newScale: number): Position => {\n const { containerRect, startX, startY, initialScale, startPos } = pinchRef.current\n if (!containerRect) return { x: 0, y: 0 }\n\n const containerCenterX = containerRect.width / 2\n const containerCenterY = containerRect.height / 2\n\n // Pinch center relative to container center\n const currentPinchX = centerX - (containerRect.left + containerCenterX)\n const currentPinchY = centerY - (containerRect.top + containerCenterY)\n \n // Initial pinch center relative to container center\n const startPinchX = startX - (containerRect.left + containerCenterX)\n const startPinchY = startY - (containerRect.top + containerCenterY)\n\n const scaleRatio = newScale / initialScale\n const pinchImageX = startPinchX - startPos.x\n const pinchImageY = startPinchY - startPos.y\n\n return {\n x: currentPinchX - pinchImageX * scaleRatio,\n y: currentPinchY - pinchImageY * scaleRatio,\n }\n }, [])\n\n const onImageTouchStart = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n swipeBlockedRef.current = e.touches.length === 2\n\n if (e.touches.length === 2) {\n // Pinch zoom\n const container = containerRef.current\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n pinchRef.current = {\n startDist: dist,\n initialScale: scale,\n startX: centerX,\n startY: centerY,\n startPos: { x: position.x, y: position.y },\n containerRect: container?.getBoundingClientRect()\n }\n } else if (e.touches.length === 1 && scale > config.minScale) {\n // Swipe navigation disabled when zoomed\n setIsDragging(true)\n dragStartRef.current = {\n x: e.touches[0].clientX - position.x,\n y: e.touches[0].clientY - position.y,\n hasDragged: false,\n startX: e.touches[0].clientX,\n startY: e.touches[0].clientY,\n }\n }\n },\n [scale, position, config.minScale, containerRef],\n )\n\n const onImageTouchMove = useCallback(\n (e: React.TouchEvent<HTMLImageElement>) => {\n if (e.touches.length === 2) {\n // Pinch zoom\n e.preventDefault()\n const dist = Math.hypot(\n e.touches[0].clientX - e.touches[1].clientX,\n e.touches[0].clientY - e.touches[1].clientY,\n )\n const centerX = (e.touches[0].clientX + e.touches[1].clientX) / 2\n const centerY = (e.touches[0].clientY + e.touches[1].clientY) / 2\n\n const ratio = dist / pinchRef.current.startDist\n const newScale = Math.min(Math.max(config.minScale, pinchRef.current.initialScale * ratio), config.maxScale)\n\n if (pinchRef.current.containerRect && newScale > config.minScale) {\n const newPosition = getPinchPosition(\n centerX, \n centerY, \n newScale, \n )\n \n const clampedPosition = getClampedPosition(\n newPosition,\n newScale,\n getContentElement() as HTMLElement,\n )\n setPosition(clampedPosition)\n } else {\n setPosition({ x: 0, y: 0 })\n }\n setScale(newScale)\n } else if (e.touches.length === 1 && isDragging && scale > config.minScale) {\n // Pan when zoomed\n e.preventDefault()\n const touchX = e.touches[0].clientX\n const touchY = e.touches[0].clientY\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n touchX - dragStartRef.current.startX,\n touchY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdTouch) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: touchX - dragStartRef.current.x,\n y: touchY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, getContentElement, getPinchPosition, config.minScale, config.maxScale, config.dragThresholdTouch],\n )\n\n const onImageTouchEnd = useCallback(() => {\n setIsDragging(false)\n // Reset pinch state to avoid stale calculations\n pinchRef.current = {\n startDist: 0,\n initialScale: scale,\n startX: 0,\n startY: 0,\n startPos: { x: position.x, y: position.y },\n }\n }, [scale, position])\n\n const onImageMouseDown = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n setIsTransitioning(false)\n if (scale > config.minScale) {\n e.preventDefault()\n setIsDragging(true)\n dragStartRef.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n hasDragged: false,\n startX: e.clientX,\n startY: e.clientY,\n }\n }\n },\n [scale, position, config.minScale],\n )\n\n const handleSwipe = useCallback(\n (targetX: number, targetY: number) => {\n if (!config.enableSwipe) return\n\n const distanceX = Math.abs(targetX - dragStartRef.current.startX)\n const distanceY = Math.abs(targetY - dragStartRef.current.startY)\n\n // Only consider as swipe if movement is predominantly horizontal\n if (distanceX > config.swipeThreshold && distanceX > distanceY) {\n if (targetX < dragStartRef.current.startX) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [config.enableSwipe, config.swipeThreshold, onNext, onPrev]\n )\n\n const onImageMouseMove = useCallback(\n (e: React.MouseEvent<HTMLImageElement>) => {\n if (isDragging && scale > config.minScale) {\n e.preventDefault()\n\n if (!dragStartRef.current.hasDragged) {\n const moveDist = Math.hypot(\n e.clientX - dragStartRef.current.startX,\n e.clientY - dragStartRef.current.startY,\n )\n if (moveDist > config.dragThresholdMouse) {\n dragStartRef.current.hasDragged = true\n }\n }\n\n if (dragStartRef.current.hasDragged) {\n const newPosition = {\n x: e.clientX - dragStartRef.current.x,\n y: e.clientY - dragStartRef.current.y,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scale, e.currentTarget)\n setPosition(clampedPosition)\n }\n }\n },\n [isDragging, scale, getClampedPosition, config.minScale, config.dragThresholdMouse],\n )\n\n const onImageMouseUp = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onImageMouseLeave = useCallback(() => {\n setIsDragging(false)\n }, [])\n\n const onContainerTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n touchStartXRef.current = touch.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerTouchEnd = useCallback(\n (e: React.TouchEvent) => {\n if (swipeBlockedRef.current) {\n swipeBlockedRef.current = false\n return\n }\n if (scale > config.minScale) return\n const touch = e.changedTouches[0]\n const startX = touchStartXRef.current\n const endX = touch.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const onContainerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n touchStartXRef.current = e.clientX\n },\n [scale, config.minScale],\n )\n\n const onContainerMouseUp = useCallback(\n (e: React.MouseEvent) => {\n if (scale > config.minScale) return\n const startX = touchStartXRef.current\n const endX = e.clientX\n const diff = startX - endX\n\n if (Math.abs(diff) > config.swipeThreshold) {\n if (diff > 0) {\n onNext?.()\n } else {\n onPrev?.()\n }\n }\n },\n [scale, onNext, onPrev, config.minScale, config.swipeThreshold],\n )\n\n const zoomTo = useCallback(\n (x: number, y: number, targetScale?: number) => {\n setIsTransitioning(true)\n const container = containerRef.current\n const content = contentRef.current || container?.firstElementChild as HTMLElement\n if (!container || !content) return\n\n const scaleToUse = targetScale ?? config.clickZoomScale\n const contentWidth = content.offsetWidth\n const contentHeight = content.offsetHeight\n \n // Calculate position to center the (x, y) point\n // Since transform-origin is center (default), the offset to center a point (x,y) is:\n // (CenterOfContent - TargetPoint) * Scale\n const newPosition = {\n x: (contentWidth / 2 - x) * scaleToUse,\n y: (contentHeight / 2 - y) * scaleToUse,\n }\n\n const clampedPosition = getClampedPosition(newPosition, scaleToUse, content)\n\n setScale(scaleToUse)\n setPosition(clampedPosition)\n },\n [getClampedPosition, config.clickZoomScale, containerRef],\n )\n\n // Clear transition state after duration completes\n useEffect(() => {\n if (!isTransitioning) return\n const timer = setTimeout(() => setIsTransitioning(false), TRANSITION_DURATION)\n return () => clearTimeout(timer)\n }, [isTransitioning])\n\n // Cleanup handled in main effect hook above\n\n const contentStyle = React.useMemo(() => {\n const style: React.CSSProperties = {\n transformOrigin: 'center',\n transition: isTransitioning ? `transform ${TRANSITION_DURATION}ms ${TRANSITION_CURVE}` : 'none',\n touchAction: 'none',\n userSelect: 'none',\n WebkitUserSelect: 'none',\n }\n\n if (config.manageCursor) {\n if (isDragging) {\n style.cursor = 'grabbing'\n } else if (scale > config.minScale) {\n style.cursor = 'grab'\n } else if (enableZoom) {\n style.cursor = 'zoom-in'\n } else {\n style.cursor = 'default'\n }\n }\n\n return style\n }, [isTransitioning, config.manageCursor, isDragging, scale, config.minScale, enableZoom])\n\n const contentProps = React.useMemo(() => ({\n ref: contentRef as React.Ref<any>, // Cast to compatible ref type\n style: contentStyle,\n onClick: onImageClick,\n onDoubleClick: onImageDoubleClick,\n onTouchStart: onImageTouchStart,\n onTouchMove: onImageTouchMove,\n onTouchEnd: onImageTouchEnd,\n onMouseDown: onImageMouseDown,\n onMouseMove: onImageMouseMove,\n onMouseUp: onImageMouseUp,\n onMouseLeave: onImageMouseLeave,\n }), [\n contentStyle,\n onImageClick,\n onImageDoubleClick,\n onImageTouchStart,\n onImageTouchMove,\n onImageTouchEnd,\n onImageMouseDown,\n onImageMouseMove,\n onImageMouseUp,\n onImageMouseLeave\n ])\n\n const containerProps = React.useMemo(() => ({\n onTouchStart: onContainerTouchStart,\n onTouchEnd: onContainerTouchEnd,\n onMouseDown: onContainerMouseDown,\n onMouseUp: onContainerMouseUp,\n }), [\n onContainerTouchStart,\n onContainerTouchEnd,\n onContainerMouseDown,\n onContainerMouseUp\n ])\n\n return {\n scale,\n position,\n isDragging,\n reset,\n zoomTo,\n contentProps,\n containerProps,\n }\n}","'use client'\n\nimport React, { useRef, CSSProperties } from 'react'\nimport { useZoomPan, ZoomPanOptions } from './useZoomPan'\n\ninterface ZoomPanProps {\n children: React.ReactNode\n className?: string\n style?: CSSProperties\n contentClassName?: string\n contentStyle?: CSSProperties\n enableZoom?: boolean\n onNext?: () => void\n onPrev?: () => void\n options?: ZoomPanOptions\n}\n\n/**\n * A simple component wrapper for zoom and pan functionality.\n * Wrap any content (images, SVG, canvas, etc.) to make it zoomable and pannable.\n * \n * @example\n * ```tsx\n * <ZoomPan>\n * <img src=\"photo.jpg\" alt=\"Zoomable\" />\n * </ZoomPan>\n * ```\n * \n * @example With custom options\n * ```tsx\n * <ZoomPan options={{ maxScale: 6, clickZoomScale: 3 }}>\n * <canvas ref={canvasRef} />\n * </ZoomPan>\n * ```\n */\nexport const ZoomPan: React.FC<ZoomPanProps> = ({\n children,\n className = '',\n style = {},\n contentClassName = '',\n contentStyle = {},\n enableZoom = true,\n onNext,\n onPrev,\n options,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null)\n\n const { scale, position, contentProps, containerProps } = useZoomPan({\n containerRef,\n enableZoom,\n onNext,\n onPrev,\n options,\n })\n\n const defaultContainerStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: scale > 1 ? 'grab' : enableZoom ? 'zoom-in' : 'default',\n position: 'relative',\n ...style,\n }\n\n const defaultContentStyle: CSSProperties = {\n transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,\n ...contentProps.style,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n touchAction: 'none',\n maxWidth: '100%',\n maxHeight: '100%',\n ...contentStyle,\n }\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={defaultContainerStyle}\n {...containerProps}\n >\n <div\n className={contentClassName}\n {...contentProps}\n style={{\n ...defaultContentStyle,\n ...contentProps.style,\n }}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport default ZoomPan"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitebytom/use-zoom-pan",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "React hook and component for smooth zoom and pan interactions on any content with full mouse and touch support",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",