phobos/src/components/Lightbox.astro
2025-08-20 12:26:19 +02:00

104 lines
2.5 KiB
Text

<figure class="place-content-center app-lightbox backdrop-blur-md">
<img class="portal" />
<figcaption class="desc rounded font-bold backdrop-blur-sm bg-black/50"></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");
let artist = lightbox.querySelector("#artist");
// eslint-disable-next-line no-restricted-syntax
for (const trig of lbTriggers) {
trig.addEventListener("click", () => {
const T = trig.getElementsByTagName("img")[0];
const url = new URL(T.src);
const noThumb = url.href.replaceAll(url.search, "");
portal.src = noThumb;
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", () => {
lightbox.classList.remove("is-active");
document.documentElement.classList.remove("scrollIsLocked");
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
lightbox.classList.remove("is-active");
document.documentElement.classList.remove("scrollIsLocked");
}
});
</script>
<style lang="scss">
.app-lightbox {
position: fixed;
margin: auto auto;
padding: 2rem;
align-items: center;
justify-content: center;
z-index: 3;
width: 100%;
height: 100%;
pointer-events: none;
cursor: zoom-out;
background-color: var(--bg-color, hsla(0, 0%, 0%, 0.623));
opacity: 0;
transition: opacity ease-in-out 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%;
transition:
opacity 0.35s,
transform 0.35s;
transform: scale(0.5);
:global(img) {
width: 100%;
height: 100%;
object-fit: contain;
}
.is-active & {
transform: scale(1);
}
}
.desc {
max-width: 50%;
margin: auto auto;
padding: 1rem;
}
</style>