Beta-2.1 - The clearer, the faster #22
@@ -48,7 +48,7 @@ function renderGallery() {
 | 
				
			|||||||
    div.className = 'photo flex-item flex-column';
 | 
					    div.className = 'photo flex-item flex-column';
 | 
				
			||||||
    div.innerHTML = `
 | 
					    div.innerHTML = `
 | 
				
			||||||
      <div class="flex-item">
 | 
					      <div class="flex-item">
 | 
				
			||||||
        <img src="/photos/${img.src}">
 | 
					        <img class="fade-in-img" src="/photos/${img.src}">
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="tags-display" data-index="${i}"></div>
 | 
					      <div class="tags-display" data-index="${i}"></div>
 | 
				
			||||||
      <div class="flex-item flex-full">
 | 
					      <div class="flex-item flex-full">
 | 
				
			||||||
@@ -92,6 +92,22 @@ function renderGallery() {
 | 
				
			|||||||
  if (removeAllBtnBottom) {
 | 
					  if (removeAllBtnBottom) {
 | 
				
			||||||
    removeAllBtnBottom.style.display = imagesToShow.length > 0 ? 'inline-block' : 'none';
 | 
					    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 ---
 | 
					// --- Render tags for a single image ---
 | 
				
			||||||
@@ -514,5 +530,7 @@ document.addEventListener('DOMContentLoaded', () => {
 | 
				
			|||||||
  if (removeAllHeroBtnBottom) removeAllHeroBtnBottom.onclick = () => showDeleteModal('hero-all');
 | 
					  if (removeAllHeroBtnBottom) removeAllHeroBtnBottom.onclick = () => showDeleteModal('hero-all');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Initialize ---
 | 
					// --- Initialize ---
 | 
				
			||||||
loadData();
 | 
					loadData();
 | 
				
			||||||
@@ -337,6 +337,20 @@ h2 {
 | 
				
			|||||||
.toast.success { background-color: #28a7468c; }
 | 
					.toast.success { background-color: #28a7468c; }
 | 
				
			||||||
.toast.error { background-color: #dc3545; }
 | 
					.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 --- */
 | 
					/* --- Tags --- */
 | 
				
			||||||
.tag-input {
 | 
					.tag-input {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user