Skip to content

Commit 445259c

Browse files
authored
Streamline UI: remove welcome screen, brush types, and layer reordering buttons (#58)
- Remove welcome/home modal on startup; auto-create 16:9 project - Remove brush shape selector (circle only, simpler UX) - Remove layer up/down buttons; layer hierarchy is now fixed - Optimize lasso tool for mobile by removing dashed line and adding RAF throttling Users can still reorder color swatches within layers via drag on mobile/desktop.
1 parent 5f1609e commit 445259c

7 files changed

Lines changed: 15 additions & 236 deletions

File tree

celstomp/celstomp-app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,6 @@
17541754
wireEraserButtonRightClick();
17551755
wirePointerDrawingOnCanvas($("drawCanvas"));
17561756

1757-
openHomeModal();
1757+
startNewProject();
17581758
});
17591759
})();

celstomp/css/components/brushes.css

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -54,97 +54,6 @@
5454
display: none;
5555
}
5656

57-
#brushShapeSeg{
58-
display: grid;
59-
grid-template-columns: repeat(4, minmax(0, 1fr));
60-
gap: 6px;
61-
}
62-
63-
@media (max-width: 880px){
64-
#brushShapeSeg{
65-
grid-template-columns: repeat(3, minmax(0, 1fr));
66-
}
67-
}
68-
69-
@media (max-width: 720px){
70-
#brushShapeSeg{
71-
grid-template-columns: repeat(2, minmax(0, 1fr));
72-
}
73-
}
74-
75-
#brushShapeSeg > input{
76-
position: absolute;
77-
opacity: 0;
78-
pointer-events: none;
79-
}
80-
81-
#brushShapeSeg > label{
82-
height: 28px;
83-
border: 1px solid rgba(255,255,255,0.14);
84-
border-radius: 0;
85-
background: rgba(0,0,0,0.18);
86-
display: grid;
87-
place-items: center;
88-
cursor: pointer;
89-
}
90-
91-
#brushShapeSeg > label::before{
92-
content: "";
93-
width: 14px;
94-
height: 14px;
95-
border: 0;
96-
background: rgba(255,255,255,0.92);
97-
box-sizing: border-box;
98-
}
99-
100-
#brushShapeSeg > label[data-brush-shape="circle"]::before{
101-
border-radius: 50%;
102-
}
103-
104-
#brushShapeSeg > label[data-brush-shape="square"]::before{
105-
border-radius: 0;
106-
}
107-
108-
#brushShapeSeg > label[data-brush-shape="diamond"]::before{
109-
transform: rotate(45deg);
110-
}
111-
112-
#brushShapeSeg > label[data-brush-shape="oval-h"]::before{
113-
width: 16px;
114-
height: 10px;
115-
border-radius: 999px;
116-
}
117-
118-
#brushShapeSeg > label[data-brush-shape="oval-v"]::before{
119-
width: 10px;
120-
height: 16px;
121-
border-radius: 999px;
122-
}
123-
124-
#brushShapeSeg > label[data-brush-shape="rect-h"]::before{
125-
width: 16px;
126-
height: 8px;
127-
}
128-
129-
#brushShapeSeg > label[data-brush-shape="rect-v"]::before{
130-
width: 8px;
131-
height: 16px;
132-
}
133-
134-
#brushShapeSeg > label[data-brush-shape="triangle"]::before{
135-
background: transparent;
136-
width: 0;
137-
height: 0;
138-
border-left: 7px solid transparent;
139-
border-right: 7px solid transparent;
140-
border-bottom: 12px solid rgba(255,255,255,0.95);
141-
}
142-
143-
#brushShapeSeg > input:checked + label{
144-
outline: 2px solid rgba(120, 200, 255, 0.9);
145-
outline-offset: 0;
146-
}
147-
14857
.sideRangeRow{
14958
display: grid;
15059
gap: 4px;

celstomp/css/components/layers.css

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,38 +31,6 @@
3131
min-width: 0;
3232
}
3333

34-
#layerSeg .layerMoveControls{
35-
display: inline-flex;
36-
align-items: center;
37-
gap: 4px;
38-
margin-left: auto;
39-
}
40-
41-
#layerSeg .layerMoveBtn{
42-
width: 20px;
43-
height: 20px;
44-
padding: 0;
45-
border-radius: 6px;
46-
border: 1px solid rgba(255,255,255,0.12);
47-
background: rgba(255,255,255,0.06);
48-
color: #fff;
49-
display: inline-flex;
50-
align-items: center;
51-
justify-content: center;
52-
cursor: pointer;
53-
line-height: 1;
54-
font-size: 10px;
55-
}
56-
57-
#layerSeg .layerMoveBtn:disabled{
58-
opacity: 0.4;
59-
cursor: default;
60-
}
61-
62-
#layerSeg .layerMoveBtn:hover:not(:disabled){
63-
background: rgba(255,255,255,0.10);
64-
}
65-
6634
#layerSeg .layerSwatches{
6735
margin-left: 6px;
6836
display:flex;

