[object Object]

← back to Quadrille Showroom

Usable view: 6ft back + dead-centre + 65° open + ISOLATE (hide other boards); replace Fan with Back/Next board nav; remove 'fanning' wording

6e2efdde04a888024d009a5a786d481eb14398a9 · 2026-06-27 10:29:11 -0700 · Steve

Files touched

Diff

commit 6e2efdde04a888024d009a5a786d481eb14398a9
Author: Steve <steve@designerwallcoverings.com>
Date:   Sat Jun 27 10:29:11 2026 -0700

    Usable view: 6ft back + dead-centre + 65° open + ISOLATE (hide other boards); replace Fan with Back/Next board nav; remove 'fanning' wording
---
 public/js/showroom.js | 45 ++++++++++++++++++++++++++++-----------------
 public/showroom.html  |  6 +++---
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/public/js/showroom.js b/public/js/showroom.js
index 1b0a428..952847f 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -40,7 +40,7 @@ let wallsAutoClad = true;    // focusing a wing clads the room walls in its patt
 // like a sample book — left leaf mirrored, right leaf normal (same pattern, both sides).
 let proximityEnabled = true;
 const PROX_FT = 1.22;        // 4 feet, in meters
-const BOOK_OPEN = 1.35;      // leaf hinge angle when open (~77°) — panels open out to present 1 design
+let BOOK_OPEN = 1.134;       // 65° leaf hinge when open (Steve) — panels present 1 design
 
 // SHARED materials — key perf optimization
 const MAT = {};
