fix glitches with zooming

This commit is contained in:
marlon-erler
2026-08-30 22:43:56 +02:00
parent f159d45c75
commit 7ee9457be1
2 changed files with 54 additions and 35 deletions
+16 -10
View File
@@ -1138,15 +1138,20 @@
} }
function implementPinchZoom(targetSelector) { function implementPinchZoom(targetSelector) {
let pinching = false; let pinching = false;
let initialDistance = 0; let lastElement = void 0;
let currentZoom = 1; let initialDistance, currentZoom, initialZoom, currentX, currentY, initialX, initialY, initialTouchX, initialTouchY;
let initialZoom = 1; function reset() {
let currentX = 0; initialDistance = 0;
let currentY = 0; currentZoom = 1;
let initialX = 0; initialZoom = 1;
let initialY = 0; currentX = 0;
let initialTouchX = 0; currentY = 0;
let initialTouchY = 0; initialX = 0;
initialY = 0;
initialTouchX = 0;
initialTouchY = 0;
}
reset();
const MIN = 0.25; const MIN = 0.25;
const MAX = 5; const MAX = 5;
const element = () => canvas.querySelector(targetSelector); const element = () => canvas.querySelector(targetSelector);
@@ -1160,7 +1165,6 @@
function apply(factor, offset) { function apply(factor, offset) {
if (factor < MIN) return apply(MIN, offset); if (factor < MIN) return apply(MIN, offset);
if (factor > MAX) return apply(5, offset); if (factor > MAX) return apply(5, offset);
if (!element) return;
const [x, y] = offset; const [x, y] = offset;
element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`; element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`;
currentX = x; currentX = x;
@@ -1170,6 +1174,8 @@
const canvas = document.body; const canvas = document.body;
canvas.addEventListener("touchstart", (event) => { canvas.addEventListener("touchstart", (event) => {
document.activeElement.blur(); document.activeElement.blur();
if (lastElement != void 0 && lastElement != element()) reset();
lastElement = element();
initialZoom = currentZoom; initialZoom = currentZoom;
initialX = currentX; initialX = currentX;
initialY = currentY; initialY = currentY;
+38 -25
View File
@@ -281,18 +281,29 @@ export function localeCompare(a: string, b: string): number {
// ui // ui
export function implementPinchZoom(targetSelector: string) { export function implementPinchZoom(targetSelector: string) {
let pinching = false; let pinching = false;
let lastElement: HTMLElement|undefined = undefined;
let initialDistance = 0; let initialDistance,
currentZoom, initialZoom,
currentX, currentY,
initialX, initialY,
initialTouchX, initialTouchY;
let currentZoom = 1; function reset() {
let initialZoom = 1; initialDistance = 0;
let currentX = 0; currentZoom = 1;
let currentY = 0; initialZoom = 1;
let initialX = 0;
let initialY = 0; currentX = 0;
let initialTouchX = 0; currentY = 0;
let initialTouchY = 0; initialX = 0;
initialY = 0;
initialTouchX = 0;
initialTouchY = 0;
}
reset();
const MIN = 0.25; const MIN = 0.25;
const MAX = 5; const MAX = 5;
@@ -300,36 +311,38 @@ export function implementPinchZoom(targetSelector: string) {
const element = (): HTMLElement => canvas.querySelector(targetSelector); const element = (): HTMLElement => canvas.querySelector(targetSelector);
const parent = (): HTMLElement => element().parentElement; const parent = (): HTMLElement => element().parentElement;
const distance = (e: TouchEvent) => const distance = (e: TouchEvent) =>
Math.hypot( Math.hypot(
e.touches[0].pageX - e.touches[1].pageX, e.touches[0].pageX - e.touches[1].pageX,
e.touches[0].pageY - e.touches[1].pageY, e.touches[0].pageY - e.touches[1].pageY,
); );
const point = (e: TouchEvent, direction: "x" | "y", i: number) => 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") => 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]) { function apply(factor: number, offset: [number, number]) {
if (factor < MIN) return apply(MIN, offset); if (factor < MIN) return apply(MIN, offset);
if (factor > MAX) return apply(5, offset); if (factor > MAX) return apply(5, offset);
if (!element) return;
const [x, y] = offset; const [x, y] = offset;
element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`; element().style.transform = `scale(${(Math.floor(factor * 100) / 100).toString()}) translate(${x}px, ${y}px)`;
currentX = x; currentX = x;
currentY = y; currentY = y;
currentZoom = factor; currentZoom = factor;
} }
const canvas = document.body; const canvas = document.body;
canvas.addEventListener("touchstart", (event: TouchEvent) => { canvas.addEventListener("touchstart", (event: TouchEvent) => {
(document.activeElement as HTMLElement).blur(); (document.activeElement as HTMLElement).blur();
initialZoom = currentZoom; if (lastElement != undefined && lastElement != element()) reset();
lastElement = element();
initialZoom = currentZoom;
initialX = currentX; initialX = currentX;
initialY = currentY; initialY = currentY;
if (event.touches.length != 2) { if (event.touches.length != 2) {
pinching = false; pinching = false;
initialTouchX = event.touches[0].clientX; initialTouchX = event.touches[0].clientX;
initialTouchY = event.touches[0].clientY; initialTouchY = event.touches[0].clientY;