Compare commits

...

4 Commits

Author SHA1 Message Date
Benjamin Wiegand
5254596ce5 fix images not shrinking on mobile 2024-09-08 14:19:05 -07:00
Benjamin Wiegand
bd1e958207 resize image boundary to match aspect ratio to reduce jank 2024-09-08 13:40:36 -07:00
Benjamin Wiegand
ca036ad6ed close image viewer on escape key 2024-09-08 12:45:17 -07:00
Benjamin Wiegand
dc5acea909 reduce cls by fitting thumbnails to 16x9 2024-09-08 12:31:27 -07:00
5 changed files with 89 additions and 31 deletions

View File

@ -5,6 +5,8 @@ for (const image of images) {
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;
@ -16,47 +18,84 @@ 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;});
lazy_image.addEventListener('mouseup', () => {
grabbed = false;
});
lazy_image.addEventListener('mousedown', (e) => {
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) => {
lazy_image.addEventListener('mousemove', e => {
if(!grabbed) return;
modal.scrollLeft = startX - e.pageX;
modal.scrollTop = startY - e.pageY;
});
// 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,
lazy_image.clientHeight / initH
);
console.log(zoom_factor);
x = clickX * zoom_factor - (window.innerWidth / 2);
y = clickY * zoom_factor - (window.innerHeight / 2);
console.log('zoom 2 ' + x + ', ' + y);
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;
}
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -67,9 +67,13 @@
</details>
<div class="double-screenshot">
<div class="project-image">
<label for="lpcl"><img src="/img/peercord-login-thumb.webp" alt="PeerCord login screen"></label>
<label for="lpcl" class="thumbnail">
<img src="/img/peercord-login-thumb.webp" alt="PeerCord login screen">
</label>
<input type="checkbox" id="lpcl">
<div class="modal"><label for="lpcl" class="modal-bg"></label><label for="lpcl" class="close"></label>
<div class="modal">
<label for="lpcl" class="modal-bg"></label>
<label for="lpcl" class="close"></label>
<label>
<input type="checkbox">
<div class="lazy-image" style="background-image: url('/img/peercord-login.png')"></div>
@ -77,7 +81,7 @@
</div>
</div>
<div class="project-image">
<label for="lpcc">
<label for="lpcc" class="thumbnail">
<img src="/img/peercord-chat-thumb.webp" alt="PeerCord login screen">
</label>
<input type="checkbox" id="lpcc">
@ -111,7 +115,7 @@
</details>
<div class="double-screenshot">
<div class="project-image">
<label for="lio">
<label for="lio" class="thumbnail">
<img src="/img/ilo-overview-thumb.webp" alt="overview of my ILO dashboard in grafana">
</label>
<input type="checkbox" id="lio">
@ -125,7 +129,7 @@
</div>
</div>
<div class="project-image">
<label for="lit">
<label for="lit" class="thumbnail">
<img src="/img/ilo-temperatures-thumb.webp" alt="temperature sensor data shown in my ILO dashboard in grafana">
</label>
<input type="checkbox" id="lit">
@ -139,7 +143,7 @@
</div>
</div>
<div class="project-image">
<label for="lid">
<label for="lid" class="thumbnail">
<img src="/img/ilo-drives-thumb.webp" alt="drive health, status, and temperature shown in my ILO dashboard in grafana">
</label>
<input type="checkbox" id="lid">
@ -153,7 +157,7 @@
</div>
</div>
<div class="project-image">
<label for="lifci">
<label for="lifci" class="thumbnail">
<img src="/img/ilo-fan-and-cpu-info-thumb.webp" alt="fan speed, fan health, fan status, and cpu status shown in my ILO dashboard in grafana">
</label>
<input type="checkbox" id="lifci">
@ -187,7 +191,7 @@
</details>
<div class="double-screenshot">
<div class="project-image">
<label for="sma">
<label for="sma" class="thumbnail">
<img src="/img/smbus-mitm-arduino-thumb.webp" alt="the arduino leonardo that's attached to my battery, complete with small OLED display">
</label>
<input type="checkbox" id="sma">
@ -201,7 +205,7 @@
</div>
</div>
<div class="project-image">
<label for="smw">
<label for="smw" class="thumbnail">
<img src="/img/smbus-mitm-wiring-thumb.webp" alt="wiring to intercept communications between the BMS and the laptop">
</label>
<input type="checkbox" id="smw">
@ -229,7 +233,7 @@
</details>
<div class="double-screenshot">
<div class="project-image">
<label for="scst">
<label for="scst" class="thumbnail">
<img src="/img/security-camera-stream-thumb.webp" alt="two phones, one streaming video to another over the network">
</label>
<input type="checkbox" id="scst">
@ -243,7 +247,7 @@
</div>
</div>
<div class="project-image">
<label for="scsc">
<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">
@ -272,7 +276,7 @@
<div class="double-screenshot">
<div class="project-image">
<label for="r">
<label for="r" class="thumbnail">
<img src="/img/roomba-thumb.webp" alt="a normal Roomba with a webcam, Raspberry pi, Arduino, and a voltage regulator mounted on it">
</label>
<input type="checkbox" id="r">
@ -286,7 +290,7 @@
</div>
</div>
<div class="project-image">
<label for="rc">
<label for="rc" class="thumbnail">
<img src="/img/roomba-control-thumb.webp" alt="webpage for controlling the Roomba and viewing the live feed">
</label>
<input type="checkbox" id="rc">

View File

@ -187,20 +187,37 @@ h3 {
align-items: center;
}
.double-screenshot img {
width: 450px;
.double-screenshot .thumbnail {
display: flex;
align-items: center;
justify-content: center;
width: 444px;
max-width: calc(min(450px,calc(100vw - 100px)));
max-height: 253.125px;
overflow: hidden;
margin: 3px;
cursor: pointer;
}
.double-screenshot .thumbnail img {
min-width: calc(min(450px,calc(100vw - 100px)));
min-height: calc(min(450px,calc(100vw - 100px)) * 0.5625);
}
.double-screenshot .no-crop img {
min-width: auto;
max-width: calc(min(450px,calc(100vw - 100px)));
min-height: auto;
max-height: 253.125px;
}
.project-image {
max-width: 100%;
vertical-align: middle;
}
.project-image input {
display: none;
}
.project-image img {
cursor: pointer;
}
.modal {
display: none;
}
@ -220,8 +237,6 @@ input:checked + .modal {
}
.lazy-image {
width: 500px;
height: 500px;
min-width: 90vw;
min-height: 90vh;
background-size: contain;