phobos/src/components/Lightbox.astro
2024-06-30 21:16:36 +02:00

110 lines
2.5 KiB
Text

<figure class="place-content-center app-lightbox">
<img class="portal" />
<figcaption class="desc rounded font-bold"></figcaption>
</figure>
<script>
// @ts-nocheck
const lbTriggers = document.querySelectorAll('[data-lightbox="true"]');
const lightbox = document.querySelector(".app-lightbox");
let portal = lightbox.querySelector(".portal");
let desc = lightbox.querySelector(".desc");
// eslint-disable-next-line no-restricted-syntax
for (const trig of lbTriggers) {
trig.addEventListener("click", () => {
const T = trig.getElementsByTagName("img")[0];
portal.src = T.src;
// console.log();
if (!T.alt) desc.classList.add('hidden');
else desc.classList.remove('hidden')
desc.innerHTML = T.alt;
setTimeout(() => {
// Adapt size attribute dynamically
const img = portal;
const ratio = img.naturalWidth / img.naturalHeight;
img.sizes = `${window.innerHeight * ratio}px`;
}, 352);
lightbox.classList.add("is-active");
document.documentElement.classList.add("scrollIsLocked");
});
}
lightbox.addEventListener("click", () => {
// console.log('cli');
lightbox.classList.remove("is-active");
document.documentElement.classList.remove("scrollIsLocked");
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
// console.log(e);
lightbox.classList.remove("is-active");
document.documentElement.classList.remove("scrollIsLocked");
}
});
</script>
<style lang="scss">
.app-lightbox {
position: fixed;
margin: auto auto;
align-items: center;
justify-content: center;
z-index: 2;
width: 100%;
height: 100%;
pointer-events: none;
cursor: zoom-out;
// TODO: map color to API
background-color: var(--bg-color, hsl(0, 0%, 0%, 0.85));
opacity: 0;
transition: opacity 0.35s;
&.is-active {
pointer-events: initial;
opacity: 1;
}
}
:global([data-lightbox]) {
cursor: zoom-in;
}
.portal {
display: flex;
margin: auto auto;
padding: 2rem;
max-width: 90%;
max-height: 90%;
// TODO: map speed to API
transition:
opacity 0.35s,
transform 0.35s;
transform: scale(0.2);
:global(img) {
width: 100%;
height: 100%;
object-fit: contain;
}
.is-active & {
transform: scale(1);
}
}
.desc {
background-color: white;
max-width: 20%;
margin: auto auto;
padding: 1rem;
}
</style>