From 739de10e6bab61df692a7a678aefeb2cad8e2a61 Mon Sep 17 00:00:00 2001 From: pearmini Date: Fri, 3 Apr 2026 13:57:09 -0400 Subject: [PATCH 1/4] Update Charming Canvas --- docs/api-index.md | 1 + docs/canvas.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/api-index.md b/docs/api-index.md index 4863559..fb122d2 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -4,6 +4,7 @@ - [_cm_.**html**](/dom#cm-html) — HTML via tagged template literal. - [_cm_.**attr**](/dom#cm-attr) — get, set, or remove attributes (including styles and events) on a node. - [_cm_.**context2d**](/canvas#cm-context2d) — create a 2D canvas rendering context (size, DPR, optional container). +- [_cm_.**cssFont**](/canvas#cm-css-font) — build a CSS `font` shorthand string (canvas, DOM, or D3). - [_cm_.**strokeLine**](/canvas#cm-stroke-line) — stroke a line between two points. - [_cm_.**fillCircle**](/canvas#cm-fill-circle) — fill a circle. - [_cm_.**strokeCircle**](/canvas#cm-stroke-circle) — stroke a circle. diff --git a/docs/canvas.md b/docs/canvas.md index 980f6fc..a1f11b2 100644 --- a/docs/canvas.md +++ b/docs/canvas.md @@ -71,6 +71,44 @@ context.arc(50, 50, 25, 0, Math.PI * 2); context.fill(); ``` +## _cm_.cssFont(_options_) {#cm-css-font} + +Returns a **CSS `font` shorthand** string suitable for `CanvasRenderingContext2D#font`, DOM `element.style.font`, or libraries that accept a font string (for example D3’s `.style("font", …)`). + +Options (all optional): + +- **fontStyle** — default `"normal"`. +- **fontVariant** — default `"normal"`. +- **fontWeight** — default `"normal"`. +- **fontSize** — default `10`; may be a number (interpreted as pixels) or a string with units, e.g. `"1.2rem"`. +- **fontFamily** — default `"sans-serif"`. + +Extra keys on the options object are ignored. The result has normalized spacing. + +```js eval code=false +(() => { + const context = cm.context2d({width: 220, height: 56}); + context.fillStyle = "orange"; + context.fillRect(0, 0, 220, 56); + context.fillStyle = "#222"; + context.font = cm.cssFont({fontSize: 22, fontFamily: "Georgia, serif"}); + context.textBaseline = "middle"; + context.fillText("Hello Canvas!", 12, 28); + return context.canvas; +})(); +``` + +```js +const context = cm.context2d({width: 220, height: 56}); +context.font = cm.cssFont({ + fontStyle: "italic", + fontWeight: "700", + fontSize: 18, + fontFamily: "system-ui, sans-serif", +}); +context.fillText("Hello Canvas!", 10, 30); +``` + ## _cm_.strokeLine(_context_, _x1_, _y1_, _x2_, _y2_) {#cm-stroke-line} Strokes from (_x1_, _y1_) to (_x2_, _y2_) using the current stroke style and line width. From e281d85d29b1429098ab8a55791552334afd5a57 Mon Sep 17 00:00:00 2001 From: pearmini Date: Fri, 3 Apr 2026 14:01:31 -0400 Subject: [PATCH 2/4] Update API index --- docs/api-index.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api-index.md b/docs/api-index.md index fb122d2..296185e 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -1,8 +1,13 @@ # API Index +## [Charming DOM](/dom) + - [_cm_.**svg**](/dom#cm-svg) — SVG via tagged template literal. - [_cm_.**html**](/dom#cm-html) — HTML via tagged template literal. - [_cm_.**attr**](/dom#cm-attr) — get, set, or remove attributes (including styles and events) on a node. + +## [Charming Canvas](/canvas) + - [_cm_.**context2d**](/canvas#cm-context2d) — create a 2D canvas rendering context (size, DPR, optional container). - [_cm_.**cssFont**](/canvas#cm-css-font) — build a CSS `font` shorthand string (canvas, DOM, or D3). - [_cm_.**strokeLine**](/canvas#cm-stroke-line) — stroke a line between two points. From d86c2f081f2f68c06ba5ca599596207ad84e17ab Mon Sep 17 00:00:00 2001 From: pearmini Date: Fri, 3 Apr 2026 14:12:07 -0400 Subject: [PATCH 3/4] Add docs for charming path --- docs/.vitepress/config.mjs | 4 ++ docs/api-index.md | 8 +++ docs/path.md | 113 +++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 docs/path.md diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index cfb7a52..91ea229 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -55,6 +55,10 @@ export default defineConfig({ text: "Charming Canvas", link: "/canvas", }, + { + text: "Charming Path", + link: "/path", + }, ], }, ], diff --git a/docs/api-index.md b/docs/api-index.md index 296185e..1cab3b1 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -15,3 +15,11 @@ - [_cm_.**strokeCircle**](/canvas#cm-stroke-circle) — stroke a circle. - [_cm_.**strokeEllipse**](/canvas#cm-stroke-ellipse) — stroke an axis-aligned ellipse. - [_cm_.**fillEllipse**](/canvas#cm-fill-ellipse) — fill an axis-aligned ellipse. + +## [Charming Path](/path) + +- [_cm_.**pathLine**](/path#cm-path-line) — open segment `M` … `L` … +- [_cm_.**pathCircle**](/path#cm-path-circle) — closed circle. +- [_cm_.**pathRect**](/path#cm-path-rect) — closed rectangle. +- [_cm_.**pathEllipse**](/path#cm-path-ellipse) — closed axis-aligned ellipse. +- [_cm_.**pathPolygon**](/path#cm-path-polygon) — closed path through `[x, y]` points. diff --git a/docs/path.md b/docs/path.md new file mode 100644 index 0000000..4c69848 --- /dev/null +++ b/docs/path.md @@ -0,0 +1,113 @@ +# Charming Path + +**Charming Path** builds SVG [`d`](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d) path strings from numbers—handy for ``, [`getPointAtLength`](https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement/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 eval code=false +(() => { + const d = cm.pathCircle(100, 100, 80); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathCircle(100, 100, 80); + +cm.svg` + +`; +``` + +## _cm_.pathLine(_x1_, _y1_, _x2_, _y2_) {#cm-path-line} + +Returns an **open** path: `M` to (_x1_, _y1_), `L` to (_x2_, _y2_). + +```js eval code=false +(() => { + const d = cm.pathLine(10, 90, 90, 10); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathLine(10, 90, 90, 10); +``` + +## _cm_.pathCircle(_cx_, _cy_, _r_) {#cm-path-circle} + +Returns a **closed** circle centered at (_cx_, _cy_) with radius _r_, using two arc segments. + +```js eval code=false +(() => { + const d = cm.pathCircle(50, 50, 40); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathCircle(100, 100, 50); +``` + +## _cm_.pathRect(_x_, _y_, _width_, _height_) {#cm-path-rect} + +Returns a **closed** rectangle with top-left (_x_, _y_) and size _width_ × _height_. + +```js eval code=false +(() => { + const d = cm.pathRect(15, 25, 70, 50); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathRect(0, 0, 100, 50); +``` + +## _cm_.pathEllipse(_cx_, _cy_, _rx_, _ry_) {#cm-path-ellipse} + +Returns a **closed** axis-aligned ellipse centered at (_cx_, _cy_) with radii _rx_ and _ry_, using two elliptical arcs. + +```js eval code=false +(() => { + const d = cm.pathEllipse(50, 50, 42, 28); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathEllipse(100, 100, 60, 40); +``` + +## _cm_.pathPolygon(_points_) {#cm-path-polygon} + +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 eval code=false +(() => { + const d = cm.pathPolygon([ + [50, 10], + [90, 90], + [10, 90], + ]); + return cm.svg` + + `; +})(); +``` + +```js +const d = cm.pathPolygon([ + [0, 0], + [100, 0], + [50, 80], +]); +``` From d309803eaddeae0f70483b61c6ed06c5c95a4dc5 Mon Sep 17 00:00:00 2001 From: pearmini Date: Fri, 3 Apr 2026 18:33:43 -0400 Subject: [PATCH 4/4] Add description for each modules --- docs/api-index.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/api-index.md b/docs/api-index.md index 1cab3b1..a822a8a 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -1,13 +1,19 @@ # API Index +Charming offers a set of utilities for working with SVG and Canvas, which can be used either together or independently. + ## [Charming DOM](/dom) +Create and manipulate DOM elements. + - [_cm_.**svg**](/dom#cm-svg) — SVG via tagged template literal. - [_cm_.**html**](/dom#cm-html) — HTML via tagged template literal. - [_cm_.**attr**](/dom#cm-attr) — get, set, or remove attributes (including styles and events) on a node. ## [Charming Canvas](/canvas) +Set up a 2D canvas and draw shapes. + - [_cm_.**context2d**](/canvas#cm-context2d) — create a 2D canvas rendering context (size, DPR, optional container). - [_cm_.**cssFont**](/canvas#cm-css-font) — build a CSS `font` shorthand string (canvas, DOM, or D3). - [_cm_.**strokeLine**](/canvas#cm-stroke-line) — stroke a line between two points. @@ -18,6 +24,8 @@ ## [Charming Path](/path) +Build SVG path strings for common shapes. + - [_cm_.**pathLine**](/path#cm-path-line) — open segment `M` … `L` … - [_cm_.**pathCircle**](/path#cm-path-circle) — closed circle. - [_cm_.**pathRect**](/path#cm-path-rect) — closed rectangle.