art: verify pointerId in dragMove + clear activePointer on every exit (Codex final)

dragMove now ignores events from any pointer other than the one that started the drag
(if !dragging || e.pointerId !== activePointer), dragStart ignores a second pointer
mid-drag, and activePointer is reset in enterZoom/fit/Escape (the close effect already
did). Prevents a second/hybrid-device pointer from hijacking an active drag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-30 17:00:12 -04:00
parent c42f29537b
commit e64c5ced3c
+5 -5
View File
@@ -38,8 +38,8 @@
let zoomBoxEl, zoomImgEl; // refs for clamping pan to the image bounds
let lastX = 0, lastY = 0, activePointer = null;
function enterZoom() { zoomLevel = 1.5; tx = 0; ty = 0; dragging = false; zoomed = true; }
function fit() { dragging = false; zoomed = false; } // back to the framed gallery view
function enterZoom() { zoomLevel = 1.5; tx = 0; ty = 0; dragging = false; activePointer = null; zoomed = true; }
function fit() { dragging = false; activePointer = null; zoomed = false; } // back to the framed gallery view
function clampPan() {
if (!zoomImgEl || !zoomBoxEl) return;
const maxX = Math.max(0, (zoomImgEl.offsetWidth * zoomLevel - zoomBoxEl.clientWidth) / 2);
@@ -55,12 +55,12 @@
clampPan();
}
function dragStart(e) {
if (e.button !== 0) return; // primary button only
if (dragging || e.button !== 0) return; // primary button only; ignore a 2nd pointer mid-drag
dragging = true; lastX = e.clientX; lastY = e.clientY; activePointer = e.pointerId;
e.currentTarget.setPointerCapture?.(e.pointerId);
}
function dragMove(e) {
if (!dragging) return;
if (!dragging || e.pointerId !== activePointer) return; // only the pointer that started the drag
tx += e.clientX - lastX; ty += e.clientY - lastY;
lastX = e.clientX; lastY = e.clientY;
clampPan();
@@ -76,7 +76,7 @@
function onKey(e) {
if (e.key !== 'Escape') return;
if (zoomed) { zoomed = false; dragging = false; } // Escape steps out of inspection first, then closes
if (zoomed) { zoomed = false; dragging = false; activePointer = null; } // Escape steps out of inspection first, then closes
else if (zoom) zoom = false;
}
// Leaving the lightbox always resets the inspector, so re-opening starts framed.