feat: add lightbox for viewing forest and reward images fullscreen

- Click any forest element or reward image to see it large
- Smooth zoom-in animation, click anywhere to close
- Hover effect on clickable images
- Works on both forest grid and reward screen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 20:50:20 +02:00
co-authored by Claude Opus 4.6
parent f9ae7c45eb
commit fabf9211c4
3 changed files with 72 additions and 0 deletions
+5
View File
@@ -195,6 +195,11 @@
<span class="mute-btn__icon" id="mute-icon">&#x1F50A;</span>
</button>
<!-- Lightbox for forest element images -->
<div id="image-lightbox" class="lightbox" style="display:none">
<img id="lightbox-img" class="lightbox__img" src="" alt="">
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+23
View File
@@ -64,4 +64,27 @@ document.addEventListener("DOMContentLoaded", async () => {
};
document.addEventListener("click", initAudioOnce);
document.addEventListener("keydown", initAudioOnce);
// Lightbox: click on forest/reward images to view fullscreen
const lightbox = document.getElementById("image-lightbox")!;
const lightboxImg = document.getElementById("lightbox-img") as HTMLImageElement;
document.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
// Open lightbox when clicking forest element or reward image
if (
(target.tagName === "IMG" && target.closest(".forest__element")) ||
(target.tagName === "IMG" && target.closest(".reward__image-area"))
) {
lightboxImg.src = (target as HTMLImageElement).src;
lightboxImg.alt = (target as HTMLImageElement).alt;
lightbox.style.display = "flex";
}
});
// Close lightbox on click
lightbox.addEventListener("click", () => {
lightbox.style.display = "none";
lightboxImg.src = "";
});
});
+44
View File
@@ -484,9 +484,15 @@ h3 {
max-height: 100%;
object-fit: cover;
border-radius: 50%;
cursor: pointer;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
mask-image: radial-gradient(ellipse 70% 70% at center, black 50%, transparent 100%);
-webkit-mask-image: radial-gradient(ellipse 70% 70% at center, black 50%, transparent 100%);
transition: transform 0.2s ease;
}
.forest__element img:hover {
transform: scale(1.1);
}
.forest__element--new {
@@ -542,7 +548,13 @@ h3 {
max-width: 100%;
max-height: 100%;
object-fit: contain;
cursor: pointer;
animation: reward-image-appear 0.8s ease-out;
transition: transform 0.2s ease;
}
.reward__image-area img:hover {
transform: scale(1.05);
}
@keyframes reward-image-appear {
@@ -995,6 +1007,38 @@ h3 {
opacity: 0.6;
}
/* Lightbox for viewing forest images fullscreen */
.lightbox {
position: fixed;
inset: 0;
background: rgba(61, 50, 37, 0.85);
z-index: 500;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
animation: lightbox-fade-in 0.3s ease;
}
.lightbox__img {
max-width: 90vw;
max-height: 85vh;
object-fit: contain;
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
animation: lightbox-zoom-in 0.3s ease;
}
@keyframes lightbox-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes lightbox-zoom-in {
from { transform: scale(0.7); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
/* Error overlay — kindgerechte Fehlermeldung */
.error-overlay {
position: fixed;