summary refs log tree commit diff stats
path: root/resources/js/gallery.js
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2022-06-11 11:58:29 +0530
committerAndinus <andinus@nand.sh>2022-06-11 11:58:29 +0530
commit89c60aee5a602ed5bfd73a9d5bcbbf9945aac44f (patch)
treec734a88fc77c56faa6b68edfde3484f8859e9b73 /resources/js/gallery.js
parentbef200b4669f058ce43ec9c0a3583de7fac558e3 (diff)
downloadcrater-89c60aee5a602ed5bfd73a9d5bcbbf9945aac44f.tar.gz
Scope css, improve image error handling, show progress bar
- Errors are shown if some images fail to load.
- Progress bar is shown while images are loading.
- .pack is called after all images have been loaded.
Diffstat (limited to 'resources/js/gallery.js')
-rw-r--r--resources/js/gallery.js96
1 files changed, 61 insertions, 35 deletions
diff --git a/resources/js/gallery.js b/resources/js/gallery.js
index bab4d1d..2a608f5 100644
--- a/resources/js/gallery.js
+++ b/resources/js/gallery.js
@@ -1,68 +1,94 @@
 'use strict';
 
+const round = Math.round;
+
 // image width.
 const imgW = 400;
 
 // Gallery using bricks.js ////////////////////////////////////////////////////
 
-// mq      - the minimum viewport width (String CSS unit: em, px, rem)
-// columns - the number of vertical columns
-// gutter  - the space (in px) between the columns and grid items
 const sizes = [
     { columns: 1, gutter: 30 },
-    { mq: Math.round((imgW * 2.2) + 40) + "px", columns: 2, gutter: 35 },
-    { mq: Math.round((imgW * 3.5) + 50) + "px", columns: 3, gutter: 50 },
-    { mq: Math.round((imgW * 4.4) + 50) + "px", columns: 4, gutter: 50 },
+    { mq: round((imgW * 2.2) + 40) + "px", columns: 2, gutter: 35 },
+    { mq: round((imgW * 3.5) + 50) + "px", columns: 3, gutter: 50 },
+    { mq: round((imgW * 4.4) + 50) + "px", columns: 4, gutter: 50 },
 ];
 
-const instance = Bricks({
+const bricks = Bricks({
     container: '#gallery',
     packed: 'data-packed',
     sizes: sizes
 });
 
-instance
+bricks
     .on('pack',   () => console.log('ALL grid items packed.'))
     .on('update', () => console.log('NEW grid items packed.'))
     .on('resize', size => console.log(
         'The grid has be re-packed to accommodate a new BREAKPOINT.', size
     ));
 
-// start it up, when the DOM is ready. note that if images are in the
-// grid, you may need to wait for document.readyState === 'complete'.
 document.addEventListener('DOMContentLoaded', event => {
-    instance.resize(true).pack(); // bind resize handler & pack initial items
-});
-document.addEventListener('readystatechange', event => {
-    if (event.target.readyState === 'complete') {
-        instance.pack();
-    }
+    bricks.resize(true); // bind resize handler
 });
 
-// Re-packing after loading images ////////////////////////////////////////////
+// Packing after loading images ////////////////////////////////////////////
+
+const onImagesLoaded = (container, event) => {
+    const images = container.getElementsByTagName("img");
+    const progressBar = document.getElementById("loading-progress");
+
+    // failed keeps track of images that failed to load.
+    let failed = 0;
+    let remaining = images.length;
 
-function onImagesLoaded(container, event) {
-    let images = container.getElementsByTagName("img");
-    let loaded = images.length;
     for (let i = 0; i < images.length; i++) {
-        if (images[i].complete) {
-            loaded--;
-        }
+        if (images[i].complete)
+            remaining--;
         else {
+            // Add listeners to images that have to be loaded.
             images[i].addEventListener("load", function () {
-                loaded--;
-                if (loaded == 0) {
-                    event();
-                }
+                remaining--;
+                progressBar.value = round(
+                    ((images.length - remaining) / images.length) * 100
+                );
+                if (remaining === failed)
+                    event(remaining, failed, progressBar);
             });
+
+            // If loading fails then we increment failed, an error
+            // will be shown later.
+            images[i].addEventListener("error", function () {
+                failed++;
+                if (remaining === failed)
+                    event(remaining, failed, progressBar);
+            });
+
         }
-        if (loaded == 0) {
-            event();
-        }
+        if (remaining == failed)
+            event(remaining, failed, progressBar);
     }
-}
+};
 
-const container = document.getElementById("gallery");
-onImagesLoaded(container, function () {
-    instance.pack();
-});
+const gallery = document.getElementById("gallery");
+const imagesLoaded = (remaining, failed, progressBar) => {
+    bricks.pack();
+
+    progressBar.value = 100;
+    document.getElementById("loading").style.display = "none";
+
+    // Show error on failure.
+    const loadError = document.getElementById("loading-error");
+    const loadErrorText = document.getElementById("loading-error-text");
+    const loadErrorDismiss = document.getElementById("loading-error-dismiss");
+    if (failed !== 0) {
+        loadError.style.display = "block";
+        const t = failed === 1 ? "image" : "images";
+        loadErrorText.innerHTML = `${failed} ${t} failed to load.`;
+
+        loadErrorDismiss.addEventListener('click', function(){
+            loadError.style.display = "none";
+        });
+    }
+};
+
+onImagesLoaded(gallery, imagesLoaded);