fix: zoom

This commit is contained in:
Tim Rijkse
2026-01-16 09:52:16 +01:00
parent 3dbe404443
commit 939a4e9c57

View File

@@ -16,6 +16,10 @@ class ImageGallery extends HTMLElement {
this.startY = 0;
this.lastTranslateX = 0;
this.lastTranslateY = 0;
// Pinch zoom state
this.initialPinchDistance = 0;
this.initialZoom = 1;
}
connectedCallback() {
@@ -90,7 +94,81 @@ class ImageGallery extends HTMLElement {
// Prevent default drag behavior
modalImage.addEventListener("dragstart", (e) => e.preventDefault());
// Mouse wheel zoom
modalImage.addEventListener("wheel", (e) => this.handleWheel(e), { passive: false });
}
// Pinch zoom for touch devices on modal content
const modalContent = this.shadowRoot.querySelector(".modal-content");
if (modalContent) {
modalContent.addEventListener("touchstart", (e) => this.handleTouchStart(e), { passive: false });
modalContent.addEventListener("touchmove", (e) => this.handleTouchMove(e), { passive: false });
modalContent.addEventListener("touchend", (e) => this.handleTouchEnd(e));
// Prevent default browser gestures on the modal
modalContent.addEventListener("gesturestart", (e) => e.preventDefault());
modalContent.addEventListener("gesturechange", (e) => e.preventDefault());
modalContent.addEventListener("gestureend", (e) => e.preventDefault());
}
}
handleWheel(e) {
e.preventDefault();
e.stopPropagation();
const delta = e.deltaY > 0 ? -0.1 : 0.1;
this.zoom(delta);
}
handleTouchStart(e) {
if (e.touches.length === 2) {
// Pinch zoom start
e.preventDefault();
this.initialPinchDistance = this.getPinchDistance(e.touches);
this.initialZoom = this.currentZoom;
} else if (e.touches.length === 1 && this.currentZoom > 1) {
// Single touch drag when zoomed
this.startDrag(e);
}
}
handleTouchMove(e) {
if (e.touches.length === 2) {
// Pinch zoom
e.preventDefault();
const currentDistance = this.getPinchDistance(e.touches);
const scale = currentDistance / this.initialPinchDistance;
const newZoom = Math.max(1, Math.min(4, this.initialZoom * scale));
this.currentZoom = newZoom;
if (this.currentZoom === 1) {
this.translateX = 0;
this.translateY = 0;
}
this.updateImageTransform();
const modalImage = this.shadowRoot.querySelector(".modal-image");
if (modalImage) {
modalImage.style.cursor = this.currentZoom > 1 ? "grab" : "default";
}
} else if (e.touches.length === 1 && this.isDragging) {
// Single touch drag
this.drag(e);
}
}
handleTouchEnd(e) {
this.initialPinchDistance = 0;
this.endDrag();
}
getPinchDistance(touches) {
const dx = touches[0].clientX - touches[1].clientX;
const dy = touches[0].clientY - touches[1].clientY;
return Math.sqrt(dx * dx + dy * dy);
}
startDrag(e) {
@@ -263,6 +341,8 @@ class ImageGallery extends HTMLElement {
background-color: rgba(0, 0, 0, 0.95);
z-index: 1000;
flex-direction: column;
touch-action: none;
-webkit-touch-callout: none;
}
.modal-overlay.open {
@@ -321,11 +401,13 @@ class ImageGallery extends HTMLElement {
.modal-content {
flex: 1;
overflow: auto;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
padding: var(--spacing-md, 1rem);
touch-action: none;
-webkit-touch-callout: none;
}
.modal-image {
@@ -336,6 +418,7 @@ class ImageGallery extends HTMLElement {
cursor: default;
user-select: none;
-webkit-user-drag: none;
touch-action: none;
}
</style>