celstomp/js/editor/layer-manager.js

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,6 @@ function closeLayerRowMenu() {
754754
}
755755

756756
const visBtnByLayer = new Map;
757-
const layerMoveCtrlsByLayer = new Map;
758757
function layerIsHidden(L) {
759758
if (L === PAPER_LAYER) return false;
760759
return (layers[L]?.opacity ?? 1) <= 0;
@@ -789,70 +788,6 @@ function applyLayerSegOrder() {
789788
seg.appendChild(row.label);
790789
}
791790
}
792-
function moveLayerInList(L, dir) {
793-
if (L === PAPER_LAYER) return;
794-
const ui = mainLayersTopToBottom();
795-
const idx = ui.indexOf(L);
796-
if (idx < 0) return;
797-
const next = idx + dir;
798-
if (next < 0 || next >= ui.length) return;
799-
[ ui[idx], ui[next] ] = [ ui[next], ui[idx] ];
800-
mainLayerOrder = normalizeMainLayerOrder(ui.slice().reverse());
801-
applyLayerSegOrder();
802-
wireLayerVisButtons();
803-
queueRenderAll();
804-
805-
// TODO: this throws a wrench in things
806-
// rearrange export logic st dirty logic precedes layer logic
807-
// markProjectDirty();
808-
}
809-
function updateLayerMoveButtons() {
810-
const ui = mainLayersTopToBottom();
811-
for (let i = 0; i < ui.length; i++) {
812-
const L = ui[i];
813-
const refs = layerMoveCtrlsByLayer.get(L);
814-
if (!refs) continue;
815-
refs.up.disabled = i === 0;
816-
refs.down.disabled = i === ui.length - 1;
817-
refs.up.title = refs.up.disabled ? "Already at top" : "Move layer up";
818-
refs.down.title = refs.down.disabled ? "Already at bottom" : "Move layer down";
819-
}
820-
}
821-
function ensureLayerMoveControls(label, L) {
822-
if (!label || L === PAPER_LAYER) return;
823-
const existing = label.querySelector(".layerMoveControls");
824-
if (existing) return;
825-
const wrap = document.createElement("span");
826-
wrap.className = "layerMoveControls";
827-
const up = document.createElement("button");
828-
up.type = "button";
829-
up.className = "layerMoveBtn";
830-
up.textContent = "▲";
831-
up.setAttribute("aria-label", "Move layer up");
832-
up.addEventListener("click", e => {
833-
e.preventDefault();
834-
e.stopPropagation();
835-
moveLayerInList(L, -1);
836-
});
837-
const down = document.createElement("button");
838-
down.type = "button";
839-
down.className = "layerMoveBtn";
840-
down.textContent = "▼";
841-
down.setAttribute("aria-label", "Move layer down");
842-
down.addEventListener("click", e => {
843-
e.preventDefault();
844-
e.stopPropagation();
845-
moveLayerInList(L, 1);
846-
});
847-
wrap.appendChild(up);
848-
wrap.appendChild(down);
849-
const sw = label.querySelector(".layerSwatches");
850-
if (sw) label.insertBefore(wrap, sw); else label.appendChild(wrap);
851-
layerMoveCtrlsByLayer.set(L, {
852-
up: up,
853-
down: down
854-
});
855-
}
856791
function injectVisBtn(radioId, L) {
857792
const input = $(radioId);
858793
if (!input) return;
@@ -861,7 +796,6 @@ function injectVisBtn(radioId, L) {
861796
const existing = label.querySelector(".visBtn");
862797
if (existing) {
863798
label.dataset.layerRow = String(L);
864-
ensureLayerMoveControls(label, L);
865799
visBtnByLayer.set(L, existing);
866800
updateVisBtn(L);
867801
return;
@@ -880,7 +814,6 @@ function injectVisBtn(radioId, L) {
880814
});
881815
label.insertBefore(btn, label.firstChild);
882816
label.dataset.layerRow = String(L);
883-
ensureLayerMoveControls(label, L);
884817
if (!label._opacityCtxWired) {
885818
label._opacityCtxWired = true;
886819
label.addEventListener("contextmenu", e => {
@@ -908,5 +841,4 @@ function wireLayerVisButtons() {
908841
updateVisBtn(LAYER.SHADE);
909842
updateVisBtn(LAYER.LINE);
910843
updateVisBtn(LAYER.SKETCH);
911-
updateLayerMoveButtons();
912844
}

celstomp/js/tools/lasso-helper.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
let lassoActive = false;
22
let lassoPts = [];
33
const lassoMinDist = 2.5;
4+
let _lassoPreviewScheduled = false;
5+
let _lassoLastPreviewMode = "fill";
46

57
function addLassoPoint(pt) {
68
const last = lassoPts[lassoPts.length - 1];
79
if (!last || Math.hypot(pt.x - last.x, pt.y - last.y) >= lassoMinDist) {
810
lassoPts.push(pt);
911
}
1012
}
13+
function scheduleLassoPreview(mode = "fill") {
14+
_lassoLastPreviewMode = mode;
15+
if (_lassoPreviewScheduled) return;
16+
_lassoPreviewScheduled = true;
17+
requestAnimationFrame(() => {
18+
_lassoPreviewScheduled = false;
19+
drawLassoPreviewImmediate(_lassoLastPreviewMode);
20+
});
21+
}
1122
function drawLassoPreview(mode = "fill") {
23+
scheduleLassoPreview(mode);
24+
}
25+
function drawLassoPreviewImmediate(mode = "fill") {
1226
const fxctx = getCanvas(CANVAS_TYPE.fxCanvas).getContext("2d");
1327
queueClearFx();
1428
if (lassoPts.length < 2) return;
@@ -26,7 +40,6 @@ function drawLassoPreview(mode = "fill") {
2640
}
2741
fxctx.globalAlpha = 1;
2842
fxctx.lineWidth = Math.max(1 / (getZoom() * dpr), .6);
29-
fxctx.setLineDash([ 10 / getZoom(), 7 / getZoom() ]);
3043
fxctx.strokeStyle = isErase ? "rgba(255,90,90,0.95)" : "rgba(255,255,255,0.95)";
3144
fxctx.beginPath();
3245
fxctx.moveTo(lassoPts[0].x, lassoPts[0].y);

celstomp/js/ui/ui-components.js

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,40 +45,6 @@
4545
toolContainer.replaceChildren(frag);
4646
}
4747

48-
const brushes = [
49-
{ id: 'shape-circle', val: 'circle', label: 'Circle', checked: true },
50-
{ id: 'shape-square', val: 'square', label: 'Square' },
51-
{ id: 'shape-diamond', val: 'diamond', label: 'Diamond' },
52-
{ id: 'shape-oval-h', val: 'oval-h', label: 'Horizontal oval' },
53-
{ id: 'shape-oval-v', val: 'oval-v', label: 'Vertical oval' },
54-
{ id: 'shape-rect-h', val: 'rect-h', label: 'Rectangle horizontal' },
55-
{ id: 'shape-rect-v', val: 'rect-v', label: 'Rectangle vertical' },
56-
{ id: 'shape-triangle', val: 'triangle', label: 'Triangle' }
57-
];
58-
const brushesContainer = document.getElementById('brushShapeSeg');
59-
if (brushesContainer) {
60-
const frag = document.createDocumentFragment();
61-
brushes.forEach(t => {
62-
const inp = document.createElement('input');
63-
inp.type = 'radio';
64-
inp.name = 'brushShape';
65-
inp.id = t.id;
66-
inp.value = t.val;
67-
inp.dataset.brushShape = t.val;
68-
if (t.checked) inp.checked = true;
69-
70-
const lbl = document.createElement('label');
71-
lbl.htmlFor = t.id;
72-
lbl.dataset.brushShape = t.val;
73-
lbl.setAttribute('aria-label', t.label);
74-
lbl.textContent = '';
75-
76-
frag.appendChild(inp);
77-
frag.appendChild(lbl);
78-
});
79-
brushesContainer.replaceChildren(frag);
80-
}
81-
8248
const layers = [
8349
{ id: 'bt-sketch-layer', val: 'sketch', label: 'SKETCH', swatchId: 'swatches-sketch' },
8450
{ id: 'bt-line', val: 'line', label: 'LINE', swatchId: 'swatches-line', checked: true },

celstomp/parts/sidepanel.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ document.getElementById('part-sidepanel').innerHTML = `
77
<div id="toolSettingsTitle" class="sideSectionTitle">Brushes</div>
88
</div>
99
10-
<section class="toolFold" data-fold="brushes">
11-
<button id="toolFoldBrushesBtn" class="toolFoldBtn" type="button" aria-expanded="true" aria-controls="toolFoldBrushesBody">Brushes</button>
12-
<div id="toolFoldBrushesBody" class="toolFoldBody">
13-
<div id="brushShapeSeg" class="brushShapeSeg" role="radiogroup" aria-label="Brush shape selector"></div>
14-
</div>
15-
</section>
16-
1710
<section class="toolFold" data-fold="settings">
1811
<button id="toolFoldSettingsBtn" class="toolFoldBtn" type="button" aria-expanded="true" aria-controls="toolFoldSettingsBody">Brush Settings</button>
1912
<div id="toolFoldSettingsBody" class="toolFoldBody">
@@ -41,8 +34,6 @@ document.getElementById('part-sidepanel').innerHTML = `
4134
</div>
4235
</section>
4336
44-
<div id="brushShapeTooltip" class="brushShapeTooltip" hidden></div>
45-
4637
<input id="eraserSize" type="hidden" value="100" />
4738
</section>
4839

0 commit comments

Comments
 (0)