sketchmark 2.1.0 → 2.1.2
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/package.json +1 -7
- package/ANIMATABLE_MATRIX.md +0 -177
- package/KERNEL_SPEC.md +0 -412
- package/PACKS.md +0 -81
- package/PRESETS.md +0 -182
- package/dist/src/builders/index.d.ts +0 -64
- package/dist/src/builders/index.js +0 -212
- package/dist/src/compounds.d.ts +0 -13
- package/dist/src/compounds.js +0 -118
- package/dist/src/deck.d.ts +0 -4
- package/dist/src/deck.js +0 -91
- package/dist/src/export/index.d.ts +0 -8
- package/dist/src/export/index.js +0 -15
- package/dist/src/kernel.d.ts +0 -8
- package/dist/src/kernel.js +0 -68
- package/dist/src/motion.d.ts +0 -4
- package/dist/src/motion.js +0 -262
- package/dist/src/patch.d.ts +0 -5
- package/dist/src/patch.js +0 -72
- package/dist/src/player/index.d.ts +0 -68
- package/dist/src/player/index.js +0 -600
- package/dist/src/project.d.ts +0 -11
- package/dist/src/project.js +0 -107
- package/dist/src/render/raw-three.d.ts +0 -7
- package/dist/src/render/raw-three.js +0 -17
- package/dist/src/render/three-html.d.ts +0 -2
- package/dist/src/render/three-html.js +0 -257
- package/dist/src/render/three-preview-svg.d.ts +0 -3
- package/dist/src/render/three-preview-svg.js +0 -102
- package/dist/src/scenes.d.ts +0 -4
- package/dist/src/scenes.js +0 -26
- package/dist/src/sequences.d.ts +0 -43
- package/dist/src/sequences.js +0 -109
- package/dist/src/shapes/builtins.d.ts +0 -2
- package/dist/src/shapes/builtins.js +0 -393
- package/dist/src/shapes/common.d.ts +0 -9
- package/dist/src/shapes/common.js +0 -76
- package/dist/src/shapes/geometry.d.ts +0 -22
- package/dist/src/shapes/geometry.js +0 -166
- package/dist/src/shapes/index.d.ts +0 -2
- package/dist/src/shapes/index.js +0 -18
- package/dist/src/shapes/registry.d.ts +0 -8
- package/dist/src/shapes/registry.js +0 -31
- package/dist/src/shapes/types.d.ts +0 -32
- package/dist/src/shapes/types.js +0 -2
- package/examples/1730642890464.jpg +0 -0
- package/examples/app-screen.svg +0 -1
- package/examples/app-screen.visual.json +0 -503
- package/examples/dashboard-table.svg +0 -1
- package/examples/dashboard-table.visual.json +0 -708
- package/examples/dev-docs.svg +0 -1
- package/examples/dev-docs.visual.json +0 -248
- package/examples/explainer.mp4 +0 -0
- package/examples/explainer.visual.json +0 -1713
- package/examples/group-origin-effects-lab-check.svg +0 -1
- package/examples/group-origin-effects-lab.visual.json +0 -1880
- package/examples/image-clip-radius.visual.json +0 -271
- package/examples/make-app-screen.cjs +0 -368
- package/examples/make-dashboard-table.cjs +0 -277
- package/examples/make-dev-docs.cjs +0 -233
- package/examples/make-explainer.cjs +0 -438
- package/examples/make-group-origin-effects-lab.cjs +0 -370
- package/examples/make-image-clip-radius.cjs +0 -169
- package/examples/make-modal-dialog.cjs +0 -355
- package/examples/make-origin-effects-lab.cjs +0 -311
- package/examples/make-preset-character-motion.cjs +0 -32
- package/examples/make-presets-demo.cjs +0 -30
- package/examples/make-pricing.cjs +0 -286
- package/examples/make-product-demo.cjs +0 -468
- package/examples/make-product-hero.cjs +0 -223
- package/examples/make-release-notes.cjs +0 -333
- package/examples/make-settings-panel.cjs +0 -435
- package/examples/make-split-preview.cjs +0 -248
- package/examples/make-storyboard.cjs +0 -215
- package/examples/make-transcript.cjs +0 -234
- package/examples/make-typography-test.cjs +0 -397
- package/examples/make-ui-demo-explainer.cjs +0 -1094
- package/examples/make-ui-flow.cjs +0 -762
- package/examples/make-walkthrough.cjs +0 -815
- package/examples/modal-dialog.svg +0 -1
- package/examples/modal-dialog.visual.json +0 -239
- package/examples/origin-effects-lab-check.svg +0 -1
- package/examples/origin-effects-lab.visual.json +0 -1412
- package/examples/preset-character-motion.visual.json +0 -949
- package/examples/presets-demo.visual.json +0 -787
- package/examples/pricing.svg +0 -1
- package/examples/pricing.visual.json +0 -652
- package/examples/product-demo.mp4 +0 -0
- package/examples/product-demo.visual.json +0 -866
- package/examples/product-hero.svg +0 -1
- package/examples/product-hero.visual.json +0 -242
- package/examples/release-notes.svg +0 -1
- package/examples/release-notes.visual.json +0 -467
- package/examples/settings-panel.svg +0 -1
- package/examples/settings-panel.visual.json +0 -501
- package/examples/split-preview.svg +0 -1
- package/examples/split-preview.visual.json +0 -124
- package/examples/storyboard.svg +0 -1
- package/examples/storyboard.visual.json +0 -312
- package/examples/transcript.svg +0 -1
- package/examples/transcript.visual.json +0 -407
- package/examples/typography-indent-check.svg +0 -1
- package/examples/typography-lineheight-0.svg +0 -1
- package/examples/typography-lineheight-2.svg +0 -1
- package/examples/typography-test-check.svg +0 -1
- package/examples/typography-test.svg +0 -1
- package/examples/typography-test.visual.json +0 -757
- package/examples/ui-demo-explainer-billing.svg +0 -1
- package/examples/ui-demo-explainer-check.svg +0 -1
- package/examples/ui-demo-explainer-save.svg +0 -1
- package/examples/ui-demo-explainer-toggle.svg +0 -1
- package/examples/ui-demo-explainer.mp4 +0 -0
- package/examples/ui-demo-explainer.visual.json +0 -2597
- package/examples/ui-flow.mp4 +0 -0
- package/examples/ui-flow.visual.json +0 -1211
- package/examples/walkthrough.mp4 +0 -0
- package/examples/walkthrough.visual.json +0 -1372
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
const width = 1100;
|
|
5
|
-
const height = 560;
|
|
6
|
-
const bg = "#f8fafc";
|
|
7
|
-
const font = "Inter, system-ui, sans-serif";
|
|
8
|
-
|
|
9
|
-
const colors = {
|
|
10
|
-
pageTitle: "#0f172a",
|
|
11
|
-
tableTitle: "#1e293b",
|
|
12
|
-
headerBg: "#f1f5f9",
|
|
13
|
-
headerText: "#475569",
|
|
14
|
-
rowBg: "#ffffff",
|
|
15
|
-
rowAltBg: "#fafbfc",
|
|
16
|
-
rowBorder: "#e2e8f0",
|
|
17
|
-
cellText: "#334155",
|
|
18
|
-
cellMuted: "#64748b",
|
|
19
|
-
tableBorder: "#e2e8f0",
|
|
20
|
-
statusGreen: "#10b981",
|
|
21
|
-
statusGreenBg: "#d1fae5",
|
|
22
|
-
statusYellow: "#d97706",
|
|
23
|
-
statusYellowBg: "#fef3c7",
|
|
24
|
-
statusRed: "#dc2626",
|
|
25
|
-
statusRedBg: "#fee2e2",
|
|
26
|
-
statusGray: "#64748b",
|
|
27
|
-
statusGrayBg: "#f1f5f9"
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const padX = 48;
|
|
31
|
-
let y = 40;
|
|
32
|
-
|
|
33
|
-
const elements = [];
|
|
34
|
-
|
|
35
|
-
// Page title
|
|
36
|
-
elements.push({
|
|
37
|
-
id: "page-title",
|
|
38
|
-
type: "text",
|
|
39
|
-
x: padX,
|
|
40
|
-
y: y,
|
|
41
|
-
text: "Operations Dashboard",
|
|
42
|
-
align: "left",
|
|
43
|
-
valign: "top",
|
|
44
|
-
fontSize: 26,
|
|
45
|
-
fontFamily: font,
|
|
46
|
-
weight: 700,
|
|
47
|
-
fill: colors.pageTitle
|
|
48
|
-
});
|
|
49
|
-
y += 44;
|
|
50
|
-
|
|
51
|
-
// Table title
|
|
52
|
-
elements.push({
|
|
53
|
-
id: "table-title",
|
|
54
|
-
type: "text",
|
|
55
|
-
x: padX,
|
|
56
|
-
y: y,
|
|
57
|
-
text: "Service Health Overview",
|
|
58
|
-
align: "left",
|
|
59
|
-
valign: "top",
|
|
60
|
-
fontSize: 16,
|
|
61
|
-
fontFamily: font,
|
|
62
|
-
weight: 600,
|
|
63
|
-
fill: colors.tableTitle
|
|
64
|
-
});
|
|
65
|
-
y += 32;
|
|
66
|
-
|
|
67
|
-
// Table structure
|
|
68
|
-
const tableX = padX;
|
|
69
|
-
const tableW = width - padX * 2;
|
|
70
|
-
const rowH = 44;
|
|
71
|
-
const headerH = 40;
|
|
72
|
-
|
|
73
|
-
const columns = [
|
|
74
|
-
{ key: "service", label: "Service", width: 200, align: "left" },
|
|
75
|
-
{ key: "requests", label: "Requests", width: 120, align: "right" },
|
|
76
|
-
{ key: "latency", label: "Avg Latency", width: 120, align: "right" },
|
|
77
|
-
{ key: "errors", label: "Error Rate", width: 110, align: "right" },
|
|
78
|
-
{ key: "uptime", label: "Uptime", width: 100, align: "right" },
|
|
79
|
-
{ key: "status", label: "Status", width: 110, align: "center" }
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const rows = [
|
|
83
|
-
{ service: "API Gateway", requests: "1.2M", latency: "42ms", errors: "0.02%", uptime: "99.99%", status: "Healthy" },
|
|
84
|
-
{ service: "Auth Service", requests: "890K", latency: "28ms", errors: "0.01%", uptime: "99.98%", status: "Healthy" },
|
|
85
|
-
{ service: "User Database", requests: "2.4M", latency: "8ms", errors: "0.00%", uptime: "100%", status: "Healthy" },
|
|
86
|
-
{ service: "Cache Layer", requests: "5.1M", latency: "2ms", errors: "0.03%", uptime: "99.95%", status: "Degraded" },
|
|
87
|
-
{ service: "Search Index", requests: "340K", latency: "156ms", errors: "1.20%", uptime: "98.50%", status: "Warning" },
|
|
88
|
-
{ service: "Legacy Sync", requests: "45K", latency: "890ms", errors: "4.50%", uptime: "94.20%", status: "Critical" }
|
|
89
|
-
];
|
|
90
|
-
|
|
91
|
-
const statusColors = {
|
|
92
|
-
Healthy: { bg: colors.statusGreenBg, text: colors.statusGreen },
|
|
93
|
-
Degraded: { bg: colors.statusYellowBg, text: colors.statusYellow },
|
|
94
|
-
Warning: { bg: colors.statusYellowBg, text: colors.statusYellow },
|
|
95
|
-
Critical: { bg: colors.statusRedBg, text: colors.statusRed },
|
|
96
|
-
Offline: { bg: colors.statusGrayBg, text: colors.statusGray }
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Table outer border
|
|
100
|
-
const tableH = headerH + rows.length * rowH;
|
|
101
|
-
elements.push({
|
|
102
|
-
id: "table-border",
|
|
103
|
-
type: "path",
|
|
104
|
-
d: roundedRect(tableX, y, tableW, tableH, 8),
|
|
105
|
-
fill: colors.rowBg,
|
|
106
|
-
stroke: colors.tableBorder,
|
|
107
|
-
strokeWidth: 1
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Header row background
|
|
111
|
-
elements.push({
|
|
112
|
-
id: "header-bg",
|
|
113
|
-
type: "path",
|
|
114
|
-
d: `M ${tableX + 8} ${y} L ${tableX + tableW - 8} ${y} Q ${tableX + tableW} ${y} ${tableX + tableW} ${y + 8} L ${tableX + tableW} ${y + headerH} L ${tableX} ${y + headerH} L ${tableX} ${y + 8} Q ${tableX} ${y} ${tableX + 8} ${y} Z`,
|
|
115
|
-
fill: colors.headerBg,
|
|
116
|
-
stroke: "none"
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Header row bottom border
|
|
120
|
-
elements.push({
|
|
121
|
-
id: "header-border",
|
|
122
|
-
type: "path",
|
|
123
|
-
d: `M ${tableX} ${y + headerH} L ${tableX + tableW} ${y + headerH}`,
|
|
124
|
-
stroke: colors.rowBorder,
|
|
125
|
-
strokeWidth: 1,
|
|
126
|
-
fill: "none"
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Column headers
|
|
130
|
-
let colX = tableX;
|
|
131
|
-
columns.forEach((col, i) => {
|
|
132
|
-
const textX = col.align === "left" ? colX + 16 :
|
|
133
|
-
col.align === "right" ? colX + col.width - 16 :
|
|
134
|
-
colX + col.width / 2;
|
|
135
|
-
|
|
136
|
-
elements.push({
|
|
137
|
-
id: `header-${col.key}`,
|
|
138
|
-
type: "text",
|
|
139
|
-
x: textX,
|
|
140
|
-
y: y + headerH / 2,
|
|
141
|
-
text: col.label,
|
|
142
|
-
align: col.align,
|
|
143
|
-
valign: "middle",
|
|
144
|
-
fontSize: 12,
|
|
145
|
-
fontFamily: font,
|
|
146
|
-
weight: 600,
|
|
147
|
-
fill: colors.headerText
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
colX += col.width;
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Data rows
|
|
154
|
-
rows.forEach((row, ri) => {
|
|
155
|
-
const rowY = y + headerH + ri * rowH;
|
|
156
|
-
|
|
157
|
-
// Alternating row background
|
|
158
|
-
if (ri % 2 === 1) {
|
|
159
|
-
elements.push({
|
|
160
|
-
id: `row-bg-${ri}`,
|
|
161
|
-
type: "path",
|
|
162
|
-
d: `M ${tableX} ${rowY} L ${tableX + tableW} ${rowY} L ${tableX + tableW} ${rowY + rowH} L ${tableX} ${rowY + rowH} Z`,
|
|
163
|
-
fill: colors.rowAltBg,
|
|
164
|
-
stroke: "none"
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Row border (except last)
|
|
169
|
-
if (ri < rows.length - 1) {
|
|
170
|
-
elements.push({
|
|
171
|
-
id: `row-border-${ri}`,
|
|
172
|
-
type: "path",
|
|
173
|
-
d: `M ${tableX + 16} ${rowY + rowH} L ${tableX + tableW - 16} ${rowY + rowH}`,
|
|
174
|
-
stroke: colors.rowBorder,
|
|
175
|
-
strokeWidth: 1,
|
|
176
|
-
fill: "none"
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Cell values
|
|
181
|
-
let cx = tableX;
|
|
182
|
-
columns.forEach((col) => {
|
|
183
|
-
const value = row[col.key];
|
|
184
|
-
const textX = col.align === "left" ? cx + 16 :
|
|
185
|
-
col.align === "right" ? cx + col.width - 16 :
|
|
186
|
-
cx + col.width / 2;
|
|
187
|
-
|
|
188
|
-
if (col.key === "status") {
|
|
189
|
-
// Status chip
|
|
190
|
-
const chipW = 72;
|
|
191
|
-
const chipH = 24;
|
|
192
|
-
const chipX = cx + (col.width - chipW) / 2;
|
|
193
|
-
const chipY = rowY + (rowH - chipH) / 2;
|
|
194
|
-
const chipR = 12;
|
|
195
|
-
const sc = statusColors[value] || statusColors.Offline;
|
|
196
|
-
|
|
197
|
-
elements.push({
|
|
198
|
-
id: `cell-${ri}-${col.key}-bg`,
|
|
199
|
-
type: "path",
|
|
200
|
-
d: roundedRect(chipX, chipY, chipW, chipH, chipR),
|
|
201
|
-
fill: sc.bg,
|
|
202
|
-
stroke: "none"
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
elements.push({
|
|
206
|
-
id: `cell-${ri}-${col.key}-text`,
|
|
207
|
-
type: "text",
|
|
208
|
-
x: chipX + chipW / 2,
|
|
209
|
-
y: chipY + chipH / 2,
|
|
210
|
-
text: value,
|
|
211
|
-
align: "center",
|
|
212
|
-
valign: "middle",
|
|
213
|
-
fontSize: 11,
|
|
214
|
-
fontFamily: font,
|
|
215
|
-
weight: 600,
|
|
216
|
-
fill: sc.text
|
|
217
|
-
});
|
|
218
|
-
} else if (col.key === "service") {
|
|
219
|
-
// Service name (row label)
|
|
220
|
-
elements.push({
|
|
221
|
-
id: `cell-${ri}-${col.key}`,
|
|
222
|
-
type: "text",
|
|
223
|
-
x: textX,
|
|
224
|
-
y: rowY + rowH / 2,
|
|
225
|
-
text: value,
|
|
226
|
-
align: col.align,
|
|
227
|
-
valign: "middle",
|
|
228
|
-
fontSize: 13,
|
|
229
|
-
fontFamily: font,
|
|
230
|
-
weight: 500,
|
|
231
|
-
fill: colors.cellText
|
|
232
|
-
});
|
|
233
|
-
} else {
|
|
234
|
-
// Numeric values
|
|
235
|
-
elements.push({
|
|
236
|
-
id: `cell-${ri}-${col.key}`,
|
|
237
|
-
type: "text",
|
|
238
|
-
x: textX,
|
|
239
|
-
y: rowY + rowH / 2,
|
|
240
|
-
text: value,
|
|
241
|
-
align: col.align,
|
|
242
|
-
valign: "middle",
|
|
243
|
-
fontSize: 13,
|
|
244
|
-
fontFamily: font,
|
|
245
|
-
weight: 400,
|
|
246
|
-
fill: colors.cellMuted
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
cx += col.width;
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
function roundedRect(x, y, w, h, r) {
|
|
255
|
-
return [
|
|
256
|
-
`M ${x + r} ${y}`,
|
|
257
|
-
`L ${x + w - r} ${y}`,
|
|
258
|
-
`Q ${x + w} ${y} ${x + w} ${y + r}`,
|
|
259
|
-
`L ${x + w} ${y + h - r}`,
|
|
260
|
-
`Q ${x + w} ${y + h} ${x + w - r} ${y + h}`,
|
|
261
|
-
`L ${x + r} ${y + h}`,
|
|
262
|
-
`Q ${x} ${y + h} ${x} ${y + h - r}`,
|
|
263
|
-
`L ${x} ${y + r}`,
|
|
264
|
-
`Q ${x} ${y} ${x + r} ${y}`,
|
|
265
|
-
"Z"
|
|
266
|
-
].join(" ");
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const doc = {
|
|
270
|
-
version: 1,
|
|
271
|
-
canvas: { width, height, background: bg },
|
|
272
|
-
elements
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
const outPath = path.join(__dirname, "dashboard-table.visual.json");
|
|
276
|
-
fs.writeFileSync(outPath, JSON.stringify(doc, null, 2));
|
|
277
|
-
console.log("Written:", outPath);
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
|
|
4
|
-
const width = 1280;
|
|
5
|
-
const height = 960;
|
|
6
|
-
const bg = "#ffffff";
|
|
7
|
-
const textColor = "#1a1a2e";
|
|
8
|
-
const mutedColor = "#6b7280";
|
|
9
|
-
const accentColor = "#2563eb";
|
|
10
|
-
const codeBg = "#f1f5f9";
|
|
11
|
-
const codeBorder = "#e2e8f0";
|
|
12
|
-
const codeText = "#334155";
|
|
13
|
-
const bulletColor = "#2563eb";
|
|
14
|
-
const btnBg = "#2563eb";
|
|
15
|
-
const btnText = "#ffffff";
|
|
16
|
-
const font = "Inter, system-ui, sans-serif";
|
|
17
|
-
const monoFont = "JetBrains Mono, Fira Code, monospace";
|
|
18
|
-
|
|
19
|
-
const padX = 80;
|
|
20
|
-
let y = 64;
|
|
21
|
-
|
|
22
|
-
const elements = [];
|
|
23
|
-
|
|
24
|
-
// Page title
|
|
25
|
-
elements.push({
|
|
26
|
-
id: "title",
|
|
27
|
-
type: "text",
|
|
28
|
-
x: padX,
|
|
29
|
-
y: y,
|
|
30
|
-
text: "Getting Started with the Render API",
|
|
31
|
-
align: "left",
|
|
32
|
-
valign: "top",
|
|
33
|
-
fontSize: 36,
|
|
34
|
-
fontFamily: font,
|
|
35
|
-
weight: 700,
|
|
36
|
-
fill: textColor
|
|
37
|
-
});
|
|
38
|
-
y += 52;
|
|
39
|
-
|
|
40
|
-
// Subtitle
|
|
41
|
-
elements.push({
|
|
42
|
-
id: "subtitle",
|
|
43
|
-
type: "text",
|
|
44
|
-
x: padX,
|
|
45
|
-
y: y,
|
|
46
|
-
text: "A concise guide to integrating the render pipeline into your application.",
|
|
47
|
-
align: "left",
|
|
48
|
-
valign: "top",
|
|
49
|
-
fontSize: 16,
|
|
50
|
-
fontFamily: font,
|
|
51
|
-
weight: 400,
|
|
52
|
-
fill: mutedColor
|
|
53
|
-
});
|
|
54
|
-
y += 48;
|
|
55
|
-
|
|
56
|
-
// Horizontal rule
|
|
57
|
-
elements.push({
|
|
58
|
-
id: "divider",
|
|
59
|
-
type: "path",
|
|
60
|
-
d: `M ${padX} ${y} L ${width - padX} ${y}`,
|
|
61
|
-
stroke: "#e5e7eb",
|
|
62
|
-
strokeWidth: 1,
|
|
63
|
-
fill: "none"
|
|
64
|
-
});
|
|
65
|
-
y += 32;
|
|
66
|
-
|
|
67
|
-
// Paragraph 1
|
|
68
|
-
elements.push({
|
|
69
|
-
id: "para1",
|
|
70
|
-
type: "text",
|
|
71
|
-
x: padX,
|
|
72
|
-
y: y,
|
|
73
|
-
text: "The Render API exposes a minimal surface for compiling visual documents into\noutput frames. It accepts a validated kernel document and a target time, then\nresolves all timeline interpolations and returns a flat list of positioned primitives\nready for rasterization or SVG serialization.",
|
|
74
|
-
align: "left",
|
|
75
|
-
valign: "top",
|
|
76
|
-
fontSize: 15,
|
|
77
|
-
fontFamily: font,
|
|
78
|
-
weight: 400,
|
|
79
|
-
lineHeight: 1.7,
|
|
80
|
-
fill: textColor,
|
|
81
|
-
maxWidth: width - padX * 2
|
|
82
|
-
});
|
|
83
|
-
y += 110;
|
|
84
|
-
|
|
85
|
-
// Paragraph 2
|
|
86
|
-
elements.push({
|
|
87
|
-
id: "para2",
|
|
88
|
-
type: "text",
|
|
89
|
-
x: padX,
|
|
90
|
-
y: y,
|
|
91
|
-
text: "Before calling the render function, ensure your document passes schema\nvalidation. Invalid documents will throw a structured error with path information\npointing to the offending node. This keeps the pipeline predictable and safe.",
|
|
92
|
-
align: "left",
|
|
93
|
-
valign: "top",
|
|
94
|
-
fontSize: 15,
|
|
95
|
-
fontFamily: font,
|
|
96
|
-
weight: 400,
|
|
97
|
-
lineHeight: 1.7,
|
|
98
|
-
fill: textColor,
|
|
99
|
-
maxWidth: width - padX * 2
|
|
100
|
-
});
|
|
101
|
-
y += 100;
|
|
102
|
-
|
|
103
|
-
// Code block background
|
|
104
|
-
const codeBlockH = 172;
|
|
105
|
-
elements.push({
|
|
106
|
-
id: "code-bg",
|
|
107
|
-
type: "path",
|
|
108
|
-
d: `M ${padX} ${y} L ${width - padX} ${y} L ${width - padX} ${y + codeBlockH} L ${padX} ${y + codeBlockH} Z`,
|
|
109
|
-
fill: codeBg,
|
|
110
|
-
stroke: codeBorder,
|
|
111
|
-
strokeWidth: 1
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Code block text (6 lines)
|
|
115
|
-
elements.push({
|
|
116
|
-
id: "code-text",
|
|
117
|
-
type: "text",
|
|
118
|
-
x: padX + 20,
|
|
119
|
-
y: y + 18,
|
|
120
|
-
text: `import { validateVisualDocument, resolveVisualFrame } from "sketchmark";\n\nconst doc = JSON.parse(fs.readFileSync("scene.visual.json", "utf8"));\nvalidateVisualDocument(doc);\n\nconst frame = resolveVisualFrame(doc, { time: 1.5 });\nconsole.log(frame.elements.length, "primitives resolved");`,
|
|
121
|
-
align: "left",
|
|
122
|
-
valign: "top",
|
|
123
|
-
fontSize: 13,
|
|
124
|
-
fontFamily: monoFont,
|
|
125
|
-
weight: 400,
|
|
126
|
-
lineHeight: 1.8,
|
|
127
|
-
fill: codeText,
|
|
128
|
-
maxWidth: width - padX * 2 - 40
|
|
129
|
-
});
|
|
130
|
-
y += codeBlockH + 36;
|
|
131
|
-
|
|
132
|
-
// Section heading for bullet list
|
|
133
|
-
elements.push({
|
|
134
|
-
id: "list-heading",
|
|
135
|
-
type: "text",
|
|
136
|
-
x: padX,
|
|
137
|
-
y: y,
|
|
138
|
-
text: "Key Concepts",
|
|
139
|
-
align: "left",
|
|
140
|
-
valign: "top",
|
|
141
|
-
fontSize: 20,
|
|
142
|
-
fontFamily: font,
|
|
143
|
-
weight: 600,
|
|
144
|
-
fill: textColor
|
|
145
|
-
});
|
|
146
|
-
y += 36;
|
|
147
|
-
|
|
148
|
-
// Bullet list items
|
|
149
|
-
const bullets = [
|
|
150
|
-
"Documents must declare version: 1 and a canvas with width and height.",
|
|
151
|
-
"Elements are flat arrays of path, text, image, point, or group primitives.",
|
|
152
|
-
"Timelines are element-local — each element owns its own tracks and keyframes.",
|
|
153
|
-
"Interpolation resolves per-track using cubic bezier, graph, or hold curves.",
|
|
154
|
-
"The output frame contains fully resolved properties with no remaining references."
|
|
155
|
-
];
|
|
156
|
-
|
|
157
|
-
bullets.forEach((text, i) => {
|
|
158
|
-
const bulletY = y + i * 30;
|
|
159
|
-
elements.push({
|
|
160
|
-
id: `bullet-dot-${i}`,
|
|
161
|
-
type: "path",
|
|
162
|
-
d: `M ${padX + 4} ${bulletY + 7} A 3 3 0 1 1 ${padX + 4} ${bulletY + 7.01} Z`,
|
|
163
|
-
fill: bulletColor,
|
|
164
|
-
stroke: "none"
|
|
165
|
-
});
|
|
166
|
-
elements.push({
|
|
167
|
-
id: `bullet-text-${i}`,
|
|
168
|
-
type: "text",
|
|
169
|
-
x: padX + 18,
|
|
170
|
-
y: bulletY,
|
|
171
|
-
text: text,
|
|
172
|
-
align: "left",
|
|
173
|
-
valign: "top",
|
|
174
|
-
fontSize: 14,
|
|
175
|
-
fontFamily: font,
|
|
176
|
-
weight: 400,
|
|
177
|
-
fill: textColor,
|
|
178
|
-
maxWidth: width - padX * 2 - 18
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
y += bullets.length * 30 + 40;
|
|
182
|
-
|
|
183
|
-
// Centered button
|
|
184
|
-
const btnW = 200;
|
|
185
|
-
const btnH = 44;
|
|
186
|
-
const btnX = (width - btnW) / 2;
|
|
187
|
-
const btnR = 8;
|
|
188
|
-
elements.push({
|
|
189
|
-
id: "btn-bg",
|
|
190
|
-
type: "path",
|
|
191
|
-
d: `M ${btnX + btnR} ${y} L ${btnX + btnW - btnR} ${y} Q ${btnX + btnW} ${y} ${btnX + btnW} ${y + btnR} L ${btnX + btnW} ${y + btnH - btnR} Q ${btnX + btnW} ${y + btnH} ${btnX + btnW - btnR} ${y + btnH} L ${btnX + btnR} ${y + btnH} Q ${btnX} ${y + btnH} ${btnX} ${y + btnH - btnR} L ${btnX} ${y + btnR} Q ${btnX} ${y} ${btnX + btnR} ${y} Z`,
|
|
192
|
-
fill: btnBg,
|
|
193
|
-
stroke: "none"
|
|
194
|
-
});
|
|
195
|
-
elements.push({
|
|
196
|
-
id: "btn-label",
|
|
197
|
-
type: "text",
|
|
198
|
-
x: width / 2,
|
|
199
|
-
y: y + btnH / 2,
|
|
200
|
-
text: "View Full Reference",
|
|
201
|
-
align: "center",
|
|
202
|
-
valign: "middle",
|
|
203
|
-
fontSize: 15,
|
|
204
|
-
fontFamily: font,
|
|
205
|
-
weight: 600,
|
|
206
|
-
fill: btnText
|
|
207
|
-
});
|
|
208
|
-
y += btnH + 36;
|
|
209
|
-
|
|
210
|
-
// Footer note
|
|
211
|
-
elements.push({
|
|
212
|
-
id: "footer",
|
|
213
|
-
type: "text",
|
|
214
|
-
x: padX,
|
|
215
|
-
y: y,
|
|
216
|
-
text: "Last updated May 2026 · Sketchmark v1.0 · MIT License",
|
|
217
|
-
align: "left",
|
|
218
|
-
valign: "top",
|
|
219
|
-
fontSize: 12,
|
|
220
|
-
fontFamily: font,
|
|
221
|
-
weight: 400,
|
|
222
|
-
fill: mutedColor
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const doc = {
|
|
226
|
-
version: 1,
|
|
227
|
-
canvas: { width, height, background: bg },
|
|
228
|
-
elements
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const outPath = path.join(__dirname, "dev-docs.visual.json");
|
|
232
|
-
fs.writeFileSync(outPath, JSON.stringify(doc, null, 2));
|
|
233
|
-
console.log("Written:", outPath);
|