Skip to content

Commit f21c540

Browse files
author
DavidQ
committed
Refine Sprite Editor fullscreen shell to compact top controls and full-height workspace
- update `tools/Sprite Editor/spriteEditor.css` - keep fullscreen toolbar/status container at content height (`auto`) instead of stretching - set fullscreen app shell layout to `grid-template-rows: auto minmax(0, 1fr)` with `height: calc(100dvh - 120px)` - ensure workspace can shrink/fill correctly with `min-height: 0` - result: top control area no longer appears overly tall; canvas/workspace gets remaining vertical space
1 parent 0041571 commit f21c540

3 files changed

Lines changed: 231 additions & 19 deletions

File tree

tools/Sprite Editor/index.html

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525
</div>
2626
</details>
2727
<div class="app-shell" id="appShell">
28-
<header class="app-header">
29-
<h1>Sprite Editor</h1>
30-
<p>Standalone pixel-art authoring editor for sprite documents and frame animation.</p>
31-
</header>
32-
3328
<section class="toolbar-row">
3429
<div class="toolbar-group tools-platform-control-cluster tools-platform-control-cluster--primary">
3530
<label>Width
@@ -57,18 +52,19 @@ <h1>Sprite Editor</h1>
5752
<button type="button" data-tool="eraser" class="tool-button">Eraser</button>
5853
<button type="button" data-tool="fill" class="tool-button">Fill</button>
5954
</div>
60-
</section>
6155

62-
<section class="state-row">
63-
<p id="toolStateText" class="state-pill">Tool: Pencil</p>
64-
<p id="activeColorText" class="state-pill">Color: #ff5a5aff</p>
65-
<p id="frameStateText" class="state-pill">Frame: 1 / 1</p>
66-
<p id="toggleStateText" class="state-pill">Grid: On | Onion: Off</p>
67-
<p id="statusBarText" class="state-pill">Canvas: 32x32 | Zoom: 18 | Cursor: -, -</p>
56+
<div class="state-row">
57+
<p id="toolStateText" class="state-pill">Tool: Pencil</p>
58+
<p id="activeColorText" class="state-pill">Color: #ff5a5aff</p>
59+
<p id="frameStateText" class="state-pill">Frame: 1 / 1</p>
60+
<p id="toggleStateText" class="state-pill">Grid: On | Onion: Off</p>
61+
<p id="statusBarText" class="state-pill">Canvas: 32x32 | Zoom: 18 | Cursor: -, -</p>
62+
</div>
6863
</section>
6964

7065
<section class="workspace tools-platform-layout-grid">
71-
<div class="left-panel tools-platform-resize-panel" data-panel-side="left">
66+
<div id="leftSidebar" class="left-panel tools-platform-resize-panel" data-panel-side="left">
67+
<button id="closeLeftOverlayButton" class="overlay-close-button" type="button" aria-label="Close Left Panel">X</button>
7268
<div class="panel-block">
7369
<h2>Colors</h2>
7470
<label>Palette Source (Engine)
@@ -106,7 +102,7 @@ <h2>Frames</h2>
106102
</label>
107103
</div>
108104

109-
<div class="panel-block">
105+
<div id="projectIoPanel" class="panel-block">
110106
<h2>Project I/O</h2>
111107
<div class="io-controls">
112108
<button id="saveAssetRegistryButton" type="button">Save Assets Registry</button>
@@ -130,12 +126,15 @@ <h2>Project I/O</h2>
130126
</div>
131127

132128
<div class="center-panel">
129+
<button id="showLeftPanelButton" class="fullscreen-overlay-button" type="button">Tools</button>
130+
<button id="showRightPanelButton" class="fullscreen-overlay-button" type="button">Status</button>
133131
<div class="canvas-wrap">
134132
<canvas id="editorCanvas" aria-label="Sprite drawing canvas"></canvas>
135133
</div>
136134
</div>
137135

