Skip to content

Commit 6016a50

Browse files
committed
feat(zoom): highly improve pinch-zoom gestures handling
1 parent 7f7f57e commit 6016a50

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

src/modules/zoom/zoom.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
2929
let fakeGestureMoved;
3030
const evCache = [];
3131
const gesture = {
32+
originX: 0,
33+
originY: 0,
3234
slideEl: undefined,
3335
slideWidth: undefined,
3436
slideHeight: undefined,
@@ -158,7 +160,8 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
158160
}
159161
if (gesture.imageEl) {
160162
const [originX, originY] = getScaleOrigin();
161-
gesture.imageEl.style.transformOrigin = `${originX}px ${originY}px`;
163+
gesture.originX = originX;
164+
gesture.originY = originY;
162165
gesture.imageEl.style.transitionDuration = '0ms';
163166
}
164167
isScaling = true;
@@ -187,7 +190,6 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
187190
if (zoom.scale < params.minRatio) {
188191
zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
189192
}
190-
191193
gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
192194
}
193195
function onGestureEnd(e) {
@@ -216,18 +218,22 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
216218
gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
217219
} else if (zoom.scale <= 1 && gesture.slideEl) {
218220
gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
219-
gesture.imageEl.style.transformOrigin = ``;
220221
}
221-
if (zoom.scale === 1) gesture.slideEl = undefined;
222+
if (zoom.scale === 1) {
223+
gesture.originX = 0;
224+
gesture.originY = 0;
225+
gesture.slideEl = undefined;
226+
}
222227
}
223228
function onTouchStart(e) {
224229
const device = swiper.device;
225230
if (!gesture.imageEl) return;
226231
if (image.isTouched) return;
227232
if (device.android && e.cancelable) e.preventDefault();
228233
image.isTouched = true;
229-
image.touchesStart.x = e.pageX;
230-
image.touchesStart.y = e.pageY;
234+
const event = evCache.length > 0 ? evCache[0] : e;
235+
image.touchesStart.x = event.pageX;
236+
image.touchesStart.y = event.pageY;
231237
}
232238
function onTouchMove(e) {
233239
if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
@@ -293,8 +299,20 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
293299
e.stopPropagation();
294300

295301
image.isMoved = true;
296-
image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX;
297-
image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY;
302+
const scaleRatio =
303+
(zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
304+
const { originX, originY } = gesture;
305+
306+
image.currentX =
307+
image.touchesCurrent.x -
308+
image.touchesStart.x +
309+
image.startX +
310+
scaleRatio * (image.width - originX * 2);
311+
image.currentY =
312+
image.touchesCurrent.y -
313+
image.touchesStart.y +
314+
image.startY +
315+
scaleRatio * (image.height - originY * 2);
298316

299317
if (image.currentX < image.minX) {
300318
image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
@@ -381,6 +399,8 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
381399
gesture.slideEl = undefined;
382400
gesture.imageEl = undefined;
383401
gesture.imageWrapEl = undefined;
402+
gesture.originX = 0;
403+
gesture.originY = 0;
384404
}
385405
}
386406

@@ -498,7 +518,8 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
498518
translateY = 0;
499519
}
500520
if (forceZoomRatio && zoom.scale === 1) {
501-
gesture.imageEl.style.transformOrigin = ``;
521+
gesture.originX = 0;
522+
gesture.originY = 0;
502523
}
503524
gesture.imageWrapEl.style.transitionDuration = '300ms';
504525
gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
@@ -537,10 +558,11 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
537558
gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
538559
gesture.imageEl.style.transitionDuration = '300ms';
539560
gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
540-
gesture.imageEl.style.transformOrigin = ``;
541561

542562
gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
543563
gesture.slideEl = undefined;
564+
gesture.originX = 0;
565+
gesture.originY = 0;
544566
}
545567

546568
// Toggle Zoom

0 commit comments

Comments
 (0)