From 7ee9457be16452c7cd09607f57c9f35fccb656bf Mon Sep 17 00:00:00 2001 From: marlon-erler Date: Sun, 30 Aug 2026 22:43:56 +0200 Subject: [PATCH] fix glitches with zooming --- dist/index.js | 26 +++++++++------ src/Model/Utility/utility.ts | 63 ++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/dist/index.js b/dist/index.js index de2e9241..3c6227d3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1138,15 +1138,20 @@ } function implementPinchZoom(targetSelector) { let pinching = false; - let initialDistance = 0; - let currentZoom = 1; - let initialZoom = 1; - let currentX = 0; - let currentY = 0; - let initialX = 0; - let initialY = 0; - let initialTouchX = 0; - let initialTouchY = 0; + let lastElement = void 0; + let initialDistance, currentZoom, initialZoom, currentX, currentY, initialX, initialY, initialTouchX, initialTouchY; + function reset() { + initialDistance = 0; + currentZoom = 1; + initialZoom = 1; + currentX = 0; + currentY = 0; + initialX = 0; + initialY = 0; + initialTouchX = 0; + initialTouchY = 0; + } + reset(); const MIN = 0.25; const MAX = 5; const element = () => canvas.querySelector(targetSelector); @@ -1160,7 +1165,6 @@ function apply(factor, offset) { if (factor < MIN) return apply(MIN, offset); if (factor > MAX) return apply(5, offset); - if (!element) return; const [x, y] = offset; element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`; currentX = x; @@ -1170,6 +1174,8 @@ const canvas = document.body; canvas.addEventListener("touchstart", (event) => { document.activeElement.blur(); + if (lastElement != void 0 && lastElement != element()) reset(); + lastElement = element(); initialZoom = currentZoom; initialX = currentX; initialY = currentY; diff --git a/src/Model/Utility/utility.ts b/src/Model/Utility/utility.ts index 65e61c35..da2f7d53 100644 --- a/src/Model/Utility/utility.ts +++ b/src/Model/Utility/utility.ts @@ -281,18 +281,29 @@ export function localeCompare(a: string, b: string): number { // ui export function implementPinchZoom(targetSelector: string) { let pinching = false; + let lastElement: HTMLElement|undefined = undefined; - let initialDistance = 0; + let initialDistance, + currentZoom, initialZoom, + currentX, currentY, + initialX, initialY, + initialTouchX, initialTouchY; - let currentZoom = 1; - let initialZoom = 1; + function reset() { + initialDistance = 0; - let currentX = 0; - let currentY = 0; - let initialX = 0; - let initialY = 0; - let initialTouchX = 0; - let initialTouchY = 0; + currentZoom = 1; + initialZoom = 1; + + currentX = 0; + currentY = 0; + initialX = 0; + initialY = 0; + initialTouchX = 0; + initialTouchY = 0; + } + + reset(); const MIN = 0.25; const MAX = 5; @@ -300,36 +311,38 @@ export function implementPinchZoom(targetSelector: string) { const element = (): HTMLElement => canvas.querySelector(targetSelector); const parent = (): HTMLElement => element().parentElement; const distance = (e: TouchEvent) => - Math.hypot( - e.touches[0].pageX - e.touches[1].pageX, - e.touches[0].pageY - e.touches[1].pageY, - ); + Math.hypot( + e.touches[0].pageX - e.touches[1].pageX, + e.touches[0].pageY - e.touches[1].pageY, + ); const point = (e: TouchEvent, direction: "x" | "y", i: number) => - e.touches[i][direction == "x" ? "clientX" : "clientY"]; + e.touches[i][direction == "x" ? "clientX" : "clientY"]; const midpoint = (e: TouchEvent, direction: "x" | "y") => - (point(e, direction, 0) + point(e, direction, 1)) / 2; + (point(e, direction, 0) + point(e, direction, 1)) / 2; function apply(factor: number, offset: [number, number]) { - if (factor < MIN) return apply(MIN, offset); - if (factor > MAX) return apply(5, offset); - if (!element) return; + if (factor < MIN) return apply(MIN, offset); + if (factor > MAX) return apply(5, offset); - const [x, y] = offset; - element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`; - currentX = x; - currentY = y; - currentZoom = factor; + const [x, y] = offset; + element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`; + currentX = x; + currentY = y; + currentZoom = factor; } const canvas = document.body; canvas.addEventListener("touchstart", (event: TouchEvent) => { (document.activeElement as HTMLElement).blur(); - initialZoom = currentZoom; + if (lastElement != undefined && lastElement != element()) reset(); + lastElement = element(); + + initialZoom = currentZoom; initialX = currentX; initialY = currentY; - if (event.touches.length != 2) { + if (event.touches.length != 2) { pinching = false; initialTouchX = event.touches[0].clientX; initialTouchY = event.touches[0].clientY;