From 3089fb04189577bae66e2aeb2c412b0e1ef9a3d4 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 9 Jul 2025 22:01:30 +0200 Subject: refactor: move timeline zoom to custom hook --- apps/web/src/hooks/use-timeline-zoom.ts | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 apps/web/src/hooks/use-timeline-zoom.ts (limited to 'apps/web/src/hooks') diff --git a/apps/web/src/hooks/use-timeline-zoom.ts b/apps/web/src/hooks/use-timeline-zoom.ts new file mode 100644 index 00000000..b1f77456 --- /dev/null +++ b/apps/web/src/hooks/use-timeline-zoom.ts @@ -0,0 +1,54 @@ +import { useState, useCallback, useEffect, RefObject } from "react"; + +interface UseTimelineZoomProps { + containerRef: RefObject; + isInTimeline?: boolean; +} + +interface UseTimelineZoomReturn { + zoomLevel: number; + setZoomLevel: (zoomLevel: number | ((prev: number) => number)) => void; + handleWheel: (e: React.WheelEvent) => void; +} + +export function useTimelineZoom({ + containerRef, + isInTimeline = false, +}: UseTimelineZoomProps): UseTimelineZoomReturn { + const [zoomLevel, setZoomLevel] = useState(1); + + const handleWheel = useCallback((e: React.WheelEvent) => { + // Only zoom if user is using pinch gesture (ctrlKey or metaKey is true) + if (e.ctrlKey || e.metaKey) { + e.preventDefault(); + const delta = e.deltaY > 0 ? -0.05 : 0.05; + setZoomLevel((prev) => Math.max(0.1, Math.min(10, prev + delta))); + } + // Otherwise, allow normal scrolling + }, []); + + // Prevent browser zooming in/out when in timeline + useEffect(() => { + const preventZoom = (e: WheelEvent) => { + if ( + isInTimeline && + (e.ctrlKey || e.metaKey) && + containerRef.current?.contains(e.target as Node) + ) { + e.preventDefault(); + } + }; + + document.addEventListener("wheel", preventZoom, { passive: false }); + + return () => { + document.removeEventListener("wheel", preventZoom); + }; + }, [isInTimeline, containerRef]); + + return { + zoomLevel, + setZoomLevel, + handleWheel, + }; +} -- cgit v1.3.1