Fix lightbox zooming

This commit is contained in:
2026-05-05 20:54:04 +02:00
parent 5e690e5576
commit 07a5c3baf9

View File

@@ -468,26 +468,24 @@ export default class Lightbox {
event.preventDefault();
const rect = this.image.getBoundingClientRect();
const oldZoom = parseFloat(this.image.style.getPropertyValue('--scale') || '1');
const oldTranslateX = parseFloat(this.image.style.getPropertyValue('--translate-x') || '0');
const oldTranslateY = parseFloat(this.image.style.getPropertyValue('--translate-y') || '0');
const oldTransform = this.getImageTransform();
const oldZoom = oldTransform.scale;
const maxZoom = Math.max(media.width / Math.max(this.image.width, 1), media.height / Math.max(this.image.height, 1), 1);
const newZoom = Math.min(Math.max(oldZoom + (-Math.sign(event.deltaY) / 10), 1), maxZoom);
const offsetX = event.clientX - rect.left;
const offsetY = event.clientY - rect.top;
let translateX = oldTranslateX + (newZoom - oldZoom) * ((this.image.width / 2) - offsetX);
let translateY = oldTranslateY + (newZoom - oldZoom) * ((this.image.height / 2) - offsetY);
const maxTranslateX = (newZoom - 1) * this.image.width / 2;
const maxTranslateY = (newZoom - 1) * this.image.height / 2;
translateX = Math.max(Math.min(translateX, maxTranslateX), -maxTranslateX);
translateY = Math.max(Math.min(translateY, maxTranslateY), -maxTranslateY);
const imageCenterX = rect.left + rect.width / 2 - oldTransform.translateX;
const imageCenterY = rect.top + rect.height / 2 - oldTransform.translateY;
const cursorX = event.clientX - imageCenterX;
const cursorY = event.clientY - imageCenterY;
const zoomRatio = newZoom / oldZoom;
const transform = this.clampImageTransform({
scale: newZoom,
translateX: cursorX - zoomRatio * (cursorX - oldTransform.translateX),
translateY: cursorY - zoomRatio * (cursorY - oldTransform.translateY)
});
this.container.classList.toggle('moveable', newZoom > 1);
this.image.style.setProperty('--scale', String(newZoom));
this.image.style.setProperty('--translate-x', `${translateX}px`);
this.image.style.setProperty('--translate-y', `${translateY}px`);
this.setImageTransform(transform);
}
onDragStart(event) {
@@ -502,16 +500,13 @@ export default class Lightbox {
onDragMove(event) {
const zoom = parseFloat(this.image.style.getPropertyValue('--scale') || '1');
let translateX = event.clientX - this.gMouseDownOffsetX;
let translateY = event.clientY - this.gMouseDownOffsetY;
const maxTranslateX = (zoom - 1) * this.image.width / 2;
const maxTranslateY = (zoom - 1) * this.image.height / 2;
const transform = this.clampImageTransform({
scale: zoom,
translateX: event.clientX - this.gMouseDownOffsetX,
translateY: event.clientY - this.gMouseDownOffsetY
});
translateX = Math.max(Math.min(translateX, maxTranslateX), -maxTranslateX);
translateY = Math.max(Math.min(translateY, maxTranslateY), -maxTranslateY);
this.image.style.setProperty('--translate-x', `${translateX}px`);
this.image.style.setProperty('--translate-y', `${translateY}px`);
this.setImageTransform(transform);
}
onDragEnd() {
@@ -520,9 +515,32 @@ export default class Lightbox {
}
resetImageTransform() {
this.image.style.setProperty('--scale', '1');
this.image.style.setProperty('--translate-x', '0px');
this.image.style.setProperty('--translate-y', '0px');
this.setImageTransform({scale: 1, translateX: 0, translateY: 0});
}
getImageTransform() {
return {
scale: parseFloat(this.image.style.getPropertyValue('--scale') || '1'),
translateX: parseFloat(this.image.style.getPropertyValue('--translate-x') || '0'),
translateY: parseFloat(this.image.style.getPropertyValue('--translate-y') || '0')
};
}
clampImageTransform(transform) {
const maxTranslateX = (transform.scale - 1) * this.image.width / 2;
const maxTranslateY = (transform.scale - 1) * this.image.height / 2;
return {
scale: transform.scale,
translateX: Math.max(Math.min(transform.translateX, maxTranslateX), -maxTranslateX),
translateY: Math.max(Math.min(transform.translateY, maxTranslateY), -maxTranslateY)
};
}
setImageTransform(transform) {
this.image.style.setProperty('--scale', String(transform.scale));
this.image.style.setProperty('--translate-x', `${transform.translateX}px`);
this.image.style.setProperty('--translate-y', `${transform.translateY}px`);
}
hideElements(elements) {
@@ -573,4 +591,4 @@ export default class Lightbox {
if (this.options.disableScrolling) document.body.classList.remove('lb-disable-scrolling');
this.options.onClosing();
}
}
}