resize image boundary to match aspect ratio to reduce jank

This commit is contained in:
Benjamin Wiegand 2024-09-08 13:40:36 -07:00
parent ca036ad6ed
commit bd1e958207
4 changed files with 46 additions and 12 deletions

View File

@ -6,6 +6,7 @@ for (const image of images) {
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;
@ -17,6 +18,24 @@ for (const image of images) {
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;});
@ -41,12 +60,13 @@ for (const image of images) {
});
// unzoom on close
close.addEventListener('click', () => {
zoom.checked = false;
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,
@ -57,11 +77,24 @@ for (const image of images) {
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;
if (e.key == 'Escape') {
open.checked = false;
zoom.checked = false;
}
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -247,7 +247,7 @@
</div>
</div>
<div class="project-image">
<label for="scsc" class="thumbnail">
<label for="scsc" class="thumbnail no-crop">
<img src="/img/security-camera-screenshot-thumb.webp" alt="screenshot of the app while it's recording video">
</label>
<input type="checkbox" id="scsc">

View File

@ -197,21 +197,24 @@ h3 {
vertical-align: middle;
overflow: hidden;
margin: 3px;
cursor: pointer;
}
.thumbnail img {
.double-screenshot .thumbnail img {
min-width: 450px;
min-height: 253.125px;
}
.double-screenshot .no-crop img {
min-width: auto;
max-width: 450px;
min-height: auto;
max-height: 253.125px;
}
.project-image input {
display: none;
}
.project-image img {
cursor: pointer;
}
.modal {
display: none;
}
@ -231,8 +234,6 @@ input:checked + .modal {
}
.lazy-image {
width: 500px;
height: 500px;
min-width: 90vw;
min-height: 90vh;
background-size: contain;