Skip to content

Charming Path

Charming Path builds SVG d path strings from numbers—handy for <path>, getPointAtLength, or APIs such as layoutTextInPath that expect a path description. Shapes are axis-aligned in user space (no rotation in the path itself).

js
(() => {
  const d = cm.pathCircle(100, 100, 80);
  return cm.svg`<svg ${{width: 200, height: 200}}>
    <path ${{fill: "none", stroke: "black", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathCircle(100, 100, 80);

cm.svg`<svg ${{width: 200, height: 200}}>
  <path ${{fill: "none", stroke: "black", stroke_width: 2, d}} />
</svg>`;

cm.pathLine(x1, y1, x2, y2)

Returns an open path: M to (x1, y1), L to (x2, y2).

js
(() => {
  const d = cm.pathLine(10, 90, 90, 10);
  return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
    <path ${{fill: "none", stroke: "steelblue", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathLine(10, 90, 90, 10);

cm.pathCircle(cx, cy, r)

Returns a closed circle centered at (cx, cy) with radius r, using two arc segments.

js
(() => {
  const d = cm.pathCircle(50, 50, 40);
  return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
    <path ${{fill: "none", stroke: "teal", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathCircle(100, 100, 50);

cm.pathRect(x, y, width, height)

Returns a closed rectangle with top-left (x, y) and size width × height.

js
(() => {
  const d = cm.pathRect(15, 25, 70, 50);
  return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
    <path ${{fill: "none", stroke: "purple", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathRect(0, 0, 100, 50);

cm.pathEllipse(cx, cy, rx, ry)

Returns a closed axis-aligned ellipse centered at (cx, cy) with radii rx and ry, using two elliptical arcs.

js
(() => {
  const d = cm.pathEllipse(50, 50, 42, 28);
  return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
    <path ${{fill: "none", stroke: "coral", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathEllipse(100, 100, 60, 40);

cm.pathPolygon(points)

Returns a closed path through points, an array of [x, y] pairs. The first point is moved to with M; later points use L; the path ends with Z.

js
(() => {
  const d = cm.pathPolygon([
    [50, 10],
    [90, 90],
    [10, 90],
  ]);
  return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
    <path ${{fill: "none", stroke: "darkgreen", stroke_width: 2, d}} />
  </svg>`;
})();
js
const d = cm.pathPolygon([
  [0, 0],
  [100, 0],
  [50, 80],
]);