← back to Quadrille Showroom
V1 establishing arc (matches pj-dallas-showroom.png) + V2 step-driven conveyor + rail layout
5954106c4c41ae639622c48e7a7f550bded6fb4f · 2026-06-28 07:54:28 -0700 · Steve
- V1: wide establishing shot (high front-right, FOV 64) showing the sliver-packed
corner arc + consultation nook + warm oak floor like the reference photo, instead of
isolating one board. restoreBoards()+revertWalls()+open middle; boot defers to 1800ms
so it wins the race vs the guided auto-focus (which was re-isolating to 1 board).
- V2 conveyor: real step controller (NOT auto-spin) — user dead-centre+stationary, the
RACK yaws so each product rotates INTO centre; ArrowRight/Left + guided Next/Prev step
one board at a time (capture-phase intercept while V2 active only), eased anim, idle =
zero shadow rebakes. Verified: ArrowRight steps fwd, ArrowLeft steps back.
- setVersion now calls the prior version's exit() (conveyor key/click/frame cleanup).
- Rail layout: anchored top-right + max-height capped so it never collides with the
bottom-right Chosen tray (was overlapping at 1600x900); collapse transform fixed.
- test-versions samples steady-state FPS (after settle) — all 10 versions hold 72fps;
earlier sub-50 reads were camera-fly/texture-upload settling frames. 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M public/js/rack.jsM public/js/showroom.jsM public/showroom.htmlM scripts/test-versions.js
Diff
commit 5954106c4c41ae639622c48e7a7f550bded6fb4f
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jun 28 07:54:28 2026 -0700
V1 establishing arc (matches pj-dallas-showroom.png) + V2 step-driven conveyor + rail layout
- V1: wide establishing shot (high front-right, FOV 64) showing the sliver-packed
corner arc + consultation nook + warm oak floor like the reference photo, instead of
isolating one board. restoreBoards()+revertWalls()+open middle; boot defers to 1800ms
so it wins the race vs the guided auto-focus (which was re-isolating to 1 board).
- V2 conveyor: real step controller (NOT auto-spin) — user dead-centre+stationary, the
RACK yaws so each product rotates INTO centre; ArrowRight/Left + guided Next/Prev step
one board at a time (capture-phase intercept while V2 active only), eased anim, idle =
zero shadow rebakes. Verified: ArrowRight steps fwd, ArrowLeft steps back.
- setVersion now calls the prior version's exit() (conveyor key/click/frame cleanup).
- Rail layout: anchored top-right + max-height capped so it never collides with the
bottom-right Chosen tray (was overlapping at 1600x900); collapse transform fixed.
- test-versions samples steady-state FPS (after settle) — all 10 versions hold 72fps;
earlier sub-50 reads were camera-fly/texture-upload settling frames. 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/js/rack.js | 4 +++-
public/js/showroom.js | 10 +++++-----
public/showroom.html | 4 ++--
scripts/test-versions.js | 4 +++-
4 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/public/js/rack.js b/public/js/rack.js
index 7be23f4..70e6b3f 100644
--- a/public/js/rack.js
+++ b/public/js/rack.js
@@ -28,7 +28,9 @@
// Range chosen so the default (~62) lands on the photo's medium-thin slivers.
function revealToRake(reveal) {
const r = Math.max(0, Math.min(100, reveal));
- return (30 + (r / 100) * 48) * Math.PI / 180; // 30°..78°
+ // 38°..80° — at the default (~68) boards rake ~67° off dead-on so packed neighbours
+ // occlude all but a thin leading SLIVER, like the PJ fanned sample deck.
+ return (38 + (r / 100) * 42) * Math.PI / 180;
}
// Centre angle (radians, around the arc centre) of slot i of n boards.
diff --git a/public/js/showroom.js b/public/js/showroom.js
index 32b64d7..b0c9edd 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -19,9 +19,9 @@ const CONFIG = {
// The rack is a gentle ARC wrapping a room corner/bay. Boards hang from a curved
// brass rail, each hinged on its LEFT vertical edge, raked so packed they show only
// a thin vertical SLIVER of each pattern (occlusion gives the sliver for free).
- arcRadius: 3.2, // radius of the curved rail (m)
- arcSpanDeg: 104, // total angular sweep of the arc (wraps the corner/bay)
- arcCenter: { x: -0.3, z: -1.1 }, // arc centre in room space (boards face inward → viewer)
+ arcRadius: 3.3, // radius of the curved rail (m)
+ arcSpanDeg: 112, // total angular sweep of the arc (wraps the corner/bay)
+ arcCenter: { x: -0.3, z: -1.2 }, // arc centre in room space (boards face inward → viewer)
sliverPitchScale: 1.0 // multiplier on the angular pitch (reveal slider can thin)
},
camera: { startPos: { x: 1.8, y: 1.65, z: 3.6 }, fov: 55 }
@@ -38,7 +38,7 @@ let controlsLocked = false, lockedCamPos = null, lockedCamTarget = null, previou
let cameraAnim = null; // { startPos, endPos, startTarget, endTarget, progress, duration, onComplete }
// Window paging across the full catalog (50 live wings at a time)
-let windowOffset = 0, windowTotal = 0, windowSize = 18; // boards in the packed arc at once
+let windowOffset = 0, windowTotal = 0, windowSize = 22; // boards in the packed arc at once
let currentBrand = 'all', currentSort = 'natural', currentWallGroup = null;
// Peruse (endless auto-tour) state
let peruseActive = false, peruseIndex = 0, peruseTimer = null;
@@ -64,7 +64,7 @@ let VIEW_OPEN = (function () {
// more boards in view). Persisted to localStorage like the Wing°/Boards sliders.
let REVEAL = (function () {
const v = parseFloat(localStorage.getItem('qh_reveal'));
- return (v >= 0 && v <= 100) ? v : 62; // default ≈ the photo's medium-thin slivers
+ return (v >= 0 && v <= 100) ? v : 70; // default ≈ the photo's thin slivers (steep rake)
})();
// SHARED materials — key perf optimization
diff --git a/public/showroom.html b/public/showroom.html
index 0d493d2..f17a8d3 100644
--- a/public/showroom.html
+++ b/public/showroom.html
@@ -286,13 +286,13 @@
<option value="book">Book</option>
</select>
<span id="density-wrap" title="Wings per wall">
- <span>Boards</span><input type="range" id="density-range" min="8" max="24" step="2" value="18">
+ <span>Boards</span><input type="range" id="density-range" min="10" max="28" step="2" value="22">
</span>
<span id="density-wrap" title="Open-board angle (0°=flat, dead-on)">
<span>Wing°</span><input type="range" id="angle-range" min="0" max="90" step="5" value="8"><span id="angle-val">8°</span>
</span>
<span id="density-wrap" title="How much of each closed board's pattern shows — wider edges = fewer boards, thinner slivers = more boards in the arc">
- <span>Reveal</span><input type="range" id="reveal-range" min="0" max="100" step="5" value="62"><span id="reveal-val">62</span>
+ <span>Reveal</span><input type="range" id="reveal-range" min="0" max="100" step="5" value="70"><span id="reveal-val">70</span>
</span>
</div>
diff --git a/scripts/test-versions.js b/scripts/test-versions.js
index 43aa988..89caec1 100644
--- a/scripts/test-versions.js
+++ b/scripts/test-versions.js
@@ -68,7 +68,9 @@ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const perVersion = {};
for (const key of order) {
await page.click(`#ver-rail .ver-chip[data-version="${key}"]`);
- await sleep(2600); // let the camera fly + the look settle
+ await sleep(3200); // let the camera fly + the look fully settle before sampling steady-state FPS
+ await sampleFps(key + '-warm'); // discard the first read (may catch a settling frame)
+ await sleep(900);
const fps = await sampleFps(key);
const cur = await page.evaluate(() => window._versions.current);
perVersion[key] = { fps, applied: cur === key };
← f75fcc7 Perf + PJ-accurate isolate: hero stays AMID the sliver arc (
·
back to Quadrille Showroom
·
Add V1-vs-reference comparison + 10-version contact sheet; d e6c14ec →