@@ -1140,15 +1140,17 @@ function focusOnWing(pivot) {
   previousCamTarget = controls.target.clone();
 
   focusedWing = pivot;
-  pivot.userData.panelClosed = false;  // focusing a board fans it open to present its design
+  pivot.userData.panelClosed = false;  // focusing a board opens it to present its design
+  isolateBoard(pivot);                 // hide the other boards → the design stands alone
 
   // Calculate world position of the wing
   const wingWorldPos = new THREE.Vector3();
   pivot.getWorldPosition(wingWorldPos);
 
-  // All wings face forward (+Z) on back wall — camera goes 1.2m in front
-  const camTarget = new THREE.Vector3(wingWorldPos.x, 1.2, wingWorldPos.z);
-  const camPos = new THREE.Vector3(wingWorldPos.x, 1.6, wingWorldPos.z + 1.2);
+  // Stand ~6 ft back, DEAD-CENTRE on the board, aimed at its vertical centre so the
+  // whole 6-ft design reads cleanly; the board opens to 65° (BOOK_OPEN), isolated.
+  const camTarget = new THREE.Vector3(wingWorldPos.x, 0.98, wingWorldPos.z);
+  const camPos = new THREE.Vector3(wingWorldPos.x, 1.02, wingWorldPos.z + 1.95);
 
   // Fly camera there, then hard-lock
   smoothCameraTo(camPos, camTarget, () => {
@@ -1166,7 +1168,21 @@ function focusOnWing(pivot) {
   // Clad the room walls in this pattern (immersive "see it on the wall")
   if (wallsAutoClad) cladWalls(product.image, product.isSeamlessTile);
   updateOpenBtnState(false);
-  document.getElementById('info-text').textContent = `Wing: ${product.pattern_name || product.name} by ${product.vendor} | Fan open to browse adjacent patterns`;
+  document.getElementById('info-text').textContent = `${product.pattern_name || product.name} · ${product.vendor}  |  ◀ Back / Next ▶ to flip through`;
+}
+
+// Isolate the focused board — hide the others so the open design is presented alone,
+// dead-centre. Restored on exit / window rebuild.
+function isolateBoard(pivot) { wingBoards.forEach(p => { p.visible = (p === pivot); }); }
+function restoreBoards() { wingBoards.forEach(p => { p.visible = true; }); }
+
+// Next / Back — flip to the next/previous wingboard (pages window edges, endless).
+async function gotoBoardOffset(delta) {
+  if (!wingBoards.length) return;
+  let idx = (focusedWing ? focusedWing.userData.index : 0) + delta;
+  if (idx >= wingBoards.length) { if (await advanceWindow(1)) { restoreBoards(); focusOnWing(wingBoards[0]); return; } idx = wingBoards.length - 1; }
+  else if (idx < 0) { if (await advanceWindow(-1)) { restoreBoards(); focusOnWing(wingBoards[wingBoards.length - 1]); return; } idx = 0; }
+  focusOnWing(wingBoards[idx]);
 }
 
 // "Fan out" — open the FOCUSED board's two panels (left & right) to present its
@@ -1195,6 +1211,7 @@ function closeFanCascade(skipBtnUpdate) {
 // Back button — close fan, unlock controls, fly camera back
 function unfocusWing(skipPanel) {
   if (fanWings.length > 0) closeFanCascade();
+  restoreBoards();          // bring the other wingboards back
   focusedWing = null;
   // Revert walls only on a true exit — peruse's internal wing-to-wing close passes
   // skipPanel=true and the next cladWalls overwrites, so no neutral flicker.
@@ -1277,17 +1294,11 @@ function showWingDetail(product) {
   if (cta) cta.textContent = product.cta_mode === 'live' ? 'View on Designer Wallcoverings' : 'Request a Memo Sample';
 }
 
-function updateOpenBtnState(dir) {
+function updateOpenBtnState() {
   const btnL = document.getElementById('btn-fan-left');
   const btnR = document.getElementById('btn-fan-right');
-  if (btnL) {
-    btnL.classList.toggle('active', dir === 1);
-    btnL.textContent = dir === 1 ? '\u25AE\u25AE Close' : '\u25C4 Fan Left';
-  }
-  if (btnR) {
-    btnR.classList.toggle('active', dir === -1);
-    btnR.textContent = dir === -1 ? '\u25AE\u25AE Close' : 'Fan Right \u25BA';
-  }
+  if (btnL) { btnL.classList.remove('active'); btnL.innerHTML = '\u25C4 Back'; }
+  if (btnR) { btnR.classList.remove('active'); btnR.innerHTML = 'Next \u25BA'; }
 }
 
 function lockControls(pos, target) {
@@ -1592,8 +1603,8 @@ function initHUD() {
   }));
 
   document.getElementById('close-detail').addEventListener('click', () => unfocusWing());
-  document.getElementById('btn-fan-left').addEventListener('click', () => fanCascadeOpen(1));
-  document.getElementById('btn-fan-right').addEventListener('click', () => fanCascadeOpen(-1));
+  document.getElementById('btn-fan-left').addEventListener('click', () => gotoBoardOffset(-1));   // Back
+  document.getElementById('btn-fan-right').addEventListener('click', () => gotoBoardOffset(1));    // Next
   document.getElementById('btn-back-wing').addEventListener('click', () => unfocusWing());
 
   document.getElementById('btn-music').addEventListener('click', () => document.getElementById('music-player').classList.toggle('hidden'));
diff --git a/public/showroom.html b/public/showroom.html
index 6f51d79..2597a8b 100644
--- a/public/showroom.html
+++ b/public/showroom.html
@@ -102,9 +102,9 @@
       <div id="detail-specs" hidden></div>
       <div class="detail-actions">
         <div class="wing-skill-row">
-          <button class="action-btn primary" id="btn-fan-left">&#9664; Fan Left</button>
-          <span class="wing-skill-label">Fan Cascade</span>
-          <button class="action-btn primary" id="btn-fan-right">Fan Right &#9654;</button>
+          <button class="action-btn primary" id="btn-fan-left">&#9664; Back</button>
+          <span class="wing-skill-label">Browse</span>
+          <button class="action-btn primary" id="btn-fan-right">Next &#9654;</button>
         </div>
         <button class="action-btn" id="btn-add-sample">+ Add to Sample Tray</button>
         <button class="action-btn" id="btn-view-dw">View on Designer Wallcoverings</button>

← 80afbd8 Add 30s captioned how-to-use demo recorder  ·  back to Quadrille Showroom  ·  Add 2-min soak-test recorder (walk/open/Back-Next/Peruse; lo 1793384 →