diff --git a/src/webui/js/gallery-editor.js b/src/webui/js/gallery-editor.js
index d523ef3..926d5ab 100644
--- a/src/webui/js/gallery-editor.js
+++ b/src/webui/js/gallery-editor.js
@@ -48,7 +48,7 @@ function renderGallery() {
div.className = 'photo flex-item flex-column';
div.innerHTML = `
-

+
@@ -92,6 +92,22 @@ function renderGallery() {
if (removeAllBtnBottom) {
removeAllBtnBottom.style.display = imagesToShow.length > 0 ? 'inline-block' : 'none';
}
+
+ // --- Fade-in effect for loaded images ---
+ const fadeImages = document.querySelectorAll("img.fade-in-img");
+ fadeImages.forEach(img => {
+ const onLoad = () => {
+ img.classList.add("loaded");
+ };
+ if (img.complete && img.naturalHeight !== 0) {
+ onLoad();
+ } else {
+ img.addEventListener("load", onLoad, { once: true });
+ img.addEventListener("error", () => {
+ console.warn("Image failed to load:", img.dataset.src || img.src);
+ });
+ }
+ });
}
// --- Render tags for a single image ---
@@ -514,5 +530,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (removeAllHeroBtnBottom) removeAllHeroBtnBottom.onclick = () => showDeleteModal('hero-all');
});
+
+
// --- Initialize ---
loadData();
\ No newline at end of file
diff --git a/src/webui/style/style.css b/src/webui/style/style.css
index 6e40580..a5deb7a 100644
--- a/src/webui/style/style.css
+++ b/src/webui/style/style.css
@@ -337,6 +337,20 @@ h2 {
.toast.success { background-color: #28a7468c; }
.toast.error { background-color: #dc3545; }
+/* img fade in */
+
+.fade-in-img {
+ opacity: 0;
+ transform: scale(1.02);
+ transition: opacity 1.2s ease-out, transform 1.2s ease-out;
+ will-change: opacity, transform;
+}
+
+.fade-in-img.loaded {
+ opacity: 1;
+ transform: scale(1);
+}
+
/* --- Tags --- */
.tag-input {
display: flex;