-
-
Notifications
You must be signed in to change notification settings - Fork 250
Expand file tree
/
Copy pathuse-pinch-zoom.svelte.ts
More file actions
88 lines (76 loc) · 2.71 KB
/
use-pinch-zoom.svelte.ts
File metadata and controls
88 lines (76 loc) · 2.71 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { getContext } from 'svelte';
import { useCapability } from '@embedpdf/core/svelte';
import type { ViewportPlugin } from '@embedpdf/plugin-viewport';
import { setupZoomGestures, type ZoomGestureOptions } from '../../shared/utils/pinch-zoom-logic';
import { useZoomCapability } from './use-zoom.svelte';
export type { ZoomGestureOptions };
/** Context type for viewport element */
type ViewportElementContext = { readonly current: HTMLDivElement | null };
export interface UseZoomGestureOptions {
/** Enable pinch-to-zoom gesture (default: true) */
enablePinch?: () => boolean;
/** Enable wheel zoom with ctrl/cmd key (default: true) */
enableWheel?: () => boolean;
/** Override wheel zoom step; 0.1 = 10% (default: 0.1) */
zoomStep?: () => number;
}
/**
* Hook for setting up zoom gesture functionality (pinch and wheel zoom) on an element
* @param getDocumentId Function that returns the document ID
* @param options Optional configuration for enabling/disabling gestures
*/
export function useZoomGesture(
getDocumentId: () => string | null,
options: UseZoomGestureOptions = {},
) {
const viewportCapability = useCapability<ViewportPlugin>('viewport');
const zoomCapability = useZoomCapability();
const viewportElementCtx = getContext<ViewportElementContext | undefined>('viewport-element');
let elementRef = $state<HTMLDivElement | null>(null);
let cleanup: (() => void) | undefined;
// Reactive documentId and options
const documentId = $derived(getDocumentId());
const enablePinch = $derived(options.enablePinch?.() ?? true);
const enableWheel = $derived(options.enableWheel?.() ?? true);
const zoomStep = $derived(options.zoomStep?.() ?? 0.1);
$effect(() => {
const element = elementRef;
const container = viewportElementCtx?.current;
const viewport = viewportCapability.provides;
const zoom = zoomCapability.provides;
const docId = documentId;
const pinchEnabled = enablePinch;
const wheelEnabled = enableWheel;
// Clean up previous setup
if (cleanup) {
cleanup();
cleanup = undefined;
}
// Setup new zoom gestures if all dependencies are available
if (!element || !viewport || !zoom || !docId) {
return;
}
cleanup = setupZoomGestures({
element,
container: container || undefined,
documentId: docId,
viewportProvides: viewport,
zoomProvides: zoom,
options: { enablePinch: pinchEnabled, enableWheel: wheelEnabled, zoomStep },
});
return () => {
if (cleanup) {
cleanup();
cleanup = undefined;
}
};
});
return {
get elementRef() {
return elementRef;
},
set elementRef(value: HTMLDivElement | null) {
elementRef = value;
},
};
}