Просмотр исходного кода

Make images fade in as they load

Svilen Markov 1 год назад
Родитель
Сommit
4beab6bcec
2 измененных файлов с 40 добавлено и 0 удалено
  1. 12 0
      internal/assets/static/main.css
  2. 28 0
      internal/assets/static/main.js

+ 12 - 0
internal/assets/static/main.css

@@ -217,6 +217,18 @@ img, svg {
     max-width: 100%;
 }
 
+img[loading=lazy].loaded:not(.finished-transition) {
+    transition: opacity .4s;
+}
+
+img[loading=lazy].cached:not(.finished-transition) {
+    transition: none;
+}
+
+img[loading=lazy]:not(.loaded, .cached) {
+    opacity: 0;
+}
+
 html {
     scrollbar-color: var(--color-text-subdue) transparent;
     scroll-behavior: smooth;

+ 28 - 0
internal/assets/static/main.js

@@ -142,6 +142,33 @@ function setupDynamicRelativeTime() {
     });
 }
 
+function setupLazyImages() {
+    const images = document.querySelectorAll("img[loading=lazy]");
+
+    if (images.length == 0) {
+        return;
+    }
+
+    function imageFinishedTransition(image) {
+        image.classList.add("finished-transition");
+    }
+
+    for (let i = 0; i < images.length; i++) {
+        const image = images[i];
+
+        if (image.complete) {
+            image.classList.add("cached");
+            setTimeout(() => imageFinishedTransition(image), 5);
+        } else {
+            // TODO: also handle error event
+            image.addEventListener("load", () => {
+                image.classList.add("loaded");
+                setTimeout(() => imageFinishedTransition(image), 500);
+            });
+        }
+    }
+}
+
 async function setupPage() {
     const pageElement = document.getElementById("page");
     const pageContents = await fetchPageContents(pageData.slug);
@@ -152,6 +179,7 @@ async function setupPage() {
         document.body.classList.add("animate-element-transition");
     }, 150);
 
+    setTimeout(setupLazyImages, 5);
     setupCarousels();
     setupDynamicRelativeTime();
 }