1) { resetZoom(); $event.stopPropagation(); } else { slideshowOpen = false; }"
class="fixed inset-0 bg-black/80 flex items-start justify-center overflow-hidden"
x-transition
style="z-index: 99999; display: none;"
x-cloak
x-data="{
scale: 1,
minScale: 1,
maxScale: 5,
position: { x: 0, y: 0 },
isPanning: false,
didDrag: false,
startPanPosition: { x: 0, y: 0 },
startClient: { x: 0, y: 0 },
init() {
this.$watch('slideshowOpen', (value) => {
if (value) {
this.resetZoomState();
}
});
this.$watch('currentSlide', () => {
this.resetZoomState();
});
},
resetZoomState() {
this.scale = 1;
this.position = { x: 0, y: 0 };
this.isPanning = false;
this.didDrag = false;
},
zoomIn() {
if (this.scale < this.maxScale) {
const newScale = Math.min(this.scale + 0.5, this.maxScale);
this.scale = newScale;
}
},
zoomOut() {
if (this.scale > this.minScale) {
const newScale = Math.max(this.scale - 0.5, this.minScale);
this.scale = newScale;
if (newScale === 1) {
this.position = { x: 0, y: 0 };
}
}
},
resetZoom() {
this.scale = 1;
this.position = { x: 0, y: 0 };
},
handleWheel(event) {
event.preventDefault();
if (event.ctrlKey) {
const delta = -Math.sign(event.deltaY);
const newScale = Math.max(this.minScale, Math.min(this.scale + delta * 0.1, this.maxScale));
this.scale = newScale;
if (newScale === 1) {
this.position = { x: 0, y: 0 };
}
} else if (this.scale > 1) {
this.position.x -= event.deltaX * 0.5;
this.position.y -= event.deltaY * 0.5;
}
},
startPan(event) {
if (event.button !== 0) return;
this.didDrag = false;
this.startClient.x = event.clientX;
this.startClient.y = event.clientY;
this.startPanPosition.x = this.position.x;
this.startPanPosition.y = this.position.y;
if (this.scale > 1) {
this.isPanning = true;
event.preventDefault();
}
},
doPan(event) {
if (this.isPanning) {
const dx = event.clientX - this.startClient.x;
const dy = event.clientY - this.startClient.y;
if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
this.didDrag = true;
}
this.position.x = this.startPanPosition.x + dx;
this.position.y = this.startPanPosition.y + dy;
}
},
endPan() {
this.isPanning = false;
},
clickZoom() {
if (this.didDrag) return;
this.zoomIn();
},
navigate(direction) {
if (this.scale === 1) {
const newIndex = (currentSlide + direction + zoomImages.length) % zoomImages.length;
currentSlide = newIndex;
}
}
}"
>