diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/justifiedgallery.js | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/scripts/justifiedgallery.js b/scripts/justifiedgallery.js index 0d8c2e1..690bd49 100644 --- a/scripts/justifiedgallery.js +++ b/scripts/justifiedgallery.js @@ -8,7 +8,8 @@ rowHeight: 80, //target row height (px)
margins: 2, //gap between images (px)
maxRowHeight: '150%', //cap on stretched row height
- lastRow: 'nojustify' //how to handle the final incomplete row
+ lastRow: 'nojustify', //how to handle the final incomplete row
+ trickleMs: 1000 //before any scroll: load 1 image per this many ms
};
const galleryEl = document.getElementById('gallery');
@@ -55,6 +56,37 @@ const res = await fetch(CONFIG.manifest);
const items = await res.json();
+ const pending = []; // imgs still waiting for a src, in order
+ let unlocked = false;
+
+ function startLoad(img) {
+ const src = img.dataset.src;
+ if (!src) return;
+ delete img.dataset.src;
+ const reveal = () => img.parentNode.classList.add('jg-entry-visible');
+ img.addEventListener('load', reveal, { once: true });
+ img.addEventListener('error', reveal, { once: true });
+ img.src = src;
+ }
+
+ // before the first scroll: 1 image per CONFIG.trickleMs
+ const trickle = setInterval(() => {
+ const img = pending.shift();
+ if (img) startLoad(img);
+ else clearInterval(trickle);
+ }, CONFIG.trickleMs);
+
+ // first scroll/wheel/touch anywhere (page or gallery box): release everything.
+ // img.loading='lazy' still makes the browser only fetch what's near the viewport.
+ function unlock() {
+ if (unlocked) return;
+ unlocked = true;
+ clearInterval(trickle);
+ pending.splice(0).forEach(startLoad);
+ }
+ ['scroll', 'wheel', 'touchmove'].forEach(ev =>
+ window.addEventListener(ev, unlock, { passive: true, capture: true, once: true }));
+
items.forEach(({ folder, file, width, height }) => {
const src = folder + file;
const thumbSrc = CONFIG.thumbFolder + folder + file.replace(CONFIG.imageExtensions, '.webp');
@@ -67,7 +99,8 @@ img.loading = 'lazy';
img.width = width;
img.height = height;
- img.src = thumbSrc;
+ img.dataset.src = thumbSrc; // real src is set later (trickle / first scroll)
+ pending.push(img);
entry.appendChild(img);
entry.addEventListener('click', async () => {
@@ -83,7 +116,8 @@ rowHeight: CONFIG.rowHeight,
margins: CONFIG.margins,
maxRowHeight: CONFIG.maxRowHeight,
- lastRow: CONFIG.lastRow
+ lastRow: CONFIG.lastRow,
+ waitThumbnailsLoad: false // lay out from width/height attrs, no src needed
});
}
@@ -322,6 +356,7 @@ const justifiedGallery = (function () { captionFromEntry(entry) {
const captions = Array.from(entry.querySelectorAll('.jg-caption'));
+
return captions.find(el => el.parentNode === entry) || null;
}
|
