ben.wiegand.pw/www/image-modal.js
2024-12-23 16:29:22 -08:00

71 lines
2.0 KiB
JavaScript

const images = document.getElementsByClassName('project-image');
for (const image of images) {
const modal = image.querySelector('.modal')
const lazy_image = image.querySelector('.lazy-image')
const zoom = modal.querySelector('input')
const open = image.querySelector('input');
// for pan
let grabbed = false;
let startX = 0;
let startY = 0;
// for zoom
let clickX = 0;
let clickY = 0;
let initW = lazy_image.clientWidth;
let initH = lazy_image.clientHeight;
// pan the image
lazy_image.addEventListener('mouseleave', () => {grabbed = false;});
lazy_image.addEventListener('mouseup', () => {
grabbed = false;
});
lazy_image.addEventListener('mousedown', e => {
grabbed = true;
startX = modal.scrollLeft + e.pageX;
startY = modal.scrollTop + e.pageY;
// set stuff for zoom
clickX = e.clientX - lazy_image.offsetLeft;
clickY = e.clientY - lazy_image.offsetTop;
initW = lazy_image.clientWidth;
initH = lazy_image.clientHeight;
});
lazy_image.addEventListener('mousemove', e => {
if(!grabbed) return;
modal.scrollLeft = startX - e.pageX;
modal.scrollTop = startY - e.pageY;
});
// unzoom on close
open.addEventListener('change', () => {
if (!open.checked) zoom.checked = false;
});
// zoom to click target
zoom.addEventListener('change', e => {
if (zoom.checked) {
zoom_factor = Math.max(
lazy_image.clientWidth / initW,
lazy_image.clientHeight / initH
);
x = clickX * zoom_factor - (window.innerWidth / 2);
y = clickY * zoom_factor - (window.innerHeight / 2);
modal.scrollLeft = x;
modal.scrollTop = y;
}
});
// close image on escape key
document.addEventListener('keydown', e => {
if (e.key == 'Escape') {
open.checked = false;
zoom.checked = false;
}
});
}