resize image boundary to match aspect ratio to reduce jank
This commit is contained in:
parent
ca036ad6ed
commit
bd1e958207
@ -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 |
@ -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">
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user