11import { Ref } from "@odoo/o-spreadsheet-engine" ;
22import { useRefListener } from "./listener_hook" ;
33
4- const evCache : PointerEvent [ ] = [ ] ;
5- let prevDiff = - 1 ;
6-
74/** Largely inspired by the pinch-to-zoom example provided at MDN
85 * https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events/Pinch_zoom_gestures#example
96 * on the 30th of October 2025
107 */
118export function usePinchToZoom ( ref : Ref < HTMLElement > , onZoom : ( scale : number ) => void ) {
9+ const evCache : PointerEvent [ ] = [ ] ;
10+ let prevDiff = - 1 ;
11+
1212 useRefListener ( ref , "pointerdown" , pointerdownHandler , { passive : false } ) ;
1313 useRefListener ( ref , "pointermove" , pointermoveHandler , { passive : false } ) ;
1414 useRefListener ( ref , "pointerup" , pointerupHandler , { passive : false } ) ;
@@ -27,23 +27,33 @@ export function usePinchToZoom(ref: Ref<HTMLElement>, onZoom: (scale: number) =>
2727 // The pointerdown event signals the start of a touch interaction.
2828 // This event is cached to support 2-finger gestures
2929 evCache . push ( ev ) ;
30+ if ( evCache . length < 2 ) {
31+ prevDiff = - 1 ;
32+ } else if ( evCache . length === 2 ) {
33+ prevDiff = computeDistance ( evCache [ 0 ] , evCache [ 1 ] ) ;
34+ }
35+ }
36+
37+ function computeDistance ( ev1 : PointerEvent , ev2 : PointerEvent ) {
38+ const dx = ev1 . clientX - ev2 . clientX ;
39+ const dy = ev1 . clientY - ev2 . clientY ;
40+ return Math . sqrt ( dx * dx + dy * dy ) ;
3041 }
3142
3243 function pointermoveHandler ( ev : PointerEvent ) {
3344 // Find this event in the cache and update its record with this event
3445 const index = evCache . findIndex ( ( cachedEv ) => cachedEv . pointerId === ev . pointerId ) ;
46+ if ( index === - 1 ) return ;
47+
3548 evCache [ index ] = ev ;
3649
3750 // If two pointers are down, check for pinch gestures
3851 if ( evCache . length === 2 ) {
3952 // Calculate the distance between the two pointers
40- const dx = evCache [ 0 ] . clientX - evCache [ 1 ] . clientX ;
41- const dy = evCache [ 0 ] . clientY - evCache [ 1 ] . clientY ;
42-
43- const curDiff = Math . abs ( dx * dx + dy * dy ) ;
53+ const curDiff = computeDistance ( evCache [ 0 ] , evCache [ 1 ] ) ;
4454
4555 if ( prevDiff > 0 ) {
46- onZoom ( ( curDiff / prevDiff ) ** 0.25 ) ;
56+ onZoom ( ( curDiff / prevDiff ) ** 0.5 ) ;
4757 }
4858
4959 // Cache the distance for the next move event
0 commit comments