zoom at cursor position

Hunter
Monday, October 20th, 2025 at 12:15 AM

script.js+9-13

script.js
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