← 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
M public/js/showroom.jsM public/showroom.html
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">◀ Fan Left</button>
- <span class="wing-skill-label">Fan Cascade</span>
- <button class="action-btn primary" id="btn-fan-right">Fan Right ▶</button>
+ <button class="action-btn primary" id="btn-fan-left">◀ Back</button>
+ <span class="wing-skill-label">Browse</span>
+ <button class="action-btn primary" id="btn-fan-right">Next ▶</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 →