Skip to content

Commit 985dcf8

Browse files
authored
Document path and canvas modules (#411)
* Update Charming Canvas * Update API index * Add docs for charming path * Add description for each modules
1 parent 716280b commit 985dcf8

4 files changed

Lines changed: 177 additions & 0 deletions

File tree

docs/.vitepress/config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ export default defineConfig({
5555
text: "Charming Canvas",
5656
link: "/canvas",
5757
},
58+
{
59+
text: "Charming Path",
60+
link: "/path",
61+
},
5862
],
5963
},
6064
],

docs/api-index.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
# API Index
22

3+
Charming offers a set of utilities for working with SVG and Canvas, which can be used either together or independently.
4+
5+
## [Charming DOM](/dom)
6+
7+
Create and manipulate DOM elements.
8+
39
- [_cm_.**svg**](/dom#cm-svg) — SVG via tagged template literal.
410
- [_cm_.**html**](/dom#cm-html) — HTML via tagged template literal.
511
- [_cm_.**attr**](/dom#cm-attr) — get, set, or remove attributes (including styles and events) on a node.
12+
13+
## [Charming Canvas](/canvas)
14+
15+
Set up a 2D canvas and draw shapes.
16+
617
- [_cm_.**context2d**](/canvas#cm-context2d) — create a 2D canvas rendering context (size, DPR, optional container).
18+
- [_cm_.**cssFont**](/canvas#cm-css-font) — build a CSS `font` shorthand string (canvas, DOM, or D3).
719
- [_cm_.**strokeLine**](/canvas#cm-stroke-line) — stroke a line between two points.
820
- [_cm_.**fillCircle**](/canvas#cm-fill-circle) — fill a circle.
921
- [_cm_.**strokeCircle**](/canvas#cm-stroke-circle) — stroke a circle.
1022
- [_cm_.**strokeEllipse**](/canvas#cm-stroke-ellipse) — stroke an axis-aligned ellipse.
1123
- [_cm_.**fillEllipse**](/canvas#cm-fill-ellipse) — fill an axis-aligned ellipse.
24+
25+
## [Charming Path](/path)
26+
27+
Build SVG path strings for common shapes.
28+
29+
- [_cm_.**pathLine**](/path#cm-path-line) — open segment `M``L`
30+
- [_cm_.**pathCircle**](/path#cm-path-circle) — closed circle.
31+
- [_cm_.**pathRect**](/path#cm-path-rect) — closed rectangle.
32+
- [_cm_.**pathEllipse**](/path#cm-path-ellipse) — closed axis-aligned ellipse.
33+
- [_cm_.**pathPolygon**](/path#cm-path-polygon) — closed path through `[x, y]` points.

docs/canvas.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,44 @@ context.arc(50, 50, 25, 0, Math.PI * 2);
7171
context.fill();
7272
```
7373

74+
## _cm_.cssFont(_options_) {#cm-css-font}
75+
76+
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", …)`).
77+
78+
Options (all optional):
79+
80+
- **fontStyle** — default `"normal"`.
81+
- **fontVariant** — default `"normal"`.
82+
- **fontWeight** — default `"normal"`.
83+
- **fontSize** — default `10`; may be a number (interpreted as pixels) or a string with units, e.g. `"1.2rem"`.
84+
- **fontFamily** — default `"sans-serif"`.
85+
86+
Extra keys on the options object are ignored. The result has normalized spacing.
87+
88+
```js eval code=false
89+
(() => {
90+
const context = cm.context2d({width: 220, height: 56});
91+
context.fillStyle = "orange";
92+
context.fillRect(0, 0, 220, 56);
93+
context.fillStyle = "#222";
94+
context.font = cm.cssFont({fontSize: 22, fontFamily: "Georgia, serif"});
95+
context.textBaseline = "middle";
96+
context.fillText("Hello Canvas!", 12, 28);
97+
return context.canvas;
98+
})();
99+
```
100+
101+
```js
102+
const context = cm.context2d({width: 220, height: 56});
103+
context.font = cm.cssFont({
104+
fontStyle: "italic",
105+
fontWeight: "700",
106+
fontSize: 18,
107+
fontFamily: "system-ui, sans-serif",
108+
});
109+
context.fillText("Hello Canvas!", 10, 30);
110+
```
111+
74112
## _cm_.strokeLine(_context_, _x1_, _y1_, _x2_, _y2_) {#cm-stroke-line}
75113

76114
Strokes from (_x1_, _y1_) to (_x2_, _y2_) using the current stroke style and line width.

docs/path.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Charming Path
2+
3+
**Charming Path** builds SVG [`d`](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d) path strings from numbers—handy for `<path>`, [`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).
4+
5+
```js eval code=false
6+
(() => {
7+
const d = cm.pathCircle(100, 100, 80);
8+
return cm.svg`<svg ${{width: 200, height: 200}}>
9+
<path ${{fill: "none", stroke: "black", stroke_width: 2, d}} />
10+
</svg>`;
11+
})();
12+
```
13+
14+
```js
15+
const d = cm.pathCircle(100, 100, 80);
16+
17+
cm.svg`<svg ${{width: 200, height: 200}}>
18+
<path ${{fill: "none", stroke: "black", stroke_width: 2, d}} />
19+
</svg>`;
20+
```
21+
22+
## _cm_.pathLine(_x1_, _y1_, _x2_, _y2_) {#cm-path-line}
23+
24+
Returns an **open** path: `M` to (_x1_, _y1_), `L` to (_x2_, _y2_).
25+
26+
```js eval code=false
27+
(() => {
28+
const d = cm.pathLine(10, 90, 90, 10);
29+
return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
30+
<path ${{fill: "none", stroke: "steelblue", stroke_width: 2, d}} />
31+
</svg>`;
32+
})();
33+
```
34+
35+
```js
36+
const d = cm.pathLine(10, 90, 90, 10);
37+
```
38+
39+
## _cm_.pathCircle(_cx_, _cy_, _r_) {#cm-path-circle}
40+
41+
Returns a **closed** circle centered at (_cx_, _cy_) with radius _r_, using two arc segments.
42+
43+
```js eval code=false
44+
(() => {
45+
const d = cm.pathCircle(50, 50, 40);
46+
return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
47+
<path ${{fill: "none", stroke: "teal", stroke_width: 2, d}} />
48+
</svg>`;
49+
})();
50+
```
51+
52+
```js
53+
const d = cm.pathCircle(100, 100, 50);
54+
```
55+
56+
## _cm_.pathRect(_x_, _y_, _width_, _height_) {#cm-path-rect}
57+
58+
Returns a **closed** rectangle with top-left (_x_, _y_) and size _width_ × _height_.
59+
60+
```js eval code=false
61+
(() => {
62+
const d = cm.pathRect(15, 25, 70, 50);
63+
return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
64+
<path ${{fill: "none", stroke: "purple", stroke_width: 2, d}} />
65+
</svg>`;
66+
})();
67+
```
68+
69+
```js
70+
const d = cm.pathRect(0, 0, 100, 50);
71+
```
72+
73+
## _cm_.pathEllipse(_cx_, _cy_, _rx_, _ry_) {#cm-path-ellipse}
74+
75+
Returns a **closed** axis-aligned ellipse centered at (_cx_, _cy_) with radii _rx_ and _ry_, using two elliptical arcs.
76+
77+
```js eval code=false
78+
(() => {
79+
const d = cm.pathEllipse(50, 50, 42, 28);
80+
return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
81+
<path ${{fill: "none", stroke: "coral", stroke_width: 2, d}} />
82+
</svg>`;
83+
})();
84+
```
85+
86+
```js
87+
const d = cm.pathEllipse(100, 100, 60, 40);
88+
```
89+
90+
## _cm_.pathPolygon(_points_) {#cm-path-polygon}
91+
92+
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`.
93+
94+
```js eval code=false
95+
(() => {
96+
const d = cm.pathPolygon([
97+
[50, 10],
98+
[90, 90],
99+
[10, 90],
100+
]);
101+
return cm.svg`<svg ${{width: 100, height: 100, viewBox: "0 0 100 100"}}>
102+
<path ${{fill: "none", stroke: "darkgreen", stroke_width: 2, d}} />
103+
</svg>`;
104+
})();
105+
```
106+
107+
```js
108+
const d = cm.pathPolygon([
109+
[0, 0],
110+
[100, 0],
111+
[50, 80],
112+
]);
113+
```

0 commit comments

Comments
 (0)