zoom at cursor position
Hunter
Monday, October 20th, 2025 at 12:15 AM
297
298 // Detect pinch zoom (ctrlKey is set for pinch gestures on macOS trackpad)
299 if (e.ctrlKey) {
- // Zoom under cursor
300 + // Zoom at cursor position
301 const rect = container.getBoundingClientRect();
- const mouseX = e.clientX - rect.left;
- const mouseY = e.clientY - rect.top;
-
- // Calculate mouse position relative to container center
- const centerX = rect.width / 2;
- const centerY = rect.height / 2;
- const offsetX = mouseX - centerX;
- const offsetY = mouseY - centerY;
302 + const cursorX = e.clientX - rect.left - rect.width / 2;
303 + const cursorY = e.clientY - rect.top - rect.height / 2;
304
305 const oldUserScale = imageData.userScale;
306 + const oldTotalScale = imageData.baseScale * oldUserScale;
307 const zoomDelta = -e.deltaY * 0.01;
308 const newUserScale = Math.max(1, Math.min(5, oldUserScale * (1 + zoomDelta)));
309 + const newTotalScale = imageData.baseScale * newUserScale;
310
- // Adjust pan to keep point under cursor stationary
- const scaleFactor = newUserScale / oldUserScale - 1;
- imageData.panX -= offsetX * scaleFactor;
- imageData.panY -= offsetY * scaleFactor;
311 + // Adjust pan to keep the point under cursor fixed during zoom
312 + const scaleRatio = newTotalScale / oldTotalScale;
313 + imageData.panX = cursorX * (1 - scaleRatio) + imageData.panX * scaleRatio;
314 + imageData.panY = cursorY * (1 - scaleRatio) + imageData.panY * scaleRatio;
315 imageData.userScale = newUserScale;
316
317 // Clamp after zooming to prevent whitespace