1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
import { useState, useCallback, RefObject, useMemo } from "react";
interface UseTimelineZoomProps {
containerRef: RefObject<HTMLDivElement>;
isInTimeline?: boolean;
}
interface UseTimelineZoomReturn {
zoomLevel: number;
zoomStep: number;
setZoomLevel: (zoomLevel: number | ((prev: number) => number)) => void;
handleChangeZoomStep: (zoomStep: number) => void;
handleChangeZoomLevel: (zoomStep: number) => void;
handleWheel: (e: React.WheelEvent) => void;
}
export function useTimelineZoom(): UseTimelineZoomReturn {
const [zoomLevel, setZoomLevel] = useState(1);
const zoomStep = useMemo(
() =>
Math.max(1, Math.round(zoomLevel / TIMELINE_CONSTANTS.ZOOM_STEP_BASE)),
[zoomLevel]
);
const handleChangeZoomStep = useCallback((newStep: number) => {
setZoomLevel(
Math.max(
TIMELINE_CONSTANTS.ZOOM_LEVEL_MIN,
newStep * TIMELINE_CONSTANTS.ZOOM_STEP_BASE
)
);
}, []);
const handleChangeZoomLevel = useCallback((newLevel: number) => {
setZoomLevel(
Math.max(
TIMELINE_CONSTANTS.ZOOM_LEVEL_MIN,
Math.min(TIMELINE_CONSTANTS.ZOOM_LEVEL_MAX, newLevel)
)
);
}, []);
// Mouse wheel zoom, ctrl/meta gesture
const handleWheel = useCallback((e: React.WheelEvent) => {
if (e.ctrlKey || e.metaKey) {
e.preventDefault?.();
const delta =
e.deltaY > 0
? -TIMELINE_CONSTANTS.ZOOM_STEP_BASE
: TIMELINE_CONSTANTS.ZOOM_STEP_BASE;
setZoomLevel((prev) =>
Math.max(
TIMELINE_CONSTANTS.ZOOM_LEVEL_MIN,
Math.min(TIMELINE_CONSTANTS.ZOOM_LEVEL_MAX, prev + delta)
)
);
}
}, []);
return {
zoomLevel,
zoomStep,
setZoomLevel,
handleChangeZoomStep,
handleChangeZoomLevel,
handleWheel,
};
}
|