138-
<div class="right-panel tools-platform-resize-panel" data-panel-side="right">
136+
<div id="rightSidebar" class="right-panel tools-platform-resize-panel" data-panel-side="right">
137+
<button id="closeRightOverlayButton" class="overlay-close-button" type="button" aria-label="Close Right Panel">X</button>
139138
<div class="panel-block">
140139
<h2>Preview</h2>
141140
<canvas id="previewCanvas" aria-label="Animation preview"></canvas>
@@ -150,7 +149,7 @@ <h2>Preview</h2>
150149
<output id="fpsValue">8</output>
151150
</div>
152151

153-
<div class="panel-block">
152+
<div id="statusPanel" class="panel-block">
154153
<h2>Status</h2>
155154
<p id="statusText" class="status-text">Ready.</p>
156155
<p id="remediationSummaryText" class="status-text">No remediation actions available.</p>

tools/Sprite Editor/main.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,63 @@ function bootSpriteEditor() {
2525
spriteEditorApp = initializeSpriteEditorApp();
2626
}
2727
window.spriteEditorApp = spriteEditorApi;
28+
setupFullscreenSidePanels();
2829
return spriteEditorApi;
2930
}
3031

32+
function setupFullscreenSidePanels() {
33+
const leftSidebar = document.getElementById("leftSidebar");
34+
const rightSidebar = document.getElementById("rightSidebar");
35+
const showLeftPanelButton = document.getElementById("showLeftPanelButton");
36+
const showRightPanelButton = document.getElementById("showRightPanelButton");
37+
const closeLeftOverlayButton = document.getElementById("closeLeftOverlayButton");
38+
const closeRightOverlayButton = document.getElementById("closeRightOverlayButton");
39+
40+
if (!leftSidebar || !rightSidebar || !showLeftPanelButton || !showRightPanelButton || !closeLeftOverlayButton || !closeRightOverlayButton) {
41+
return;
42+
}
43+
44+
const syncOverlayToggleButtons = () => {
45+
const leftVisible = leftSidebar.classList.contains("visible-overlay");
46+
const rightVisible = rightSidebar.classList.contains("visible-overlay");
47+
showLeftPanelButton.style.display = leftVisible ? "none" : "";
48+
showRightPanelButton.style.display = rightVisible ? "none" : "";
49+
};
50+
51+
const syncFullscreenClass = () => {
52+
const isFullscreen = Boolean(document.fullscreenElement);
53+
document.body.classList.toggle("fullscreen-mode", isFullscreen);
54+
if (!isFullscreen) {
55+
leftSidebar.classList.remove("visible-overlay");
56+
rightSidebar.classList.remove("visible-overlay");
57+
}
58+
syncOverlayToggleButtons();
59+
};
60+
61+
showLeftPanelButton.addEventListener("click", () => {
62+
leftSidebar.classList.toggle("visible-overlay");
63+
syncOverlayToggleButtons();
64+
});
65+
66+
showRightPanelButton.addEventListener("click", () => {
67+
rightSidebar.classList.toggle("visible-overlay");
68+
syncOverlayToggleButtons();
69+
});
70+
71+
closeLeftOverlayButton.addEventListener("click", () => {
72+
leftSidebar.classList.remove("visible-overlay");
73+
syncOverlayToggleButtons();
74+
});
75+
76+
closeRightOverlayButton.addEventListener("click", () => {
77+
rightSidebar.classList.remove("visible-overlay");
78+
syncOverlayToggleButtons();
79+
});
80+
81+
document.addEventListener("fullscreenchange", syncFullscreenClass);
82+
syncFullscreenClass();
83+
}
84+
3185
registerToolBootContract("sprite-editor", {
3286
init: bootSpriteEditor,
3387
destroy() {

tools/Sprite Editor/spriteEditor.css

Lines changed: 162 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,25 @@ spriteEditor.css
5656
.state-row {
5757
display: flex;
5858
flex-wrap: wrap;
59+
align-items: flex-start;
5960
gap: 0.45rem;
61+
width: 100%;
6062
border: 1px solid var(--se-panel-border);
6163
border-radius: 12px;
6264
padding: 0.6rem;
6365
background: color-mix(in srgb, var(--se-panel) 90%, black);
6466
}
6567

6668
.state-pill {
69+
flex: 0 0 auto;
6770
margin: 0;
6871
border: 1px solid var(--se-panel-border);
6972
border-radius: 999px;
7073
padding: 0.2rem 0.55rem;
7174
font-size: 0.82rem;
7275
color: var(--se-muted);
7376
background: var(--surface-inline, rgba(43, 16, 91, 0.9));
77+
white-space: nowrap;
7478
}
7579

7680
.toolbar-group {
@@ -106,6 +110,35 @@ spriteEditor.css
106110
background: color-mix(in srgb, var(--se-panel) 68%, var(--se-accent));
107111
}
108112

113+
.sprite-editor-page .fullscreen-overlay-button {
114+
display: none;
115+
position: fixed;
116+
z-index: 1200;
117+
min-height: 32px;
118+
padding: 0 12px;
119+
border: 1px solid var(--se-panel-border);
120+
border-radius: 999px;
121+
background: linear-gradient(180deg, var(--se-panel) 0%, color-mix(in srgb, var(--se-panel) 70%, var(--panel2, rgba(49, 17, 102, 0.94))) 100%);
122+
color: var(--se-text);
123+
font-weight: 600;
124+
}
125+
126+
.sprite-editor-page .overlay-close-button {
127+
display: none;
128+
position: absolute;
129+
top: 5px;
130+
right: 5px;
131+
z-index: 1300;
132+
min-height: 28px;
133+
min-width: 28px;
134+
padding: 0 8px;
135+
border-radius: 999px;
136+
border: 1px solid var(--se-panel-border);
137+
background: #ed9700;
138+
color: #ffffff;
139+
font-weight: 700;
140+
}
141+
109142
.workspace {
110143
display: grid;
111144
grid-template-columns: 260px minmax(0, 1fr) 440px;
@@ -150,19 +183,20 @@ spriteEditor.css
150183
border-radius: 12px;
151184
background: var(--surface-inline, rgba(43, 16, 91, 0.9));
152185
display: grid;
153-
justify-items: center;
154-
align-items: start;
186+
justify-items: stretch;
187+
align-items: stretch;
155188
padding: 0.9rem;
156189
overflow: auto;
157190
}
158191

159192
.canvas-wrap {
193+
width: 100%;
160194
border: 1px solid var(--se-panel-border);
161195
border-radius: 10px;
162196
background: linear-gradient(45deg, var(--se-canvas-bg-a) 25%, var(--se-canvas-bg-b) 25%, var(--se-canvas-bg-b) 50%, var(--se-canvas-bg-a) 50%, var(--se-canvas-bg-a) 75%, var(--se-canvas-bg-b) 75%, var(--se-canvas-bg-b) 100%);
163197
background-size: 20px 20px;
164198
padding: 0.5rem;
165-
margin-top: 20px;
199+
margin-top: 0;
166200
}
167201

168202
#editorCanvas {
@@ -247,6 +281,131 @@ spriteEditor.css
247281
color: var(--se-muted);
248282
}
249283

284+
#statusPanel {
285+
height: 530px;
286+
overflow-y: auto;
287+
overflow-x: hidden;
288+
}
289+
290+
#statusPanel pre.status-text {
291+
white-space: pre-wrap;
292+
word-break: break-word;
293+
}
294+
295+
#projectIoPanel {
296+
resize: none;
297+
}
298+
299+
body[data-tool-id="sprite-editor"] .tools-platform-resize-panel {
300+
resize: none;
301+
}
302+
303+
body.sprite-editor-page.fullscreen-mode .left-panel,
304+
body.sprite-editor-page.fullscreen-mode .right-panel {
305+
position: fixed;
306+
top: 96px;
307+
bottom: 72px;
308+
width: min(360px, 40vw);
309+
max-width: min(360px, 40vw);
310+
overflow: auto;
311+
z-index: 1250;
312+
margin: 0;
313+
border-radius: 12px;
314+
box-shadow: 0 18px 36px rgba(0, 0, 0, 0.28);
315+
transform: translateX(-120%);
316+
transition: transform 140ms ease;
317+
}
318+
319+
body.sprite-editor-page.fullscreen-mode .right-panel {
320+
transform: translateX(120%);
321+
}
322+
323+
body.sprite-editor-page.fullscreen-mode .workspace {
324+
grid-template-columns: minmax(0, 1fr);
325+
min-height: 0;
326+
}
327+
328+
body.sprite-editor-page.fullscreen-mode .toolbar-row {
329+
align-items: center;
330+
align-content: flex-start;
331+
gap: 0.45rem;
332+
padding: 0.45rem 0.55rem;
333+
min-height: 0;
334+
height: auto;
335+
}
336+
337+
body.sprite-editor-page.fullscreen-mode .state-row {
338+
flex-wrap: nowrap;
339+
align-items: center;
340+
gap: 0.28rem;
341+
padding: 0.25rem 0.35rem;
342+
overflow-x: auto;
343+
overflow-y: hidden;
344+
margin: 0;
345+
}
346+
347+
body.sprite-editor-page.fullscreen-mode .app-shell {
348+
height: calc(100dvh - 120px);
349+
grid-template-rows: auto minmax(0, 1fr);
350+
align-content: start;
351+
}
352+
353+
body.sprite-editor-page.fullscreen-mode .state-pill {
354+
padding: 0.15rem 0.45rem;
355+
font-size: 0.78rem;
356+
}
357+
358+
body.sprite-editor-page.fullscreen-mode .center-panel {
359+
width: 100%;
360+
min-width: 0;
361+
}
362+
363+
body.sprite-editor-page.fullscreen-mode .left-panel,
364+
body.sprite-editor-page.fullscreen-mode .right-panel {
365+
display: none;
366+
}
367+
368+
body.sprite-editor-page.fullscreen-mode .left-panel.visible-overlay,
369+
body.sprite-editor-page.fullscreen-mode .right-panel.visible-overlay {
370+
display: grid;
371+
}
372+
373+
body.sprite-editor-page.fullscreen-mode .left-panel {
374+
left: 10px;
375+
}
376+
377+
body.sprite-editor-page.fullscreen-mode .right-panel {
378+
right: 10px;
379+
}
380+
381+
body.sprite-editor-page.fullscreen-mode .left-panel.visible-overlay,
382+
body.sprite-editor-page.fullscreen-mode .right-panel.visible-overlay {
383+
transform: translateX(0);
384+
}
385+
386+
body.sprite-editor-page.fullscreen-mode .left-panel.visible-overlay .overlay-close-button,
387+
body.sprite-editor-page.fullscreen-mode .right-panel.visible-overlay .overlay-close-button {
388+
display: inline-flex;
389+
align-items: center;
390+
justify-content: center;
391+
}
392+
393+
body.sprite-editor-page.fullscreen-mode .fullscreen-overlay-button {
394+
display: inline-flex;
395+
align-items: center;
396+
justify-content: center;
397+
}
398+
399+
body.sprite-editor-page.fullscreen-mode #showLeftPanelButton {
400+
top: 152px;
401+
left: 14px;
402+
}
403+
404+
body.sprite-editor-page.fullscreen-mode #showRightPanelButton {
405+
top: 152px;
406+
right: 14px;
407+
}
408+
250409
button,
251410
input,
252411
output {

0 commit comments

Comments
 (0)