← back to Glitterwalls
hero: shuffle hi-res pool every page load — both carousel order and 4-grid tiles rotate per visit
1d62ecda1bc36e504c22fb753f41b5fe659779dc · 2026-05-08 08:43:56 -0700 · Steve Abrams
Files touched
Diff
commit 1d62ecda1bc36e504c22fb753f41b5fe659779dc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri May 8 08:43:56 2026 -0700
hero: shuffle hi-res pool every page load — both carousel order and 4-grid tiles rotate per visit
---
public/index.html | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/public/index.html b/public/index.html
index f0720be..aedb308 100644
--- a/public/index.html
+++ b/public/index.html
@@ -953,21 +953,26 @@ loadGridPage();
// Probe original (un-resized) URLs in parallel — Shopify returns the master file.
const probed = (await Promise.all(cands.map(c => probe(c.url)))).filter(Boolean);
- probed.sort((a,b) => b.w - a.w);
- const hires = probed.filter(p => p.w >= HIRES_MIN).slice(0, 8);
-
- if (hires.length >= 4) {
- // Single-image full-bleed crossfade carousel of hi-res only
+ // Hi-res pool: only images that are genuinely high-end, high-res.
+ const hiresPool = probed.filter(p => p.w >= HIRES_MIN);
+ // Fisher-Yates shuffle so every page load picks a different set/order.
+ function shuffle(a){ for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];} return a; }
+ shuffle(hiresPool);
+
+ if (hiresPool.length >= 4) {
+ // Single-image full-bleed crossfade carousel of hi-res images only,
+ // randomized each visit.
+ const cycle = hiresPool.slice(0, Math.min(8, hiresPool.length));
const overlay = document.createElement('div');
overlay.style.cssText = 'position:absolute;inset:0;background-size:cover;background-position:center;opacity:0;transition:opacity 1.8s ease;z-index:1';
bg.style.position = 'absolute'; bg.style.inset = '0';
bg.style.transition = 'opacity 1.8s ease'; bg.style.zIndex = '0';
bg.parentNode.insertBefore(overlay, bg.nextSibling);
- let idx = Math.floor(Math.random() * hires.length);
- bg.style.backgroundImage = "url('" + hires[idx].url + "')";
+ let idx = 0;
+ bg.style.backgroundImage = "url('" + cycle[idx].url + "')";
setInterval(() => {
- idx = (idx + 1) % hires.length;
- const nextUrl = hires[idx].url;
+ idx = (idx + 1) % cycle.length;
+ const nextUrl = cycle[idx].url;
overlay.style.backgroundImage = "url('" + nextUrl + "')";
overlay.style.opacity = '1';
setTimeout(() => {
@@ -980,10 +985,16 @@ loadGridPage();
return;
}
- // Fallback: 2x2 grid of the 4 best-resolution images (no fake hero)
- const top4 = probed.slice(0, 4);
- if (top4.length < 1) return;
- while (top4.length < 4) top4.push(top4[top4.length % Math.max(1, top4.length)]);
+ // 2×2 grid mode — pick 4 fresh tiles each visit. Prefer hi-res, only
+ // fall back to the next-best resolution if hi-res pool can't fill 4.
+ const ranked = probed.slice().sort((a,b) => b.w - a.w);
+ const tier1 = ranked.filter(p => p.w >= HIRES_MIN);
+ const tier2 = ranked.filter(p => p.w >= 1000 && p.w < HIRES_MIN);
+ let pool = tier1.length >= 4 ? tier1 : tier1.concat(tier2);
+ shuffle(pool);
+ const tiles = pool.slice(0, 4);
+ if (tiles.length < 1) return;
+ while (tiles.length < 4) tiles.push(tiles[tiles.length % Math.max(1, tiles.length)]);
bg.style.backgroundImage = 'none';
bg.style.background = '#000';
bg.style.position = 'absolute'; bg.style.inset = '0';
@@ -991,7 +1002,7 @@ loadGridPage();
bg.style.gridTemplateColumns = '1fr 1fr';
bg.style.gridTemplateRows = '1fr 1fr';
bg.style.gap = '2px';
- for (const tile of top4) {
+ for (const tile of tiles) {
const cell = document.createElement('div');
cell.style.cssText = "background-size:cover;background-position:center;background-image:url('"+tile.url+"');";
bg.appendChild(cell);
← 8ccb352 hero: hi-res only (>=1600px wide) carousel; 2x2 grid fallbac
·
back to Glitterwalls
·
remove /hero-bg.jpg flash — preload + CSS default replaced w 9d8a4a7 →