From fabf9211c47479ac7e2499d851354b55c7f1c736 Mon Sep 17 00:00:00 2001 From: Markus Graf Date: Sun, 29 Mar 2026 20:50:20 +0200 Subject: [PATCH] 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) --- index.html | 5 +++++ src/main.ts | 23 +++++++++++++++++++++++ src/styles/main.css | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/index.html b/index.html index 8ebecce..cd76211 100644 --- a/index.html +++ b/index.html @@ -195,6 +195,11 @@ 🔊 + + + diff --git a/src/main.ts b/src/main.ts index f7da16c..c6be37f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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 = ""; + }); }); diff --git a/src/styles/main.css b/src/styles/main.css index 34a1ccb..a754dac 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -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;