diff --git a/celstomp/celstomp-app.js b/celstomp/celstomp-app.js index 3d924b6..4dceab8 100644 --- a/celstomp/celstomp-app.js +++ b/celstomp/celstomp-app.js @@ -1736,6 +1736,6 @@ wireEraserButtonRightClick(); wirePointerDrawingOnCanvas($("drawCanvas")); - openHomeModal(); + startNewProject(); }); })(); diff --git a/celstomp/css/components/brushes.css b/celstomp/css/components/brushes.css index 3709bbf..09cd4c7 100644 --- a/celstomp/css/components/brushes.css +++ b/celstomp/css/components/brushes.css @@ -54,97 +54,6 @@ display: none; } -#brushShapeSeg{ - display: grid; - grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: 6px; -} - -@media (max-width: 880px){ - #brushShapeSeg{ - grid-template-columns: repeat(3, minmax(0, 1fr)); - } -} - -@media (max-width: 720px){ - #brushShapeSeg{ - grid-template-columns: repeat(2, minmax(0, 1fr)); - } -} - -#brushShapeSeg > input{ - position: absolute; - opacity: 0; - pointer-events: none; -} - -#brushShapeSeg > label{ - height: 28px; - border: 1px solid rgba(255,255,255,0.14); - border-radius: 0; - background: rgba(0,0,0,0.18); - display: grid; - place-items: center; - cursor: pointer; -} - -#brushShapeSeg > label::before{ - content: ""; - width: 14px; - height: 14px; - border: 0; - background: rgba(255,255,255,0.92); - box-sizing: border-box; -} - -#brushShapeSeg > label[data-brush-shape="circle"]::before{ - border-radius: 50%; -} - -#brushShapeSeg > label[data-brush-shape="square"]::before{ - border-radius: 0; -} - -#brushShapeSeg > label[data-brush-shape="diamond"]::before{ - transform: rotate(45deg); -} - -#brushShapeSeg > label[data-brush-shape="oval-h"]::before{ - width: 16px; - height: 10px; - border-radius: 999px; -} - -#brushShapeSeg > label[data-brush-shape="oval-v"]::before{ - width: 10px; - height: 16px; - border-radius: 999px; -} - -#brushShapeSeg > label[data-brush-shape="rect-h"]::before{ - width: 16px; - height: 8px; -} - -#brushShapeSeg > label[data-brush-shape="rect-v"]::before{ - width: 8px; - height: 16px; -} - -#brushShapeSeg > label[data-brush-shape="triangle"]::before{ - background: transparent; - width: 0; - height: 0; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 12px solid rgba(255,255,255,0.95); -} - -#brushShapeSeg > input:checked + label{ - outline: 2px solid rgba(120, 200, 255, 0.9); - outline-offset: 0; -} - .sideRangeRow{ display: grid; gap: 4px; diff --git a/celstomp/css/components/layers.css b/celstomp/css/components/layers.css index 7e95989..9396b0d 100644 --- a/celstomp/css/components/layers.css +++ b/celstomp/css/components/layers.css @@ -31,38 +31,6 @@ min-width: 0; } -#layerSeg .layerMoveControls{ - display: inline-flex; - align-items: center; - gap: 4px; - margin-left: auto; -} - -#layerSeg .layerMoveBtn{ - width: 20px; - height: 20px; - padding: 0; - border-radius: 6px; - border: 1px solid rgba(255,255,255,0.12); - background: rgba(255,255,255,0.06); - color: #fff; - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; - line-height: 1; - font-size: 10px; -} - -#layerSeg .layerMoveBtn:disabled{ - opacity: 0.4; - cursor: default; -} - -#layerSeg .layerMoveBtn:hover:not(:disabled){ - background: rgba(255,255,255,0.10); -} - #layerSeg .layerSwatches{ margin-left: 6px; display:flex; diff --git a/celstomp/js/editor/layer-manager.js b/celstomp/js/editor/layer-manager.js index de9eef5..9644e9d 100644 --- a/celstomp/js/editor/layer-manager.js +++ b/celstomp/js/editor/layer-manager.js @@ -754,7 +754,6 @@ function closeLayerRowMenu() { } const visBtnByLayer = new Map; -const layerMoveCtrlsByLayer = new Map; function layerIsHidden(L) { if (L === PAPER_LAYER) return false; return (layers[L]?.opacity ?? 1) <= 0; @@ -789,70 +788,6 @@ function applyLayerSegOrder() { seg.appendChild(row.label); } } -function moveLayerInList(L, dir) { - if (L === PAPER_LAYER) return; - const ui = mainLayersTopToBottom(); - const idx = ui.indexOf(L); - if (idx < 0) return; - const next = idx + dir; - if (next < 0 || next >= ui.length) return; - [ ui[idx], ui[next] ] = [ ui[next], ui[idx] ]; - mainLayerOrder = normalizeMainLayerOrder(ui.slice().reverse()); - applyLayerSegOrder(); - wireLayerVisButtons(); - queueRenderAll(); - - // TODO: this throws a wrench in things - // rearrange export logic st dirty logic precedes layer logic - // markProjectDirty(); -} -function updateLayerMoveButtons() { - const ui = mainLayersTopToBottom(); - for (let i = 0; i < ui.length; i++) { - const L = ui[i]; - const refs = layerMoveCtrlsByLayer.get(L); - if (!refs) continue; - refs.up.disabled = i === 0; - refs.down.disabled = i === ui.length - 1; - refs.up.title = refs.up.disabled ? "Already at top" : "Move layer up"; - refs.down.title = refs.down.disabled ? "Already at bottom" : "Move layer down"; - } -} -function ensureLayerMoveControls(label, L) { - if (!label || L === PAPER_LAYER) return; - const existing = label.querySelector(".layerMoveControls"); - if (existing) return; - const wrap = document.createElement("span"); - wrap.className = "layerMoveControls"; - const up = document.createElement("button"); - up.type = "button"; - up.className = "layerMoveBtn"; - up.textContent = "▲"; - up.setAttribute("aria-label", "Move layer up"); - up.addEventListener("click", e => { - e.preventDefault(); - e.stopPropagation(); - moveLayerInList(L, -1); - }); - const down = document.createElement("button"); - down.type = "button"; - down.className = "layerMoveBtn"; - down.textContent = "▼"; - down.setAttribute("aria-label", "Move layer down"); - down.addEventListener("click", e => { - e.preventDefault(); - e.stopPropagation(); - moveLayerInList(L, 1); - }); - wrap.appendChild(up); - wrap.appendChild(down); - const sw = label.querySelector(".layerSwatches"); - if (sw) label.insertBefore(wrap, sw); else label.appendChild(wrap); - layerMoveCtrlsByLayer.set(L, { - up: up, - down: down - }); -} function injectVisBtn(radioId, L) { const input = $(radioId); if (!input) return; @@ -861,7 +796,6 @@ function injectVisBtn(radioId, L) { const existing = label.querySelector(".visBtn"); if (existing) { label.dataset.layerRow = String(L); - ensureLayerMoveControls(label, L); visBtnByLayer.set(L, existing); updateVisBtn(L); return; @@ -880,7 +814,6 @@ function injectVisBtn(radioId, L) { }); label.insertBefore(btn, label.firstChild); label.dataset.layerRow = String(L); - ensureLayerMoveControls(label, L); if (!label._opacityCtxWired) { label._opacityCtxWired = true; label.addEventListener("contextmenu", e => { @@ -908,5 +841,4 @@ function wireLayerVisButtons() { updateVisBtn(LAYER.SHADE); updateVisBtn(LAYER.LINE); updateVisBtn(LAYER.SKETCH); - updateLayerMoveButtons(); } diff --git a/celstomp/js/tools/lasso-helper.js b/celstomp/js/tools/lasso-helper.js index 03ab150..b88f252 100644 --- a/celstomp/js/tools/lasso-helper.js +++ b/celstomp/js/tools/lasso-helper.js @@ -1,6 +1,8 @@ let lassoActive = false; let lassoPts = []; const lassoMinDist = 2.5; +let _lassoPreviewScheduled = false; +let _lassoLastPreviewMode = "fill"; function addLassoPoint(pt) { const last = lassoPts[lassoPts.length - 1]; @@ -8,7 +10,19 @@ function addLassoPoint(pt) { lassoPts.push(pt); } } +function scheduleLassoPreview(mode = "fill") { + _lassoLastPreviewMode = mode; + if (_lassoPreviewScheduled) return; + _lassoPreviewScheduled = true; + requestAnimationFrame(() => { + _lassoPreviewScheduled = false; + drawLassoPreviewImmediate(_lassoLastPreviewMode); + }); +} function drawLassoPreview(mode = "fill") { + scheduleLassoPreview(mode); +} +function drawLassoPreviewImmediate(mode = "fill") { const fxctx = getCanvas(CANVAS_TYPE.fxCanvas).getContext("2d"); queueClearFx(); if (lassoPts.length < 2) return; @@ -26,7 +40,6 @@ function drawLassoPreview(mode = "fill") { } fxctx.globalAlpha = 1; fxctx.lineWidth = Math.max(1 / (getZoom() * dpr), .6); - fxctx.setLineDash([ 10 / getZoom(), 7 / getZoom() ]); fxctx.strokeStyle = isErase ? "rgba(255,90,90,0.95)" : "rgba(255,255,255,0.95)"; fxctx.beginPath(); fxctx.moveTo(lassoPts[0].x, lassoPts[0].y); diff --git a/celstomp/js/ui/ui-components.js b/celstomp/js/ui/ui-components.js index 3614e29..972d3da 100644 --- a/celstomp/js/ui/ui-components.js +++ b/celstomp/js/ui/ui-components.js @@ -38,40 +38,6 @@ toolContainer.replaceChildren(frag); } - const brushes = [ - { id: 'shape-circle', val: 'circle', label: 'Circle', checked: true }, - { id: 'shape-square', val: 'square', label: 'Square' }, - { id: 'shape-diamond', val: 'diamond', label: 'Diamond' }, - { id: 'shape-oval-h', val: 'oval-h', label: 'Horizontal oval' }, - { id: 'shape-oval-v', val: 'oval-v', label: 'Vertical oval' }, - { id: 'shape-rect-h', val: 'rect-h', label: 'Rectangle horizontal' }, - { id: 'shape-rect-v', val: 'rect-v', label: 'Rectangle vertical' }, - { id: 'shape-triangle', val: 'triangle', label: 'Triangle' } - ]; - const brushesContainer = document.getElementById('brushShapeSeg'); - if (brushesContainer) { - const frag = document.createDocumentFragment(); - brushes.forEach(t => { - const inp = document.createElement('input'); - inp.type = 'radio'; - inp.name = 'brushShape'; - inp.id = t.id; - inp.value = t.val; - inp.dataset.brushShape = t.val; - if (t.checked) inp.checked = true; - - const lbl = document.createElement('label'); - lbl.htmlFor = t.id; - lbl.dataset.brushShape = t.val; - lbl.setAttribute('aria-label', t.label); - lbl.textContent = ''; - - frag.appendChild(inp); - frag.appendChild(lbl); - }); - brushesContainer.replaceChildren(frag); - } - const layers = [ { id: 'bt-sketch-layer', val: 'sketch', label: 'SKETCH', swatchId: 'swatches-sketch' }, { id: 'bt-line', val: 'line', label: 'LINE', swatchId: 'swatches-line', checked: true }, diff --git a/celstomp/parts/sidepanel.js b/celstomp/parts/sidepanel.js index 7bfda81..158eeb9 100644 --- a/celstomp/parts/sidepanel.js +++ b/celstomp/parts/sidepanel.js @@ -7,13 +7,6 @@ document.getElementById('part-sidepanel').innerHTML = `
Brushes
-
- -
-
-
-
-
@@ -41,8 +34,6 @@ document.getElementById('part-sidepanel').innerHTML = `
- -