← back to 1950swallpaper
hero: rotate curated room-setting pool (hero-pool.json), guard >=1400px, never swatches
364ae9984a0ee1f951b1f88ad16199426872f250 · 2026-06-01 15:15:56 -0700 · SteveStudio2
Kills the post-load blur: rotateHero no longer swaps the sharp static hero for
800px product sample swatches. Now rotates only large room images from
/hero-pool.json, preloads + checks naturalWidth>=1400 before painting, else keeps
the static hero. Canary for the 46-site fleet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 364ae9984a0ee1f951b1f88ad16199426872f250
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon Jun 1 15:15:56 2026 -0700
hero: rotate curated room-setting pool (hero-pool.json), guard >=1400px, never swatches
Kills the post-load blur: rotateHero no longer swaps the sharp static hero for
800px product sample swatches. Now rotates only large room images from
/hero-pool.json, preloads + checks naturalWidth>=1400 before painting, else keeps
the static hero. Canary for the 46-site fleet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/index.html | 51 ++++++++++++++++++++++++++-------------------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/public/index.html b/public/index.html
index d383223..e12fef4 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1083,34 +1083,35 @@ loadGridPage();
}
}, true);
// DW STANDARD: hero pulls from products.json[0].image_url so dw-collections-viewer
-// drag-drop / hero-pin updates the live front page on next deploy.
-// Always upgrades to the largest Shopify variant (strips _NxN size suffix) so
-// the full-page hero stays sharp.
-// DW STANDARD: hero rotates through top-20 NEWEST products on each visit
-// (novasuede.com pattern). Fetches /api/products?limit=100, sorts by created_at desc,
-// takes the freshest 20, picks one per visit via localStorage counter.
-// Falls back to static /hero-bg.jpg on any error.
+// DW STANDARD hero rotation (v2 — room-setting pool, curated in the live-fleet viewer).
+// Rotates ONLY large room-setting / hero-grade images from /hero-pool.json (highest-res
+// first), one per visit. Each candidate is preloaded and painted ONLY if it actually
+// decodes >= 1400px wide, so a small image can never blur the full-bleed hero. If the
+// pool is empty or nothing qualifies, the sharp static /hero-bg.jpg stays put.
+// NOTE: product sample swatches (~800px) are intentionally NOT used here — they read
+// blurry full-bleed. Curate big room images via the fleet viewer (writes hero-pool.json).
(async function rotateHero() {
+ const bg = document.getElementById('heroBg') || document.getElementById('cinemaBg');
+ if (!bg) return;
+ let pool = [];
try {
- const r = await fetch('/api/products?limit=100');
- if (!r.ok) return;
- const d = await r.json();
- const items = (d.items || [])
- .filter(p => p && p.image_url && /^https:\/\/(?:cdn\.shopify\.com|designerwallcoverings\.com)\//.test(p.image_url))
- .sort((a,b) => String(b.created_at || '').localeCompare(String(a.created_at || '')))
- .slice(0, 20);
- if (!items.length) return;
- let visits = 0;
- try {
- visits = parseInt(localStorage.getItem('hero_visits') || '0', 10) || 0;
- localStorage.setItem('hero_visits', String(visits + 1));
- } catch(e) {}
- const pick = items[visits % items.length];
- // Strip _NxN size suffix to get the largest CDN variant
- const url = pick.image_url.replace(/(_\d+x\d*)(\.(jpg|jpeg|png|webp|gif))(\?|$)/i, '$2$4');
- const bg = document.getElementById('heroBg') || document.getElementById('cinemaBg');
- if (bg) bg.style.backgroundImage = "url('" + url + "')";
+ const r = await fetch('/hero-pool.json', { cache: 'no-store' });
+ if (r.ok) { const j = await r.json(); pool = Array.isArray(j) ? j : (j.images || []); }
} catch (e) {}
+ pool = (pool || []).filter(u => typeof u === 'string' && /^https?:\/\/|^\//.test(u));
+ if (!pool.length) return; // no curated pool -> keep sharp static hero
+ let visits = 0;
+ try { visits = parseInt(localStorage.getItem('hero_visits') || '0', 10) || 0; localStorage.setItem('hero_visits', String(visits + 1)); } catch (e) {}
+ const start = visits % pool.length;
+ // Try pool entries in rotation order; paint the first that decodes big enough.
+ (function tryAt(i) {
+ if (i >= pool.length) return; // none qualified -> static hero stays
+ const url = pool[(start + i) % pool.length];
+ const probe = new Image();
+ probe.onload = () => { if (probe.naturalWidth >= 1400) bg.style.backgroundImage = "url('" + url + "')"; else tryAt(i + 1); };
+ probe.onerror = () => tryAt(i + 1);
+ probe.src = url;
+ })(0);
})();
← a230b76 header name → domain name '1950s Wallpaper' (remove odd bran
·
back to 1950swallpaper
·
FIX: dw-header was injected inside a doc-comment (never ran) f6db7e2 →