comfycamp/src/components/ImageViewer.astro

103 lines
2.8 KiB
Plaintext

---
// A component that allows you to open images in full screen.
// All you need to do is place it anywhere on the page.
---
<div id="fullscreenGallery" style="opacity: 0;">
<img id="fullscreenImage" />
<div id="fullscreenAlt"></div>
</div>
<style>
#fullscreenGallery {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
display: flex;
background-color: #0008;
backdrop-filter: blur(42px);
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1em;
pointer-events: none;
transition: opacity 0.1s ease-in-out;
}
#fullscreenImage {
width: 100%;
max-width: 1200px;
max-height: calc(100% - 22px - 3em);
display: block;
object-fit: contain;
}
#fullscreenAlt {
font-style: italic;
text-shadow: 0 0 4px rgba(0,0,0,.5);
height: 22px;
}
</style>
<script>
window.addEventListener("load", () => {
const fsContainer = document.getElementById("fullscreenGallery")
if (!fsContainer) return
const fsImg = document.getElementById("fullscreenImage") as HTMLImageElement
if (!fsImg) return
const fsAlt = document.getElementById("fullscreenAlt")
if (!fsAlt) return
fsContainer.addEventListener("click", () => {
fsContainer.style.opacity = "0"
fsContainer.style.pointerEvents = "none"
})
const isOpen = () => fsContainer.style.opacity !== "0"
const images = (Array.from(document.querySelectorAll("main img")) as HTMLImageElement[])
.filter(i => !i.src.endsWith("svg") && i.id != "fullscreenImage")
for (const img of images) {
img.addEventListener("click", () => {
if (!isOpen()) {
fsContainer.style.opacity = "1"
fsContainer.style.pointerEvents = "auto"
fsImg.src = img.src
fsAlt.innerHTML = img.alt
} else {
fsContainer.style.opacity = "0"
fsContainer.style.pointerEvents = "none"
}
})
}
let index = 0
document.addEventListener("keydown", function(event) {
if (!isOpen()) return
switch (event.key) {
case "Escape":
fsContainer.style.opacity = "0"
fsContainer.style.pointerEvents = "none"
break
case "ArrowLeft":
index = images.findIndex(el => el.src === fsImg.src)
index = index > 0 ? index - 1 : images.length - 1
fsImg.src = images[index]?.src || "???"
fsAlt.innerHTML = images[index]?.alt || "???"
break
case "ArrowRight":
index = images.findIndex(el => el.src === fsImg.src)
index = index < images.length - 1 ? index + 1 : 0
fsImg.src = images[index]?.src || "???"
fsAlt.innerHTML = images[index]?.alt || "???"
break
}
})
})
</script>