--- layout: page title: Icon shapes subtitle: Pick a preset or draw your own shape, then send it to Murine permalink: /icon-shapes/ sitemap: false # keep it out of sitemap.xml noindex: true # and out of search engines ---
Edit mode: drag a point to move it, drag a + to add one. With a point selected, arrow keys nudge it, Delete removes it, Esc deselects. Ctrl+click (or long-press) more points to select several: they move, nudge and delete together. Tap a point to type its position or remove it; tap empty space to deselect. Long-press more points to select several: they move together.
Move mode: drag the shape, or a corner to resize it; click a corner to type its position. Arrow keys move the shape, Delete removes it.tap a corner to type its position. The first card, Global, moves, turns, resizes or flips the whole shape at once; its reset button takes that back.
Several shapes: Ctrl+click (or long-press) a shape or its card to move them together; Esc stops.long-press a shape or its card to move them together, then tap cards to add or remove more. Tap outside the group to stop.
Saving: the save button on a card keeps that shape (on Global, the whole shape) under Custom, above the editor and in Add a shape. It stays in this browser.
This shape has a fixed outline (ready-made or imported): you can move, resize, stretch and mirror it, but not edit its points. Generate replaces it with an editable one.
An edit link opens an icon in this editor. It's the editor's URL with the icon in its fragment, in one of two forms:
https://www.murinelauncher.app/icon-shapes/#edit=DATA: the icon's JSON (below), compressed with raw
DEFLATE (no zlib header or checksum: zlib.compressobj(9, zlib.DEFLATED, -15) in Python,
new CompressionStream('deflate-raw') in JavaScript), then base64url-encoded without = padding.
This is the preferred form: it's what Share produces and it keeps links short.https://www.murinelauncher.app/icon-shapes/#edit-raw=JSON: the same JSON, uncompressed and
percent-encoded (encodeURIComponent in JavaScript, urllib.parse.quote(json, safe='') in
Python). Use it when compressing isn't possible.Opening either one loads the icon (the previous one stays a step back in Undo); Share then gives the short link and the link that sends the shape to Murine. A link that doesn't follow the format below is ignored, and the editor keeps the icon it had.
A link written by hand or by a script is worth opening before it's shared: the canvas shows the shape, and anything the launcher can't use (shapes that don't touch, crossing edges) is reported in red under Result, which also disables Use in Murine. Other messages are just information: a corner whose size shrinks its neighbours, for instance, is fine if the shape looks as intended. Small fixes can be made right there. Share then has the finished links: the address of its Edit link entry is the compressed edit link (clicking the entry copies it), and Use in Murine points to the import link.
{"shapes": [
{"pts": [{"x": 50, "y": 4, "r": 12, "s": 0.6}, {"x": 97.6, "y": 38.5, "r": 12, "s": 0.6}, …],
"mirror": "none"}
]}
x grows to the right, y grows down, and
(0, 0) is the top-left corner. The launcher scales this box to the icon's size, so the shape should fill it
and stay inside it.shapes: 1 to 20 shapes. The icon is all of them together, so they must overlap or touch and make a single
outline; gaps they enclose are filled in.pts: the corners of one shape, 3 to 200, in order around it (either direction). Its edges must not cross
each other.r (optional, default 0): how far along each edge the corner's rounding reaches, in box units; 0 is a sharp
corner. Where edges are too short for it, it's reduced automatically (along with its neighbours'), which is fine
as long as the result looks right.s (optional, default 0): the rounding's profile, 0 to 1: 0 cuts the corner straight, 0.5 is a circular
arc, 1 is the smoothest (squircle-like).mirror (optional, default "none"): "h" adds a copy mirrored left to right
(around x = 50), "v" one mirrored top to bottom (around y = 50),
"both" three copies, one per quarter.A shape can also be an SVG outline instead of corners, for free-form curves. It can be mixed with corner shapes in the
same icon, and takes mirror too:
{"path": "M 50 0 C 77.6 0 100 22.4 100 50 C 100 77.6 77.6 100 50 100 C 22.4 100 0 77.6 0 50 C 0 22.4 22.4 0 50 0 Z"}
path: one closed outline in the same 100 × 100 box, written in a strict form: it starts with
M x y, continues with L x y (lines) and C x1 y1 x2 y2 x y (cubic curves) only,
and ends with Z; absolute coordinates, every command letter and number separated by a single space, no
commas. Other commands (relative ones, H/V, S, Q, A)
and holes or extra outlines aren't accepted, and the outline must not cross itself. To use an existing SVG file,
Add a shape → Import SVG converts it, and Share then gives the link.a, x, y (optional): the outline is drawn scaled by a (default 1)
and then moved by x, y (default 0).ang (optional, default 0): a turn in degrees, clockwise, around the outline's centre.Next to shapes, an optional whole transforms the icon as a whole, after its shapes are
merged (mirrored copies included), without changing them: {"shapes": [...], "whole": {"a": 0.9, "x": 5, "y": 5,
"ang": 30, "flip": true}}. In order: flip (optional, default false) turns the icon over left to
right within the 100 × 100 box; a (default 1) scales it and x, y (default 0)
move it; ang (default 0) turns it clockwise, in degrees, around the middle of where the box now is.
In the editor it's the Global card.
A rounded pentagon: {"shapes":[{"pts":[{"x":50,"y":4,"r":12,"s":0.6},{"x":97.6,"y":38.5,"r":12,"s":0.6},{"x":79.4,"y":94.5,"r":12,"s":0.6},{"x":20.6,"y":94.5,"r":12,"s":0.6},{"x":2.4,"y":38.5,"r":12,"s":0.6}]}]}