feat(image-zoom): implement multi-touch pinch detection for zoom functionality

- Added support for pinch gestures to enhance the zoom experience on touch devices.
- Implemented event listeners for pointer events to manage pinch start and end.
- Updated closing behavior to account for active pinch gestures, improving user interaction.
This commit is contained in:
Xin
2025-09-11 20:52:59 +01:00
parent ba0934b2e1
commit 6e33f17cba

View File

@@ -23,12 +23,42 @@
overlay.appendChild(img);
// Track pinch gesture
let pinching = false;
let pinchTimer = 0;
const activeTouchPointers = new Set();
function pinchingStart() {
pinching = true;
if (pinchTimer) clearTimeout(pinchTimer);
}
function pinchingEndSoon() {
if (pinchTimer) clearTimeout(pinchTimer);
pinchTimer = setTimeout(() => (pinching = false), 350);
}
function onPointerDown(e) {
if (e.pointerType === 'touch') {
activeTouchPointers.add(e.pointerId);
if (activeTouchPointers.size > 1) pinchingStart();
}
}
function onPointerUp(e) {
if (e.pointerType === 'touch') {
activeTouchPointers.delete(e.pointerId);
if (activeTouchPointers.size < 2) pinchingEndSoon();
}
}
function close(immediate = false) {
// trigger dedicated closing transitions for smoother zoom-out
overlay.classList.add("closing");
window.removeEventListener("keydown", onKeyDown, true);
window.removeEventListener("scroll", onScroll, true);
overlay.removeEventListener("wheel", onWheel);
overlay.removeEventListener("pointerdown", onPointerDown);
overlay.removeEventListener("pointerup", onPointerUp);
overlay.removeEventListener("pointercancel", onPointerUp);
activeTouchPointers.clear();
if (pinchTimer) clearTimeout(pinchTimer);
if (immediate) {
overlay.remove();
@@ -44,10 +74,21 @@
overlay.addEventListener("click", () => close(false), { once: true });
window.addEventListener("keydown", onKeyDown, true);
function onWheel(e) { if (e && e.ctrlKey) return; close(true); }
function onScroll() { close(true); }
function onWheel(e) {
// Ignore trackpad pinch (wheel + ctrlKey) and active pinch
if ((e && e.ctrlKey) || pinching) return;
close(true);
}
function onScroll() {
if (pinching) return;
close(true);
}
overlay.addEventListener("wheel", onWheel, { passive: true });
// Standard W3C pointer events for multi-touch pinch detection
overlay.addEventListener("pointerdown", onPointerDown);
overlay.addEventListener("pointerup", onPointerUp);
overlay.addEventListener("pointercancel", onPointerUp);
window.addEventListener("scroll", onScroll, true);
document.body.appendChild(overlay);