Skip to content

Commit 278c166

Browse files
author
DavidQ
committed
`feat(vector-map-editor): unify fullscreen sidebars with accordion UX and no-page-scroll layout
- enforce fullscreen fit-to-viewport behavior with no page scrollbar - keep scrolling scoped to overlay side panels only in fullscreen - add/keep overlay close controls with updated X styling/position - convert right properties sidebar sections to accordions - default open: Selected Object - default closed: Center Point, Rotation, Appearance, Collision Flags, Points - move Keyboard & Mouse section to left sidebar - convert left sidebar sections to accordions - default open: Objects - default closed: Document, Collision Result, Keyboard & Mouse - preserve existing control IDs and tool behavior while improving fullscreen readability and panel navigation`
1 parent 05cb8b4 commit 278c166

6 files changed

Lines changed: 396 additions & 164 deletions

File tree

tools/Parallax Scene Studio/index.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
</header>
7575

7676
<div class="workspace tools-platform-layout-grid">
77-
<aside class="sidebar left-sidebar tools-platform-resize-panel" data-panel-side="left">
77+
<aside class="sidebar left-sidebar tools-platform-resize-panel" data-panel-side="left" id="leftSidebar">
7878
<section class="panel">
7979
<h3>Parallax Layers</h3>
8080
<ul id="layerList" class="layer-list"></ul>
@@ -117,11 +117,13 @@ <h3>Preview Camera</h3>
117117
</div>
118118
<div class="preview-wrap">
119119
<canvas id="previewCanvas" width="960" height="540"></canvas>
120+
<button id="showLeftPanelButton" class="fullscreen-overlay-button" type="button">Layers</button>
121+
<button id="showRightPanelButton" class="fullscreen-overlay-button" type="button">Properties</button>
120122
</div>
121123
<div id="statusText" class="status-text">Ready.</div>
122124
</main>
123125

124-
<aside class="sidebar right-sidebar tools-platform-resize-panel" data-panel-side="right">
126+
<aside class="sidebar right-sidebar tools-platform-resize-panel" data-panel-side="right" id="rightSidebar">
125127
<section class="panel">
126128
<h3>Selected Layer</h3>
127129
<label>

