mirror of
https://github.com/alesimula/Murine-launcher.git
synced 2026-10-28 09:43:42 +00:00
WEBSITE - WIP - icon shapes - better shape colors + point del button
This commit is contained in:
1 parent
28bc4b3911
commit
e5623ed823
2 files changed
+28
-8
No files matched your search
@@ -347,8 +347,7 @@
|
||||
const crossed = shapes.findIndex((sh) => sh.pts && selfIntersects(sh.pts));
|
||||
const bad = !!out.error || crossed >= 0;
|
||||
|
||||
// The merged icon is filled; every shape and mirrored copy is outlined on top, the selected one solid.
|
||||
$('se-merged').setAttribute('d', out.d);
|
||||
// Each shape and mirrored copy is filled and outlined on its own; the selected one is drawn last, on top.
|
||||
const order = shapes.map((_, i) => i).filter((i) => i !== active).concat(active); // selected shape on top
|
||||
const strokes = order.flatMap((i) => lines[i].map((d, c) => ({ d, cls: 'se-line' + (i === active ? ' active' : '') + (c ? ' copy' : '') })));
|
||||
const layer = $('se-lines');
|
||||
@@ -567,7 +566,8 @@
|
||||
drag = { kind: 'resize', anchor, d0: dist(anchor, c[g.resize]), orig: shapes[active] };
|
||||
}
|
||||
svg.setPointerCapture(e.pointerId);
|
||||
e.preventDefault();
|
||||
e.preventDefault(); // this also stops the browser focusing the canvas, so do it here:
|
||||
svg.focus({ preventScroll: true }); // Delete, arrows and Esc then act on what was just grabbed
|
||||
render();
|
||||
});
|
||||
svg.addEventListener('pointermove', (e) => {
|
||||
@@ -595,6 +595,13 @@
|
||||
if (h && +h.dataset.i !== sel) { sel = +h.dataset.i; render(); }
|
||||
});
|
||||
|
||||
// A shape can't go below 3 points: shake the canvas rather than silently ignore the key.
|
||||
const shake = () => {
|
||||
const stage = svg.parentElement;
|
||||
stage.classList.remove('se-shake');
|
||||
void stage.offsetWidth; // restarts the animation when pressed again mid-shake
|
||||
stage.classList.add('se-shake');
|
||||
};
|
||||
document.addEventListener('keydown', (e) => {
|
||||
const key = e.key.toLowerCase();
|
||||
if ((e.ctrlKey || e.metaKey) && !e.altKey && (key === 'z' || key === 'y')) {
|
||||
@@ -602,7 +609,13 @@
|
||||
e.preventDefault();
|
||||
return (key === 'y' || e.shiftKey ? $('se-redo') : $('se-undo')).click(); // Ctrl+Y, or Ctrl/Cmd+Shift+Z
|
||||
}
|
||||
if (!svg.contains(document.activeElement)) return;
|
||||
// Delete, Backspace and Esc act on the selected point wherever the focus is (say, on its Size slider),
|
||||
// unless you're typing in a field or a dialog is open. Arrows still need the canvas focused, so elsewhere
|
||||
// they keep moving sliders and scrolling the page.
|
||||
const typing = e.target.matches('input:not([type=range]):not([type=checkbox]), textarea, select');
|
||||
const pointKey = sel >= 0 && mode === 'edit' && ['Delete', 'Backspace', 'Escape'].includes(e.key)
|
||||
&& !typing && !e.target.closest('.contact-modal-overlay');
|
||||
if (!pointKey && !svg.contains(document.activeElement)) return;
|
||||
const step = grid.snap ? grid.step : e.shiftKey ? 5 : 0.5;
|
||||
const mv = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] }[e.key];
|
||||
if (mode === 'move') { // arrows move the whole shape
|
||||
@@ -616,7 +629,7 @@
|
||||
pts[sel].x = snap(pts[sel].x + mv[0] * step);
|
||||
pts[sel].y = snap(pts[sel].y + mv[1] * step);
|
||||
} else if (e.key === 'Delete' || e.key === 'Backspace') {
|
||||
if (pts.length <= 3) return;
|
||||
if (pts.length <= 3) return shake();
|
||||
checkpoint();
|
||||
pts.splice(sel, 1);
|
||||
sel = Math.min(sel, pts.length - 1);
|
||||
|
||||
+10
-3
@@ -26,8 +26,13 @@ noindex: true # and out of search engines
|
||||
.se-grid-line { stroke: var(--md-outline-variant); stroke-width: .15; }
|
||||
.se-grid-mid { stroke: var(--md-outline); stroke-width: .25; }
|
||||
.se-bounds { fill: none; stroke: var(--md-outline); stroke-width: .35; stroke-dasharray: 1.5 1; }
|
||||
.se-merged { fill: var(--md-primary-container); fill-opacity: .85; }
|
||||
.se-line { fill: none; stroke: var(--md-outline); stroke-width: .35; stroke-dasharray: 1.2 1; }
|
||||
/* Every shape is filled on its own: the others softly and behind, the selected one stronger and on top. */
|
||||
.se-stage { --se-fill-active: color-mix(in srgb, var(--md-primary) 50%, transparent);
|
||||
--se-fill-other: color-mix(in srgb, var(--md-primary-container) 85%, transparent); }
|
||||
[data-theme="dark"] .se-stage { --se-fill-active: color-mix(in srgb, var(--md-primary-container) 85%, transparent);
|
||||
--se-fill-other: color-mix(in srgb, var(--md-primary-container) 30%, transparent); }
|
||||
.se-line { fill: var(--se-fill-other); stroke: var(--md-outline); stroke-width: .35; stroke-dasharray: 1.2 1; }
|
||||
.se-line.active { fill: var(--se-fill-active); }
|
||||
.se-line.copy { stroke-dasharray: .4 .8; }
|
||||
.se-line.active { stroke: var(--md-primary); stroke-width: .5; stroke-dasharray: none; }
|
||||
.se-line.active.copy { stroke-width: .35; stroke-dasharray: 1.2 1; }
|
||||
@@ -101,6 +106,9 @@ noindex: true # and out of search engines
|
||||
/* Canvas overlay (Move mode): fit this shape top right, mirroring bottom left. */
|
||||
.se-left { min-width: 0; }
|
||||
.se-stage { position: relative; }
|
||||
.se-shake { animation: se-shake .35s; }
|
||||
@keyframes se-shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }
|
||||
@media (prefers-reduced-motion: reduce) { .se-shake { animation: none; } }
|
||||
.se-stage-btn, .se-mirror button { display: inline-flex; align-items: center; justify-content: center; padding: 0;
|
||||
border-radius: var(--md-shape-full); color: var(--md-primary); cursor: pointer; }
|
||||
.se-stage-btn { position: absolute; top: 10px; right: 10px; width: 40px; height: 40px;
|
||||
@@ -159,7 +167,6 @@ noindex: true # and out of search engines
|
||||
<svg id="se-canvas" viewBox="-20 -20 140 140" tabindex="0" aria-label="Shape editor. In Edit mode drag points to move them and the plus marks to add points; in Move mode drag the shape or its corners.">
|
||||
<g id="se-grid"></g>
|
||||
<rect class="se-bounds" x="0" y="0" width="100" height="100"/>
|
||||
<path id="se-merged" class="se-merged"/>
|
||||
<g id="se-lines"></g>
|
||||
<polygon id="se-outline" class="se-outline"/>
|
||||
<g id="se-adders"></g>
|
||||
|
||||
Reference in new issue
Block a user