@@ -14,7 +14,7 @@ import { useZoomState } from "./useZoomState.js";
1414import { usePointerEvents } from "../../../hooks/usePointerEvents.js" ;
1515
1616function distance ( pointerA : React . MouseEvent , pointerB : React . MouseEvent ) {
17- return ( ( pointerA . clientX - pointerB . clientX ) ** 2 + ( pointerA . clientY - pointerB . clientY ) ** 2 ) ** 0.5 ;
17+ return Math . hypot ( pointerA . clientX - pointerB . clientX , pointerA . clientY - pointerB . clientY ) ;
1818}
1919
2020function scaleZoom ( value : number , delta : number , factor = 100 , clamp = 2 ) {
@@ -34,7 +34,11 @@ export function useZoomSensors(
3434) {
3535 const activePointers = React . useRef < React . PointerEvent [ ] > ( [ ] ) ;
3636 const lastPointerDown = React . useRef ( 0 ) ;
37- const pinchZoomDistance = React . useRef < number > ( undefined ) ;
37+ const pinchZoom = React . useRef < {
38+ previousDistance : number ;
39+ initialDistance : number ;
40+ initialZoom : number ;
41+ } > ( undefined ) ;
3842
3943 const { globalIndex } = useLightboxState ( ) ;
4044 const { getOwnerWindow } = useDocumentContext ( ) ;
@@ -48,6 +52,7 @@ export function useZoomSensors(
4852 doubleClickDelay,
4953 doubleClickMaxStops,
5054 pinchZoomDistanceFactor,
55+ pinchZoomV4,
5156 } = useZoomProps ( ) ;
5257
5358 const translateCoordinates = React . useCallback (
@@ -175,7 +180,12 @@ export function useZoomSensors(
175180 replacePointer ( event ) ;
176181
177182 if ( pointers . length === 2 ) {
178- pinchZoomDistance . current = distance ( pointers [ 0 ] , pointers [ 1 ] ) ;
183+ const initialDistance = distance ( pointers [ 0 ] , pointers [ 1 ] ) ;
184+ pinchZoom . current = {
185+ previousDistance : initialDistance ,
186+ initialDistance : Math . max ( initialDistance , 1 ) , // prevent potential division by zero
187+ initialZoom : zoom ,
188+ } ;
179189 }
180190 } ) ;
181191
@@ -184,25 +194,27 @@ export function useZoomSensors(
184194
185195 const activePointer = pointers . find ( ( p ) => p . pointerId === event . pointerId ) ;
186196
187- if ( pointers . length === 2 && pinchZoomDistance . current ) {
197+ if ( pointers . length === 2 && pinchZoom . current ) {
188198 event . stopPropagation ( ) ;
189199
190200 replacePointer ( event ) ;
191201
192202 const currentDistance = distance ( pointers [ 0 ] , pointers [ 1 ] ) ;
193- const delta = currentDistance - pinchZoomDistance . current ;
194-
195- if ( Math . abs ( delta ) > 0 ) {
196- changeZoom (
197- scaleZoom ( zoom , delta , pinchZoomDistanceFactor ) ,
198- true ,
199- ...pointers
200- . map ( ( x ) => translateCoordinates ( x ) )
201- . reduce ( ( acc , coordinate ) => coordinate . map ( ( x , i ) => acc [ i ] + x / 2 ) ) ,
202- ) ;
203-
204- pinchZoomDistance . current = currentDistance ;
205- }
203+
204+ // TODO v4: remove `pinchZoomV4` flag and make this the default behavior
205+ const targetZoom = pinchZoomV4
206+ ? ( pinchZoom . current . initialZoom / pinchZoom . current . initialDistance ) * currentDistance
207+ : scaleZoom ( zoom , currentDistance - pinchZoom . current . previousDistance , pinchZoomDistanceFactor ) ;
208+
209+ changeZoom (
210+ targetZoom ,
211+ true ,
212+ ...pointers
213+ . map ( ( x ) => translateCoordinates ( x ) )
214+ . reduce ( ( acc , coordinate ) => coordinate . map ( ( x , i ) => acc [ i ] + x / 2 ) ) ,
215+ ) ;
216+
217+ pinchZoom . current . previousDistance = currentDistance ;
206218
207219 return ;
208220 }
@@ -225,7 +237,7 @@ export function useZoomSensors(
225237 const pointers = activePointers . current ;
226238
227239 if ( pointers . length === 2 && pointers . find ( ( p ) => p . pointerId === event . pointerId ) ) {
228- pinchZoomDistance . current = undefined ;
240+ pinchZoom . current = undefined ;
229241 }
230242
231243 clearPointer ( event ) ;
@@ -238,7 +250,7 @@ export function useZoomSensors(
238250 pointers . splice ( 0 , pointers . length ) ;
239251
240252 lastPointerDown . current = 0 ;
241- pinchZoomDistance . current = undefined ;
253+ pinchZoom . current = undefined ;
242254 } , [ ] ) ;
243255
244256 usePointerEvents ( subscribeSensors , onPointerDown , onPointerMove , onPointerUp , disabled ) ;
0 commit comments