sketchmark 2.1.10 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -227
- package/bin/editor-ui.cjs +211 -84
- package/bin/preview-ui.d.ts +1 -0
- package/dist/src/edit.d.ts +1 -0
- package/dist/src/edit.js +9 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +25 -1
- package/dist/src/render/index.d.ts +6 -0
- package/dist/src/render/index.js +27 -0
- package/package.json +12 -1
- package/skills/sketchmark/SKILL.md +16 -0
- package/skills/sketchmark/animation.md +67 -0
- package/skills/sketchmark/design.md +59 -0
- package/skills/sketchmark/kernel.md +354 -0
- package/skills/sketchmark/render.md +166 -0
package/README.md
CHANGED
|
@@ -1,254 +1,75 @@
|
|
|
1
1
|
# Sketchmark
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A pure 2D render kernel for animated visuals. Documents contain only five element types: `path`, `text`, `image`, `point`, and `group`. Higher-level constructs (rectangles, arrows, charts, etc.) compile down to this format.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- `group`
|
|
7
|
+
**As a dependency:**
|
|
8
|
+
```bash
|
|
9
|
+
npm install sketchmark
|
|
10
|
+
```
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
**Starter template:**
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/anmism/sketchmark-starter.git
|
|
15
|
+
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
**For AI agents:**
|
|
18
|
+
```bash
|
|
19
|
+
npx skills add anmism/sketchmark --yes
|
|
20
|
+
```
|
|
16
21
|
|
|
17
|
-
- [Kernel Spec](./KERNEL_SPEC.md)
|
|
18
|
-
- [Animatable Property Matrix](./ANIMATABLE_MATRIX.md)
|
|
19
|
-
- [Presets](./PRESETS.md)
|
|
20
|
-
- [Packs](./PACKS.md)
|
|
21
|
-
- [What Needs Improvement](./WHAT_NEEDS_IMPROVEMENT.md)
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Document Structure
|
|
24
24
|
|
|
25
25
|
```json
|
|
26
26
|
{
|
|
27
27
|
"version": 1,
|
|
28
|
-
"canvas": {
|
|
29
|
-
|
|
30
|
-
"height": 360,
|
|
31
|
-
"background": "#f8fafc",
|
|
32
|
-
"duration": 2,
|
|
33
|
-
"fps": 30
|
|
34
|
-
},
|
|
35
|
-
"elements": [
|
|
36
|
-
{
|
|
37
|
-
"id": "line",
|
|
38
|
-
"type": "path",
|
|
39
|
-
"d": "M 80 240 C 180 80 320 280 520 120",
|
|
40
|
-
"fill": "none",
|
|
41
|
-
"stroke": "#111827",
|
|
42
|
-
"strokeWidth": 5,
|
|
43
|
-
"strokeCap": "round"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"id": "title",
|
|
47
|
-
"type": "text",
|
|
48
|
-
"text": "Render kernel",
|
|
49
|
-
"x": 320,
|
|
50
|
-
"y": 70,
|
|
51
|
-
"align": "center",
|
|
52
|
-
"valign": "middle",
|
|
53
|
-
"fontSize": 28,
|
|
54
|
-
"weight": 800,
|
|
55
|
-
"fill": "#0f172a"
|
|
56
|
-
}
|
|
57
|
-
]
|
|
28
|
+
"canvas": { "width": 640, "height": 360, "background": "#f8fafc", "duration": 2, "fps": 30 },
|
|
29
|
+
"elements": [...]
|
|
58
30
|
}
|
|
59
31
|
```
|
|
60
32
|
|
|
61
|
-
|
|
33
|
+
## Usage
|
|
62
34
|
|
|
63
|
-
|
|
35
|
+
```js
|
|
36
|
+
const { render, edit, validateVisualDocument } = require("sketchmark");
|
|
64
37
|
|
|
65
|
-
|
|
38
|
+
// Render
|
|
39
|
+
const svg = render.svg(doc, { time: 1 });
|
|
40
|
+
const html = render.html(doc);
|
|
41
|
+
const embed = render.embedHtml(doc, { title: "Preview" });
|
|
66
42
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"id": "label",
|
|
70
|
-
"type": "text",
|
|
71
|
-
"text": "Move",
|
|
72
|
-
"x": 40,
|
|
73
|
-
"y": 80,
|
|
74
|
-
"timeline": {
|
|
75
|
-
"start": 0.5,
|
|
76
|
-
"end": 2,
|
|
77
|
-
"tracks": {
|
|
78
|
-
"position": {
|
|
79
|
-
"keyframes": [
|
|
80
|
-
{
|
|
81
|
-
"time": 0,
|
|
82
|
-
"value": [40, 80],
|
|
83
|
-
"out": {
|
|
84
|
-
"type": "cubicBezier",
|
|
85
|
-
"x1": 0.42,
|
|
86
|
-
"y1": 0,
|
|
87
|
-
"x2": 0.58,
|
|
88
|
-
"y2": 1
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
{ "time": 1.5, "value": [260, 80] }
|
|
92
|
-
]
|
|
93
|
-
},
|
|
94
|
-
"opacity": {
|
|
95
|
-
"keyframes": [[0, 0], [0.4, 1]]
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
43
|
+
// Edit
|
|
44
|
+
const updated = edit.setProperty(doc, "element-id", "fill", "#22c55e");
|
|
100
45
|
```
|
|
101
46
|
|
|
102
|
-
|
|
47
|
+
## CLI
|
|
103
48
|
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
}
|
|
49
|
+
```bash
|
|
50
|
+
sketchmark render input.visual.json out.svg
|
|
51
|
+
sketchmark render input.visual.json out.mp4
|
|
52
|
+
sketchmark preview input.visual.json
|
|
53
|
+
sketchmark edit input.visual.json
|
|
54
|
+
sketchmark lint input.visual.json
|
|
112
55
|
```
|
|
113
56
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
Current known animatable properties include transform/layout (`position`, `x`, `y`, `rotation`, `scale`, `scaleX`, `scaleY`, `origin`, `width`, `height`, `opacity`), path data/drawing/style (`d`, `fill`, `stroke`, `strokeWidth`, caps/joins, `dashArray`, `dashOffset`, `drawStart`, `drawEnd`), text content/layout (`text`, `lines`, `align`, `valign`, `fontStyle`, typography sizing), image `src`/`fit`/`source.*`, clip/mask paths and opacity, filter effects (`effects.*`), whole paint switching, structured gradient internals such as `fill.to` or `fill.stops.0.color`, and pattern internals such as `fill.x`, `fill.width`, or `fill.opacity`.
|
|
117
|
-
|
|
118
|
-
Unknown timeline tracks are invalid in the frozen kernel. Rounded images should be authored above the kernel and compiled to `clip.d`; `cornerRadius` and editor metadata are intentionally not kernel fields.
|
|
119
|
-
|
|
120
|
-
## Keyframe Authoring
|
|
121
|
-
|
|
122
|
-
For AI or editor-style authoring, use visual snapshots and compile them down to kernel timelines:
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
import { compileKeyframeStates, timelineCurvePreset } from "sketchmark";
|
|
126
|
-
|
|
127
|
-
const animated = compileKeyframeStates(document, [
|
|
128
|
-
{
|
|
129
|
-
time: 0,
|
|
130
|
-
set: {
|
|
131
|
-
card: { position: [80, 160], scale: 0.85, opacity: 0 }
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
time: 1,
|
|
136
|
-
set: {
|
|
137
|
-
card: {
|
|
138
|
-
position: {
|
|
139
|
-
value: [220, 120],
|
|
140
|
-
curve: timelineCurvePreset("ease-out")
|
|
141
|
-
},
|
|
142
|
-
scale: 1,
|
|
143
|
-
opacity: 1
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
]);
|
|
148
|
-
```
|
|
57
|
+
Video export requires `sharp` and `ffmpeg`.
|
|
149
58
|
|
|
150
|
-
|
|
59
|
+
## Package Entry Points
|
|
151
60
|
|
|
152
|
-
|
|
61
|
+
| Entry | Purpose |
|
|
62
|
+
|-------|---------|
|
|
63
|
+
| `sketchmark` | Core kernel: validate, render, edit, keyframes |
|
|
64
|
+
| `sketchmark/presets` | Authoring helpers: shapes, motions, effects |
|
|
65
|
+
| `sketchmark/editor` | Editor UI |
|
|
66
|
+
| `sketchmark/preview` | Preview player |
|
|
67
|
+
| `sketchmark/schema` | JSON schema |
|
|
153
68
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
const { applyPresetFragments, shapes, motions, effects } = require("sketchmark/presets");
|
|
158
|
-
|
|
159
|
-
const visual = applyPresetFragments(
|
|
160
|
-
{
|
|
161
|
-
version: 1,
|
|
162
|
-
canvas: { width: 960, height: 540, duration: 2, fps: 30 },
|
|
163
|
-
elements: []
|
|
164
|
-
},
|
|
165
|
-
[
|
|
166
|
-
shapes.roundedRect({
|
|
167
|
-
id: "card",
|
|
168
|
-
x: 80,
|
|
169
|
-
y: 80,
|
|
170
|
-
width: 260,
|
|
171
|
-
height: 120,
|
|
172
|
-
radius: 16,
|
|
173
|
-
fill: "#ffffff",
|
|
174
|
-
stroke: "#cbd5e1"
|
|
175
|
-
}),
|
|
176
|
-
motions.riseIn({ id: "card", from: [80, 120], to: [80, 80] }),
|
|
177
|
-
effects.dropShadow({ id: "card", dy: 10, blur: 24, opacity: 0.2 })
|
|
178
|
-
]
|
|
179
|
-
);
|
|
180
|
-
```
|
|
69
|
+
## Documentation
|
|
181
70
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
npm run build
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Render:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
node bin/sketchmark.cjs render path/to/diagram.visual.json out.svg
|
|
196
|
-
node bin/sketchmark.cjs render path/to/diagram.visual.json out.html --time 1
|
|
197
|
-
node bin/sketchmark.cjs render path/to/diagram.visual.json out.mp4
|
|
198
|
-
node bin/sketchmark.cjs render path/to/diagram.visual.json out.webm --fps 30
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Preview animated timelines in the browser:
|
|
202
|
-
|
|
203
|
-
```bash
|
|
204
|
-
node bin/sketchmark.cjs preview path/to/diagram.visual.json
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Open the tiny editor:
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
node bin/sketchmark.cjs edit path/to/diagram.visual.json
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Lint:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
node bin/sketchmark.cjs lint path/to/diagram.visual.json
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Video export is an adapter, not a kernel feature. It samples the document timeline into SVG frames, rasterizes those frames, and hands them to `ffmpeg`. It requires `sharp` and `ffmpeg` to be available in the local environment.
|
|
220
|
-
|
|
221
|
-
## Public API
|
|
222
|
-
|
|
223
|
-
```ts
|
|
224
|
-
import {
|
|
225
|
-
validateVisualDocument,
|
|
226
|
-
compileKeyframeStates,
|
|
227
|
-
timelineCurvePreset,
|
|
228
|
-
resolveVisualFrame,
|
|
229
|
-
renderToEmbedHtml,
|
|
230
|
-
renderToSvg,
|
|
231
|
-
renderToHtml,
|
|
232
|
-
lintVisualDocument
|
|
233
|
-
} from "sketchmark";
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
For a reusable browser preview with play/pause and export controls, generate a self-contained HTML embed and mount it in an `iframe` via `srcDoc`:
|
|
237
|
-
|
|
238
|
-
```ts
|
|
239
|
-
import { renderToEmbedHtml } from "sketchmark";
|
|
240
|
-
|
|
241
|
-
const html = renderToEmbedHtml(doc, {
|
|
242
|
-
title: "Login Flow",
|
|
243
|
-
maxFrames: 180
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
`renderToEmbedHtml()` inlines sampled SVG frames so the preview can play without a server route. Use `maxFrames` to trade file size for smoother motion.
|
|
248
|
-
The embed chrome defaults to a transparent outer background and uses light/dark-aware translucent controls so it can sit inside either theme more naturally.
|
|
249
|
-
For broad embed-host compatibility, prefer self-contained HTML with inline scripts/styles, avoid CDN dependencies, avoid dynamic module imports from blob/object URLs, and avoid using blob URLs for runtime-loaded assets when a `data:` URL or other inline form will work.
|
|
250
|
-
The embed export menu includes MP4 when the browser supports WebCodecs, so Chrome and Edge are the safest targets for video export.
|
|
251
|
-
|
|
252
|
-
The root package intentionally exports no builders, player, project loader, deck/sequence helpers, 3D renderer, or preset compiler.
|
|
253
|
-
|
|
254
|
-
The official preset authoring layer is available from `sketchmark/presets`, not the root kernel entrypoint.
|
|
71
|
+
See `skills/sketchmark/` for detailed guides:
|
|
72
|
+
- `kernel.md` - Element types, properties, paints, effects, timelines
|
|
73
|
+
- `design.md` - Composition and visual construction
|
|
74
|
+
- `animation.md` - Timeline and motion
|
|
75
|
+
- `render.md` - Validation, rendering, export workflows
|