102 lines
3.2 KiB
JavaScript
102 lines
3.2 KiB
JavaScript
const images = document.getElementsByClassName('project-image');
|
|
|
|
for (const image of images) {
|
|
const modal = image.querySelector('.modal')
|
|
const close = image.querySelector('.close')
|
|
const lazy_image = image.querySelector('.lazy-image')
|
|
const zoom = modal.querySelector('input')
|
|
const open = image.querySelector('input');
|
|
const thumbnail = image.querySelector('img');
|
|
|
|
// 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;
|
|
|
|
// for aspect
|
|
function fixAspectRatio() {
|
|
let img_aspect = thumbnail.clientWidth / thumbnail.clientHeight
|
|
let window_aspect = window.innerWidth / window.innerHeight;
|
|
let base = zoom.checked ? 200 : 90;
|
|
|
|
if (img_aspect > window_aspect) {
|
|
// img wider than window
|
|
lazy_image.style['min-width'] = base + 'vw';
|
|
lazy_image.style['min-height'] = (base * thumbnail.clientHeight / thumbnail.clientWidth) + 'vw';
|
|
} else {
|
|
// window wider than img
|
|
lazy_image.style['min-width'] = (base * img_aspect) + 'vh';
|
|
lazy_image.style['min-height'] = base + 'vh';
|
|
}
|
|
}
|
|
thumbnail.addEventListener('load', fixAspectRatio);
|
|
|
|
// 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 => {
|
|
fixAspectRatio();
|
|
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;
|
|
}
|
|
});
|
|
|
|
// resize image plane to match image aspect ratio
|
|
open.addEventListener('change', e => {
|
|
if (open.checked) {
|
|
fixAspectRatio();
|
|
window.addEventListener('resize', fixAspectRatio);
|
|
} else {
|
|
window.removeEventListener('resize', fixAspectRatio);
|
|
}
|
|
});
|
|
|
|
// close image on escape key
|
|
document.addEventListener('keydown', e => {
|
|
if (e.key == 'Escape') {
|
|
open.checked = false;
|
|
zoom.checked = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
|