Skip to content

Commit df18209

Browse files
committed
cleanup zoom func
1 parent 4ac287f commit df18209

1 file changed

Lines changed: 23 additions & 19 deletions

File tree

src/app/dev/course/graphv2/page.tsx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,14 @@ export default function GraphFunctionalPage() {
305305
let pinchActive = false;
306306
let lastX = 0, lastY = 0;
307307
let lastDist = 0;
308-
let lastMid = { x: 0, y: 0 };
309-
let startView = { x: 0, y: 0, k: 1 };
310308

311-
const getTouchMid = (t1: Touch, t2: Touch) => ({
312-
x: (t1.clientX + t2.clientX) / 2,
313-
y: (t1.clientY + t2.clientY) / 2,
314-
});
309+
const getTouchMid = (t1: Touch, t2: Touch) => {
310+
const rect = container.getBoundingClientRect();
311+
return {
312+
x: (t1.clientX + t2.clientX) / 2 - rect.left,
313+
y: (t1.clientY + t2.clientY) / 2 - rect.top,
314+
};
315+
};
315316
const getTouchDist = (t1: Touch, t2: Touch) => {
316317
const dx = t1.clientX - t2.clientX;
317318
const dy = t1.clientY - t2.clientY;
@@ -327,25 +328,28 @@ export default function GraphFunctionalPage() {
327328
pinchActive = true;
328329
panActive = false;
329330
lastDist = getTouchDist(e.touches[0], e.touches[1]);
330-
lastMid = getTouchMid(e.touches[0], e.touches[1]);
331-
startView = { ...viewRef.current };
332331
}
333332
};
334333
const onTouchMove = (e: TouchEvent) => {
335334
if (pinchActive && e.touches.length === 2) {
336335
e.preventDefault();
337336
const dist = getTouchDist(e.touches[0], e.touches[1]);
338-
const mid = getTouchMid(e.touches[0], e.touches[1]);
339-
const scale = dist / lastDist;
340-
const newK = Math.max(0.2, Math.min(4, startView.k * scale));
341-
// Pan so that the midpoint stays under the same screen point
342-
const dx = (mid.x - lastMid.x) / newK;
343-
const dy = (mid.y - lastMid.y) / newK;
344-
setView({
345-
x: startView.x + dx,
346-
y: startView.y + dy,
347-
k: newK,
348-
});
337+
if (lastDist === 0) {
338+
lastDist = dist;
339+
return;
340+
}
341+
const mid = getTouchMid(e.touches[0], e.touches[1]); // container-relative
342+
const { x, y, k } = viewRef.current;
343+
const scaleDelta = dist / lastDist;
344+
const unclampedK = k * scaleDelta;
345+
const newK = Math.max(0.3, Math.min(3.0, unclampedK));
346+
// Keep the world point under the current midpoint stationary while scaling
347+
const worldX = (mid.x - x) / k;
348+
const worldY = (mid.y - y) / k;
349+
const newX = mid.x - worldX * newK;
350+
const newY = mid.y - worldY * newK;
351+
setView({ x: newX, y: newY, k: newK });
352+
lastDist = dist;
349353
} else if (panActive && e.touches.length === 1) {
350354
const dx = e.touches[0].clientX - lastX;
351355
const dy = e.touches[0].clientY - lastY;

0 commit comments

Comments
 (0)