tools/Parallax Scene Studio/main.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ class ParallaxEditorApp {
378378
init(rootDocument) {
379379
this.captureRefs(rootDocument);
380380
this.attachEvents();
381+
this.syncFullscreenState();
381382
this.syncInputsFromDocument();
382383
this.renderAll();
383384
this.bindRuntimeStateSync();
@@ -452,6 +453,11 @@ class ParallaxEditorApp {
452453
this.refs.previewMeta = rootDocument.getElementById("previewMeta");
453454
this.refs.simulationContext = rootDocument.getElementById("simulationContext");
454455
this.refs.statusText = rootDocument.getElementById("statusText");
456+
this.refs.appShell = rootDocument.querySelector(".app-shell");
457+
this.refs.leftSidebar = rootDocument.getElementById("leftSidebar");
458+
this.refs.rightSidebar = rootDocument.getElementById("rightSidebar");
459+
this.refs.showLeftPanelButton = rootDocument.getElementById("showLeftPanelButton");
460+
this.refs.showRightPanelButton = rootDocument.getElementById("showRightPanelButton");
455461
this.refs.previewWrap = rootDocument.querySelector(".preview-wrap");
456462
this.refs.previewCanvas = rootDocument.getElementById("previewCanvas");
457463
this.refs.previewContext = this.refs.previewCanvas.getContext("2d", { alpha: false });
@@ -477,6 +483,17 @@ class ParallaxEditorApp {
477483
this.refs.inspectRemediationButton.addEventListener("click", () => this.inspectRemediationActions());
478484
this.refs.jumpToProblemButton.addEventListener("click", () => this.jumpToRemediationProblem());
479485
this.refs.applyRemediationButton.addEventListener("click", () => this.applyRemediationAction());
486+
this.refs.showLeftPanelButton?.addEventListener("click", () => {
487+
this.refs.leftSidebar?.classList.toggle("visible-overlay");
488+
});
489+
this.refs.showRightPanelButton?.addEventListener("click", () => {
490+
this.refs.rightSidebar?.classList.toggle("visible-overlay");
491+
});
492+
document.addEventListener("fullscreenchange", () => {
493+
this.syncFullscreenState();
494+
this.refs.leftSidebar?.classList.remove("visible-overlay");
495+
this.refs.rightSidebar?.classList.remove("visible-overlay");
496+
});
480497

481498
this.refs.applyMapMetaButton.addEventListener("click", () => this.applyMapMetaFromInputs());
482499
this.refs.projectNameInput.addEventListener("change", () => this.applyMapMetaFromInputs());
@@ -513,6 +530,10 @@ class ParallaxEditorApp {
513530
}
514531
}
515532

533+
syncFullscreenState() {
534+
document.body.classList.toggle("fullscreen-mode", Boolean(document.fullscreenElement));
535+
}
536+
516537
getSelectedLayer() {
517538
return this.documentModel.layers.find((layer) => layer.id === this.selectedLayerId) || this.documentModel.layers[0] || null;
518539
}

tools/Parallax Scene Studio/parallaxEditor.css

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ button:hover,
143143
}
144144

145145
.preview-wrap {
146+
position: relative;
146147
flex: 1;
147148
min-height: 260px;
148149
border: 1px solid var(--parallax-border);
@@ -224,6 +225,93 @@ button:hover,
224225
font-size: 12px;
225226
}
226227

228+
.parallax-editor-page .fullscreen-overlay-button {
229+
position: absolute;
230+
top: 10px;
231+
z-index: 20;
232+
display: none;
233+
min-height: 32px;
234+
padding: 0 10px;
235+
}
236+
237+
.parallax-editor-page #showLeftPanelButton {
238+
left: 10px;
239+
}
240+
241+
.parallax-editor-page #showRightPanelButton {
242+
right: 10px;
243+
}
244+
245+
body.parallax-editor-page.fullscreen-mode .app-shell {
246+
min-height: 100vh;
247+
min-height: 100dvh;
248+
overflow: hidden;
249+
padding: 8px;
250+
gap: 8px;
251+
}
252+
253+
body.parallax-editor-page.fullscreen-mode .toolbar {
254+
padding: 8px;
255+
gap: 8px;
256+
}
257+
258+
body.parallax-editor-page.fullscreen-mode .toolbar-group.tools-platform-control-cluster--workflow,
259+
body.parallax-editor-page.fullscreen-mode .toolbar-group.tools-platform-control-cluster--preview {
260+
display: none;
261+
}
262+
263+
body.parallax-editor-page.fullscreen-mode .workspace {
264+
grid-template-columns: minmax(0, 1fr);
265+
height: calc(100dvh - 90px);
266+
gap: 8px;
267+
}
268+
269+
body.parallax-editor-page.fullscreen-mode .sidebar {
270+
display: none;
271+
}
272+
273+
body.parallax-editor-page.fullscreen-mode .sidebar.visible-overlay {
274+
display: block;
275+
position: fixed;
276+
top: 70px;
277+
bottom: 8px;
278+
width: min(360px, calc(100vw - 24px));
279+
z-index: 50;
280+
overflow: auto;
281+
}
282+
283+
body.parallax-editor-page.fullscreen-mode .left-sidebar.visible-overlay {
284+
left: 12px;
285+
}
286+
287+
body.parallax-editor-page.fullscreen-mode .right-sidebar.visible-overlay {
288+
right: 12px;
289+
}
290+
291+
body.parallax-editor-page.fullscreen-mode .preview-panel {
292+
width: 100%;
293+
min-width: 0;
294+
height: 100%;
295+
padding: 8px;
296+
}
297+
298+
body.parallax-editor-page.fullscreen-mode .preview-wrap {
299+
overflow: hidden;
300+
min-height: 0;
301+
height: 100%;
302+
}
303+
304+
body.parallax-editor-page.fullscreen-mode #previewCanvas {
305+
width: 100%;
306+
height: 100%;
307+
}
308+
309+
body.parallax-editor-page.fullscreen-mode .fullscreen-overlay-button {
310+
display: inline-flex;
311+
align-items: center;
312+
justify-content: center;
313+
}
314+
227315
@media (max-width: 1260px) {
228316
.workspace {
229317
grid-template-columns: 1fr;

tools/Vector Map Editor/editor/VectorMapEditorApp.js

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,12 @@ export class VectorMapEditorApp {
8484
cacheElements(doc) {
8585
return {
8686
appRoot: doc.getElementById("appRoot"),
87+
headerAccordion: doc.querySelector(".is-collapsible"),
88+
toolsPlatformStatusHost: doc.querySelector("[data-tools-platform-status]"),
8789
leftSidebar: doc.getElementById("leftSidebar"),
8890
rightSidebar: doc.getElementById("rightSidebar"),
91+
closeLeftOverlayButton: doc.getElementById("closeLeftOverlayButton"),
92+
closeRightOverlayButton: doc.getElementById("closeRightOverlayButton"),
8993
showLeftPanelButton: doc.getElementById("showLeftPanelButton"),
9094
showRightPanelButton: doc.getElementById("showRightPanelButton"),
9195
canvasShell: doc.getElementById("canvasShell"),
@@ -111,7 +115,6 @@ export class VectorMapEditorApp {
111115
saveDocumentButton: doc.getElementById("saveDocumentButton"),
112116
exportRuntimeButton: doc.getElementById("exportRuntimeButton"),
113117
loadDocumentInput: doc.getElementById("loadDocumentInput"),
114-
toggleFullscreenButton: doc.getElementById("toggleFullscreenButton"),
115118
toggleJsonDockButton: doc.getElementById("toggleJsonDockButton"),
116119
duplicateObjectButton: doc.getElementById("duplicateObjectButton"),
117120
deleteObjectButton: doc.getElementById("deleteObjectButton"),
@@ -172,11 +175,15 @@ export class VectorMapEditorApp {
172175
start() {
173176
this.ctx = this.elements.canvas.getContext("2d");
174177
this.historyManager.reset();
178+
this.syncFullscreenLayoutHeight();
175179
this.resizeCanvas();
176180
this.wireEvents();
177181
this.syncUIFromDocument();
178182
this.render();
179-
window.addEventListener("resize", () => this.resizeCanvas());
183+
window.addEventListener("resize", () => {
184+
this.syncFullscreenLayoutHeight();
185+
this.resizeCanvas();
186+
});
180187
this.setStatus("Vector Map Editor ready.");
181188
void this.loadSampleManifest({ quiet: true });
182189
}
@@ -374,6 +381,7 @@ export class VectorMapEditorApp {
374381

375382
document.addEventListener("fullscreenchange", () => {
376383
this.fullscreenController.syncBodyClass();
384+
this.syncFullscreenLayoutHeight();
377385
this.elements.leftSidebar.classList.remove("visible-overlay");
378386
this.elements.rightSidebar.classList.remove("visible-overlay");
379387
this.resizeCanvas();
@@ -458,12 +466,6 @@ export class VectorMapEditorApp {
458466
this.setStatus(`Loaded ${file.name}.`);
459467
});
460468

461-
this.elements.toggleFullscreenButton.addEventListener("click", async () => {
462-
await this.fullscreenController.toggle();
463-
this.resizeCanvas();
464-
this.render();
465-
});
466-
467469
this.elements.showLeftPanelButton.addEventListener("click", () => {
468470
this.elements.leftSidebar.classList.toggle("visible-overlay");
469471
});
@@ -472,6 +474,14 @@ export class VectorMapEditorApp {
472474
this.elements.rightSidebar.classList.toggle("visible-overlay");
473475
});
474476

477+
this.elements.closeLeftOverlayButton?.addEventListener("click", () => {
478+
this.elements.leftSidebar.classList.remove("visible-overlay");
479+
});
480+
481+
this.elements.closeRightOverlayButton?.addEventListener("click", () => {
482+
this.elements.rightSidebar.classList.remove("visible-overlay");
483+
});
484+
475485
this.elements.toggleJsonDockButton.addEventListener("click", () => {
476486
this.elements.jsonDock.classList.toggle("hidden");
477487
this.resizeCanvas();
@@ -703,6 +713,35 @@ export class VectorMapEditorApp {
703713
});
704714
}
705715

716+
syncFullscreenLayoutHeight() {
717+
const appRoot = this.elements.appRoot;
718+
if (!(appRoot instanceof HTMLElement)) {
719+
return;
720+
}
721+
722+
if (!document.fullscreenElement) {
723+
appRoot.style.height = "";
724+
appRoot.style.maxHeight = "";
725+
document.body.style.overflow = "";
726+
document.documentElement.style.overflow = "";
727+
return;
728+
}
729+
730+
const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
731+
const headerHeight = this.elements.headerAccordion instanceof HTMLElement
732+
? this.elements.headerAccordion.getBoundingClientRect().height
733+
: 0;
734+
const statusHeight = this.elements.toolsPlatformStatusHost instanceof HTMLElement
735+
? this.elements.toolsPlatformStatusHost.getBoundingClientRect().height
736+
: 0;
737+
const availableHeight = Math.max(320, Math.floor(viewportHeight - headerHeight - statusHeight - 4));
738+
739+
appRoot.style.height = `${availableHeight}px`;
740+
appRoot.style.maxHeight = `${availableHeight}px`;
741+
document.body.style.overflow = "hidden";
742+
document.documentElement.style.overflow = "hidden";
743+
}
744+
706745
wireSpinButton(button, axis, direction) {
707746
button.addEventListener("click", (event) => {
708747
const step = event.shiftKey ? 15 : 1;

0 commit comments

Comments
 (0)