@@ -7,8 +7,28 @@ import {
77 calculateTouchMidPoint ,
88 getTouchDistance ,
99} from "./pinch.utils" ;
10- import { handleCalculateBounds } from "../bounds/bounds.utils" ;
10+ import {
11+ getMouseBoundedPosition ,
12+ handleCalculateBounds ,
13+ } from "../bounds/bounds.utils" ;
1114import { handleCalculateZoomPositions } from "../zoom/zoom.utils" ;
15+ import { getPaddingValue } from "../pan/panning.utils" ;
16+
17+ const getTouchCenter = ( event : TouchEvent ) => {
18+ let totalX = 0 ;
19+ let totalY = 0 ;
20+ // Sum up the positions of all touches
21+ for ( let i = 0 ; i < 2 ; i ++ ) {
22+ totalX += event . touches [ i ] . clientX ;
23+ totalY += event . touches [ i ] . clientY ;
24+ }
25+
26+ // Calculate the average position
27+ const x = totalX / 2 ;
28+ const y = totalY / 2 ;
29+
30+ return { x, y } ;
31+ } ;
1232
1333export const handlePinchStart = (
1434 contextInstance : ReactZoomPanPinchContext ,
@@ -21,16 +41,21 @@ export const handlePinchStart = (
2141 contextInstance . pinchStartScale = contextInstance . transformState . scale ;
2242 contextInstance . isPanning = false ;
2343
44+ const center = getTouchCenter ( event ) ;
45+ contextInstance . pinchLastCenterX = center . x ;
46+ contextInstance . pinchLastCenterY = center . y ;
47+
2448 handleCancelAnimation ( contextInstance ) ;
2549} ;
2650
2751export const handlePinchZoom = (
2852 contextInstance : ReactZoomPanPinchContext ,
2953 event : TouchEvent ,
3054) : void => {
31- const { contentComponent, pinchStartDistance } = contextInstance ;
55+ const { contentComponent, pinchStartDistance, wrapperComponent } =
56+ contextInstance ;
3257 const { scale } = contextInstance . transformState ;
33- const { limitToBounds, centerZoomedOut, zoomAnimation } =
58+ const { limitToBounds, centerZoomedOut, zoomAnimation, alignmentAnimation } =
3459 contextInstance . setup ;
3560 const { disabled, size } = zoomAnimation ;
3661
@@ -45,7 +70,15 @@ export const handlePinchZoom = (
4570 const currentDistance = getTouchDistance ( event ) ;
4671 const newScale = calculatePinchZoom ( contextInstance , currentDistance ) ;
4772
48- if ( newScale === scale ) return ;
73+ const center = getTouchCenter ( event ) ;
74+ // pan should be scale invariant.
75+ const panX = center . x - ( contextInstance . pinchLastCenterX || 0 ) ;
76+ const panY = center . y - ( contextInstance . pinchLastCenterY || 0 ) ;
77+
78+ if ( newScale === scale && 0 == panX && 0 == panY ) return ;
79+
80+ contextInstance . pinchLastCenterX = center . x ;
81+ contextInstance . pinchLastCenterY = center . y ;
4982
5083 const bounds = handleCalculateBounds ( contextInstance , newScale ) ;
5184
@@ -64,7 +97,23 @@ export const handlePinchZoom = (
6497 contextInstance . pinchMidpoint = midPoint ;
6598 contextInstance . lastDistance = currentDistance ;
6699
67- contextInstance . setTransformState ( newScale , x , y ) ;
100+ const { sizeX, sizeY } = alignmentAnimation ;
101+ const paddingValueX = getPaddingValue ( contextInstance , sizeX ) ;
102+ const paddingValueY = getPaddingValue ( contextInstance , sizeY ) ;
103+
104+ const newPositionX = x + panX ;
105+ const newPositionY = y + panY ;
106+ const { x : finalX , y : finalY } = getMouseBoundedPosition (
107+ newPositionX ,
108+ newPositionY ,
109+ bounds ,
110+ limitToBounds ,
111+ paddingValueX ,
112+ paddingValueY ,
113+ wrapperComponent ,
114+ ) ;
115+
116+ contextInstance . setTransformState ( newScale , finalX , finalY ) ;
68117} ;
69118
70119export const handlePinchStop = (
0 commit comments