Compare commits
4 Commits
09134e8c36
...
5254596ce5
Author | SHA1 | Date | |
---|---|---|---|
|
5254596ce5 | ||
|
bd1e958207 | ||
|
ca036ad6ed | ||
|
dc5acea909 |
@ -5,6 +5,8 @@ for (const image of images) {
|
|||||||
const close = image.querySelector('.close')
|
const close = image.querySelector('.close')
|
||||||
const lazy_image = image.querySelector('.lazy-image')
|
const lazy_image = image.querySelector('.lazy-image')
|
||||||
const zoom = modal.querySelector('input')
|
const zoom = modal.querySelector('input')
|
||||||
|
const open = image.querySelector('input');
|
||||||
|
const thumbnail = image.querySelector('img');
|
||||||
|
|
||||||
// for pan
|
// for pan
|
||||||
let grabbed = false;
|
let grabbed = false;
|
||||||
@ -17,12 +19,30 @@ for (const image of images) {
|
|||||||
let initW = lazy_image.clientWidth;
|
let initW = lazy_image.clientWidth;
|
||||||
let initH = lazy_image.clientHeight;
|
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
|
// pan the image
|
||||||
lazy_image.addEventListener('mouseleave', () => {grabbed = false;});
|
lazy_image.addEventListener('mouseleave', () => {grabbed = false;});
|
||||||
lazy_image.addEventListener('mouseup', () => {
|
lazy_image.addEventListener('mouseup', () => {
|
||||||
grabbed = false;
|
grabbed = false;
|
||||||
});
|
});
|
||||||
lazy_image.addEventListener('mousedown', (e) => {
|
lazy_image.addEventListener('mousedown', e => {
|
||||||
grabbed = true;
|
grabbed = true;
|
||||||
startX = modal.scrollLeft + e.pageX;
|
startX = modal.scrollLeft + e.pageX;
|
||||||
startY = modal.scrollTop + e.pageY;
|
startY = modal.scrollTop + e.pageY;
|
||||||
@ -33,30 +53,49 @@ for (const image of images) {
|
|||||||
initW = lazy_image.clientWidth;
|
initW = lazy_image.clientWidth;
|
||||||
initH = lazy_image.clientHeight;
|
initH = lazy_image.clientHeight;
|
||||||
});
|
});
|
||||||
lazy_image.addEventListener('mousemove', (e) => {
|
lazy_image.addEventListener('mousemove', e => {
|
||||||
if(!grabbed) return;
|
if(!grabbed) return;
|
||||||
modal.scrollLeft = startX - e.pageX;
|
modal.scrollLeft = startX - e.pageX;
|
||||||
modal.scrollTop = startY - e.pageY;
|
modal.scrollTop = startY - e.pageY;
|
||||||
});
|
});
|
||||||
|
|
||||||
// unzoom on close
|
// unzoom on close
|
||||||
close.addEventListener('click', () => {
|
open.addEventListener('change', () => {
|
||||||
zoom.checked = false;
|
if (!open.checked) zoom.checked = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// zoom to click target
|
// zoom to click target
|
||||||
zoom.addEventListener('change', e => {
|
zoom.addEventListener('change', e => {
|
||||||
|
fixAspectRatio();
|
||||||
if (zoom.checked) {
|
if (zoom.checked) {
|
||||||
zoom_factor = Math.max(
|
zoom_factor = Math.max(
|
||||||
lazy_image.clientWidth / initW,
|
lazy_image.clientWidth / initW,
|
||||||
lazy_image.clientHeight / initH
|
lazy_image.clientHeight / initH
|
||||||
);
|
);
|
||||||
console.log(zoom_factor);
|
|
||||||
x = clickX * zoom_factor - (window.innerWidth / 2);
|
x = clickX * zoom_factor - (window.innerWidth / 2);
|
||||||
y = clickY * zoom_factor - (window.innerHeight / 2);
|
y = clickY * zoom_factor - (window.innerHeight / 2);
|
||||||
console.log('zoom 2 ' + x + ', ' + y);
|
|
||||||
modal.scrollLeft = x;
|
modal.scrollLeft = x;
|
||||||
modal.scrollTop = y;
|
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 |
@ -67,9 +67,13 @@
|
|||||||
</details>
|
</details>
|
||||||
<div class="double-screenshot">
|
<div class="double-screenshot">
|
||||||
<div class="project-image">
|
<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">
|
<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>
|
<label>
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
<div class="lazy-image" style="background-image: url('/img/peercord-login.png')"></div>
|
<div class="lazy-image" style="background-image: url('/img/peercord-login.png')"></div>
|
||||||
@ -77,7 +81,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<div class="project-image">
|
||||||
<label for="lpcc">
|
<label for="lpcc" class="thumbnail">
|
||||||
<img src="/img/peercord-chat-thumb.webp" alt="PeerCord login screen">
|
<img src="/img/peercord-chat-thumb.webp" alt="PeerCord login screen">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="lpcc">
|
<input type="checkbox" id="lpcc">
|
||||||
@ -111,7 +115,7 @@
|
|||||||
</details>
|
</details>
|
||||||
<div class="double-screenshot">
|
<div class="double-screenshot">
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/ilo-overview-thumb.webp" alt="overview of my ILO dashboard in grafana">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="lio">
|
<input type="checkbox" id="lio">
|
||||||
@ -125,7 +129,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/ilo-temperatures-thumb.webp" alt="temperature sensor data shown in my ILO dashboard in grafana">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="lit">
|
<input type="checkbox" id="lit">
|
||||||
@ -139,7 +143,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/ilo-drives-thumb.webp" alt="drive health, status, and temperature shown in my ILO dashboard in grafana">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="lid">
|
<input type="checkbox" id="lid">
|
||||||
@ -153,7 +157,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<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>
|
</label>
|
||||||
<input type="checkbox" id="lifci">
|
<input type="checkbox" id="lifci">
|
||||||
@ -187,7 +191,7 @@
|
|||||||
</details>
|
</details>
|
||||||
<div class="double-screenshot">
|
<div class="double-screenshot">
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/smbus-mitm-arduino-thumb.webp" alt="the arduino leonardo that's attached to my battery, complete with small OLED display">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="sma">
|
<input type="checkbox" id="sma">
|
||||||
@ -201,7 +205,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/smbus-mitm-wiring-thumb.webp" alt="wiring to intercept communications between the BMS and the laptop">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="smw">
|
<input type="checkbox" id="smw">
|
||||||
@ -229,7 +233,7 @@
|
|||||||
</details>
|
</details>
|
||||||
<div class="double-screenshot">
|
<div class="double-screenshot">
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/security-camera-stream-thumb.webp" alt="two phones, one streaming video to another over the network">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="scst">
|
<input type="checkbox" id="scst">
|
||||||
@ -243,7 +247,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/security-camera-screenshot-thumb.webp" alt="screenshot of the app while it's recording video">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="scsc">
|
<input type="checkbox" id="scsc">
|
||||||
@ -272,7 +276,7 @@
|
|||||||
<div class="double-screenshot">
|
<div class="double-screenshot">
|
||||||
|
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/roomba-thumb.webp" alt="a normal Roomba with a webcam, Raspberry pi, Arduino, and a voltage regulator mounted on it">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="r">
|
<input type="checkbox" id="r">
|
||||||
@ -286,7 +290,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-image">
|
<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">
|
<img src="/img/roomba-control-thumb.webp" alt="webpage for controlling the Roomba and viewing the live feed">
|
||||||
</label>
|
</label>
|
||||||
<input type="checkbox" id="rc">
|
<input type="checkbox" id="rc">
|
||||||
|
@ -187,20 +187,37 @@ h3 {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.double-screenshot img {
|
.double-screenshot .thumbnail {
|
||||||
width: 450px;
|
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%;
|
max-width: 100%;
|
||||||
vertical-align: middle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-image input {
|
.project-image input {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-image img {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -220,8 +237,6 @@ input:checked + .modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lazy-image {
|
.lazy-image {
|
||||||
width: 500px;
|
|
||||||
height: 500px;
|
|
||||||
min-width: 90vw;
|
min-width: 90vw;
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
|
Loading…
Reference in New Issue
Block a user