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
package/PRESETS.md
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
# Sketchmark Presets
|
|
2
|
-
|
|
3
|
-
Presets are Sketchmark's official authoring layer above the render kernel.
|
|
4
|
-
|
|
5
|
-
They are reusable functions that compile to pure kernel elements and timelines. A preset may create shapes, characters, motion, effects, transitions, or scene fragments, but the final `.visual.json` must still contain only kernel fields.
|
|
6
|
-
|
|
7
|
-
## Layers
|
|
8
|
-
|
|
9
|
-
- `kernel`: final render format
|
|
10
|
-
- `presets`: reusable helpers that compile to kernel
|
|
11
|
-
- `packs`: shareable collections of presets
|
|
12
|
-
|
|
13
|
-
The root `sketchmark` export remains kernel-focused. Presets live in a separate entrypoint:
|
|
14
|
-
|
|
15
|
-
```js
|
|
16
|
-
const { applyPresetFragments, shapes, motions, effects } = require("sketchmark/presets");
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
When working inside this repo before publish, examples use:
|
|
20
|
-
|
|
21
|
-
```js
|
|
22
|
-
const { applyPresetFragments, shapes } = require("../dist/src/presets");
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Fragments
|
|
26
|
-
|
|
27
|
-
A preset returns a fragment:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
type PresetFragment = {
|
|
31
|
-
elements?: VisualElement[];
|
|
32
|
-
timelines?: Record<string, Record<string, TimelineTrack>>;
|
|
33
|
-
};
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
`elements` are appended to the document.
|
|
37
|
-
|
|
38
|
-
`timelines` are keyed by target element ID and merged into each target's local kernel timeline.
|
|
39
|
-
|
|
40
|
-
```js
|
|
41
|
-
const doc = {
|
|
42
|
-
version: 1,
|
|
43
|
-
canvas: { width: 960, height: 540, duration: 2, fps: 30 },
|
|
44
|
-
elements: []
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const visual = applyPresetFragments(doc, [
|
|
48
|
-
shapes.roundedRect({
|
|
49
|
-
id: "card",
|
|
50
|
-
x: 80,
|
|
51
|
-
y: 80,
|
|
52
|
-
width: 260,
|
|
53
|
-
height: 120,
|
|
54
|
-
radius: 16,
|
|
55
|
-
fill: "#ffffff",
|
|
56
|
-
stroke: "#cbd5e1"
|
|
57
|
-
}),
|
|
58
|
-
motions.riseIn({
|
|
59
|
-
id: "card",
|
|
60
|
-
from: [80, 120],
|
|
61
|
-
to: [80, 80],
|
|
62
|
-
duration: 0.5
|
|
63
|
-
}),
|
|
64
|
-
effects.dropShadow({
|
|
65
|
-
id: "card",
|
|
66
|
-
dy: 10,
|
|
67
|
-
blur: 24,
|
|
68
|
-
opacity: 0.2
|
|
69
|
-
})
|
|
70
|
-
]);
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
The output is a normal kernel document. There is no preset metadata in `.visual.json`.
|
|
74
|
-
|
|
75
|
-
## Built-In Namespaces
|
|
76
|
-
|
|
77
|
-
### `shapes`
|
|
78
|
-
|
|
79
|
-
- `rect`
|
|
80
|
-
- `roundedRect`
|
|
81
|
-
- `ellipse`
|
|
82
|
-
- `circle`
|
|
83
|
-
- `line`
|
|
84
|
-
- `polyline`
|
|
85
|
-
- `arrow`
|
|
86
|
-
- `regularPolygon`
|
|
87
|
-
- `star`
|
|
88
|
-
- `speechBubble`
|
|
89
|
-
|
|
90
|
-
Shapes compile to `path`, `text`, or `group`.
|
|
91
|
-
|
|
92
|
-
### `characters`
|
|
93
|
-
|
|
94
|
-
- `stickPerson`
|
|
95
|
-
- `talkingHead`
|
|
96
|
-
- `simpleDog`
|
|
97
|
-
- `simpleSpider`
|
|
98
|
-
- `cursorHand`
|
|
99
|
-
- `simpleMascot`
|
|
100
|
-
|
|
101
|
-
Characters compile to groups with namespaced IDs such as `hero.head` and `dog.frontLeg`.
|
|
102
|
-
|
|
103
|
-
### `motions`
|
|
104
|
-
|
|
105
|
-
- `fadeIn`
|
|
106
|
-
- `fadeOut`
|
|
107
|
-
- `slideIn`
|
|
108
|
-
- `riseIn`
|
|
109
|
-
- `scaleIn`
|
|
110
|
-
- `pulse`
|
|
111
|
-
- `bob`
|
|
112
|
-
- `shake`
|
|
113
|
-
- `drawOn`
|
|
114
|
-
- `stagger`
|
|
115
|
-
|
|
116
|
-
Motions compile to explicit object keyframes and curves. They do not emit legacy `ease` strings.
|
|
117
|
-
|
|
118
|
-
### `effects`
|
|
119
|
-
|
|
120
|
-
- `dropShadow`
|
|
121
|
-
- `softBlur`
|
|
122
|
-
- `glow`
|
|
123
|
-
- `dim`
|
|
124
|
-
- `tintFill`
|
|
125
|
-
- `gradientSweep`
|
|
126
|
-
- `roundedImageClip`
|
|
127
|
-
- `maskReveal`
|
|
128
|
-
|
|
129
|
-
Effects compile to existing kernel properties such as `effects.*`, `fill`, `opacity`, `clip.d`, and `mask.d`.
|
|
130
|
-
|
|
131
|
-
Rounded images are compiled to `clip.d`. Presets must not write `cornerRadius`.
|
|
132
|
-
|
|
133
|
-
### `transitions`
|
|
134
|
-
|
|
135
|
-
- `crossfade`
|
|
136
|
-
- `pushLeft`
|
|
137
|
-
- `pushRight`
|
|
138
|
-
- `slideUp`
|
|
139
|
-
- `wipeLeft`
|
|
140
|
-
- `wipeRight`
|
|
141
|
-
- `zoomCut`
|
|
142
|
-
- `fadeThroughBlack`
|
|
143
|
-
- `irisIn`
|
|
144
|
-
- `irisOut`
|
|
145
|
-
|
|
146
|
-
Transitions coordinate timelines across one or more target elements.
|
|
147
|
-
|
|
148
|
-
### `scenes`
|
|
149
|
-
|
|
150
|
-
- `titleCard`
|
|
151
|
-
- `lowerThird`
|
|
152
|
-
- `captionBubble`
|
|
153
|
-
- `comparisonSplit`
|
|
154
|
-
- `deviceFrame`
|
|
155
|
-
- `gridBackground`
|
|
156
|
-
|
|
157
|
-
Scenes create reusable layout fragments and may be combined with motions/effects.
|
|
158
|
-
|
|
159
|
-
## Composition Helpers
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
applyPresetFragments(document, fragments, options?)
|
|
163
|
-
mergePresetFragments(fragments)
|
|
164
|
-
prefixPresetFragment(fragment, prefix)
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Use `prefixPresetFragment` when reusing the same preset more than once:
|
|
168
|
-
|
|
169
|
-
```js
|
|
170
|
-
const a = prefixPresetFragment(shapes.rect({ id: "box", x: 0, y: 0, width: 40, height: 40 }), "a");
|
|
171
|
-
const b = prefixPresetFragment(shapes.rect({ id: "box", x: 50, y: 0, width: 40, height: 40 }), "b");
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
This produces `a.box` and `b.box`.
|
|
175
|
-
|
|
176
|
-
## Authoring Rules
|
|
177
|
-
|
|
178
|
-
- Presets must output only kernel elements and timelines.
|
|
179
|
-
- Presets must not write editor metadata, scene data, lock state, selection state, assets maps, or project state.
|
|
180
|
-
- Presets should emit explicit `graph`, `cubicBezier`, or `hold` curves, not legacy `ease`.
|
|
181
|
-
- Presets should use namespaced IDs for generated children.
|
|
182
|
-
- If a concept does not map cleanly to the kernel, keep it in preset code and compile it away.
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { ArcElement, CircleElement, CurveElement, EllipseElement, Endpoint, GroupElement, LineElement, PointElement, PolygonElement, PolylineElement, RectElement, TextElement, VisualDocument, VisualElement } from "../types";
|
|
2
|
-
export type ElementInput = VisualElement | VisualElement[];
|
|
3
|
-
export declare function scene(input: Omit<VisualDocument, "version"> & {
|
|
4
|
-
version?: 1;
|
|
5
|
-
}): VisualDocument;
|
|
6
|
-
export declare function rect(input: Omit<RectElement, "type">): RectElement;
|
|
7
|
-
export declare function circle(input: Omit<CircleElement, "type">): CircleElement;
|
|
8
|
-
export declare function ellipse(input: Omit<EllipseElement, "type">): EllipseElement;
|
|
9
|
-
export declare function point(input: Omit<PointElement, "type">): PointElement;
|
|
10
|
-
export declare function polyline(input: Omit<PolylineElement, "type">): PolylineElement;
|
|
11
|
-
export declare function polygon(input: Omit<PolygonElement, "type">): PolygonElement;
|
|
12
|
-
export declare function text(input: Omit<TextElement, "type">): TextElement;
|
|
13
|
-
export declare function line(input: Omit<LineElement, "type">): LineElement;
|
|
14
|
-
export declare function arrow(input: Omit<LineElement, "type">): LineElement;
|
|
15
|
-
export declare function arc(input: Omit<ArcElement, "type">): ArcElement;
|
|
16
|
-
export declare function curve(input: Omit<CurveElement, "type">): CurveElement;
|
|
17
|
-
export declare function group(input: Omit<GroupElement, "type">): GroupElement;
|
|
18
|
-
export interface NodeOptions {
|
|
19
|
-
id: string;
|
|
20
|
-
label: string;
|
|
21
|
-
x: number;
|
|
22
|
-
y: number;
|
|
23
|
-
width: number;
|
|
24
|
-
height: number;
|
|
25
|
-
radius?: number;
|
|
26
|
-
fill?: string;
|
|
27
|
-
stroke?: string;
|
|
28
|
-
strokeWidth?: number;
|
|
29
|
-
fontSize?: number;
|
|
30
|
-
textFill?: string;
|
|
31
|
-
}
|
|
32
|
-
export declare function node(options: NodeOptions): [RectElement, TextElement];
|
|
33
|
-
export interface FlowOptions {
|
|
34
|
-
id: string;
|
|
35
|
-
from: Endpoint;
|
|
36
|
-
to: Endpoint;
|
|
37
|
-
stroke?: string;
|
|
38
|
-
strokeWidth?: number;
|
|
39
|
-
label?: string;
|
|
40
|
-
labelX?: number;
|
|
41
|
-
labelY?: number;
|
|
42
|
-
}
|
|
43
|
-
export declare function flow(options: FlowOptions): VisualElement[];
|
|
44
|
-
export interface CalloutOptions {
|
|
45
|
-
id: string;
|
|
46
|
-
text: string;
|
|
47
|
-
x: number;
|
|
48
|
-
y: number;
|
|
49
|
-
width: number;
|
|
50
|
-
height: number;
|
|
51
|
-
target: Endpoint;
|
|
52
|
-
fill?: string;
|
|
53
|
-
textFill?: string;
|
|
54
|
-
stroke?: string;
|
|
55
|
-
}
|
|
56
|
-
export declare function callout(options: CalloutOptions): VisualElement[];
|
|
57
|
-
export interface StackOptions {
|
|
58
|
-
x: number;
|
|
59
|
-
y: number;
|
|
60
|
-
gap?: number;
|
|
61
|
-
children: ElementInput[];
|
|
62
|
-
}
|
|
63
|
-
export declare function row(options: StackOptions): VisualElement[];
|
|
64
|
-
export declare function column(options: StackOptions): VisualElement[];
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.scene = scene;
|
|
4
|
-
exports.rect = rect;
|
|
5
|
-
exports.circle = circle;
|
|
6
|
-
exports.ellipse = ellipse;
|
|
7
|
-
exports.point = point;
|
|
8
|
-
exports.polyline = polyline;
|
|
9
|
-
exports.polygon = polygon;
|
|
10
|
-
exports.text = text;
|
|
11
|
-
exports.line = line;
|
|
12
|
-
exports.arrow = arrow;
|
|
13
|
-
exports.arc = arc;
|
|
14
|
-
exports.curve = curve;
|
|
15
|
-
exports.group = group;
|
|
16
|
-
exports.node = node;
|
|
17
|
-
exports.flow = flow;
|
|
18
|
-
exports.callout = callout;
|
|
19
|
-
exports.row = row;
|
|
20
|
-
exports.column = column;
|
|
21
|
-
const utils_1 = require("../utils");
|
|
22
|
-
function scene(input) {
|
|
23
|
-
return { version: 1, ...input };
|
|
24
|
-
}
|
|
25
|
-
function rect(input) {
|
|
26
|
-
return { type: "rect", ...input };
|
|
27
|
-
}
|
|
28
|
-
function circle(input) {
|
|
29
|
-
return { type: "circle", ...input };
|
|
30
|
-
}
|
|
31
|
-
function ellipse(input) {
|
|
32
|
-
return { type: "ellipse", ...input };
|
|
33
|
-
}
|
|
34
|
-
function point(input) {
|
|
35
|
-
return { type: "point", ...input };
|
|
36
|
-
}
|
|
37
|
-
function polyline(input) {
|
|
38
|
-
return { type: "polyline", ...input };
|
|
39
|
-
}
|
|
40
|
-
function polygon(input) {
|
|
41
|
-
return { type: "polygon", ...input };
|
|
42
|
-
}
|
|
43
|
-
function text(input) {
|
|
44
|
-
return { type: "text", ...input };
|
|
45
|
-
}
|
|
46
|
-
function line(input) {
|
|
47
|
-
return { type: "line", ...input };
|
|
48
|
-
}
|
|
49
|
-
function arrow(input) {
|
|
50
|
-
return { type: "arrow", ...input };
|
|
51
|
-
}
|
|
52
|
-
function arc(input) {
|
|
53
|
-
return { type: "arc", ...input };
|
|
54
|
-
}
|
|
55
|
-
function curve(input) {
|
|
56
|
-
return { type: "curve", ...input };
|
|
57
|
-
}
|
|
58
|
-
function group(input) {
|
|
59
|
-
return { type: "group", ...input };
|
|
60
|
-
}
|
|
61
|
-
function node(options) {
|
|
62
|
-
return [
|
|
63
|
-
rect({
|
|
64
|
-
id: `${options.id}_box`,
|
|
65
|
-
x: options.x,
|
|
66
|
-
y: options.y,
|
|
67
|
-
width: options.width,
|
|
68
|
-
height: options.height,
|
|
69
|
-
radius: options.radius ?? 12,
|
|
70
|
-
fill: options.fill ?? "#ffffff",
|
|
71
|
-
stroke: options.stroke ?? "#2563eb",
|
|
72
|
-
strokeWidth: options.strokeWidth ?? 2
|
|
73
|
-
}),
|
|
74
|
-
text({
|
|
75
|
-
id: `${options.id}_label`,
|
|
76
|
-
text: options.label,
|
|
77
|
-
x: options.x + options.width / 2,
|
|
78
|
-
y: options.y + options.height / 2,
|
|
79
|
-
align: "center",
|
|
80
|
-
valign: "middle",
|
|
81
|
-
fontSize: options.fontSize ?? 18,
|
|
82
|
-
fill: options.textFill ?? "#111827"
|
|
83
|
-
})
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
function flow(options) {
|
|
87
|
-
const out = [
|
|
88
|
-
arrow({
|
|
89
|
-
id: options.id,
|
|
90
|
-
from: options.from,
|
|
91
|
-
to: options.to,
|
|
92
|
-
stroke: options.stroke ?? "#2563eb",
|
|
93
|
-
strokeWidth: options.strokeWidth ?? 2
|
|
94
|
-
})
|
|
95
|
-
];
|
|
96
|
-
if (options.label) {
|
|
97
|
-
if (typeof options.labelX !== "number" || typeof options.labelY !== "number") {
|
|
98
|
-
throw new Error("flow label requires explicit labelX and labelY. The builder does not infer label positions.");
|
|
99
|
-
}
|
|
100
|
-
out.push(text({
|
|
101
|
-
id: `${options.id}_label`,
|
|
102
|
-
text: options.label,
|
|
103
|
-
x: options.labelX,
|
|
104
|
-
y: options.labelY,
|
|
105
|
-
align: "center",
|
|
106
|
-
valign: "middle",
|
|
107
|
-
fontSize: 14,
|
|
108
|
-
fill: options.stroke ?? "#2563eb"
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
return out;
|
|
112
|
-
}
|
|
113
|
-
function callout(options) {
|
|
114
|
-
const boxId = `${options.id}_box`;
|
|
115
|
-
return [
|
|
116
|
-
rect({
|
|
117
|
-
id: boxId,
|
|
118
|
-
x: options.x,
|
|
119
|
-
y: options.y,
|
|
120
|
-
width: options.width,
|
|
121
|
-
height: options.height,
|
|
122
|
-
radius: 8,
|
|
123
|
-
fill: options.fill ?? "#111827",
|
|
124
|
-
stroke: options.stroke ?? "none"
|
|
125
|
-
}),
|
|
126
|
-
text({
|
|
127
|
-
id: `${options.id}_text`,
|
|
128
|
-
text: options.text,
|
|
129
|
-
x: options.x + options.width / 2,
|
|
130
|
-
y: options.y + options.height / 2,
|
|
131
|
-
align: "center",
|
|
132
|
-
valign: "middle",
|
|
133
|
-
fontSize: 15,
|
|
134
|
-
fill: options.textFill ?? "#ffffff"
|
|
135
|
-
}),
|
|
136
|
-
arrow({
|
|
137
|
-
id: `${options.id}_arrow`,
|
|
138
|
-
from: { target: boxId, anchor: (0, utils_1.anchorSpec)("bottom") },
|
|
139
|
-
to: options.target,
|
|
140
|
-
stroke: options.stroke ?? "#ef4444",
|
|
141
|
-
strokeWidth: 2
|
|
142
|
-
})
|
|
143
|
-
];
|
|
144
|
-
}
|
|
145
|
-
function row(options) {
|
|
146
|
-
return stack(options, "row");
|
|
147
|
-
}
|
|
148
|
-
function column(options) {
|
|
149
|
-
return stack(options, "column");
|
|
150
|
-
}
|
|
151
|
-
function stack(options, direction) {
|
|
152
|
-
const gap = options.gap ?? 0;
|
|
153
|
-
let cursorX = options.x;
|
|
154
|
-
let cursorY = options.y;
|
|
155
|
-
const out = [];
|
|
156
|
-
for (const childInput of options.children) {
|
|
157
|
-
const child = Array.isArray(childInput) ? childInput : [childInput];
|
|
158
|
-
const bounds = boundsFor(child);
|
|
159
|
-
if (!bounds)
|
|
160
|
-
throw new Error(`${direction} children must have explicit geometry. No auto measurement is performed.`);
|
|
161
|
-
const dx = cursorX - bounds.x;
|
|
162
|
-
const dy = cursorY - bounds.y;
|
|
163
|
-
const moved = child.map((element) => translateElement(element, dx, dy));
|
|
164
|
-
out.push(...moved);
|
|
165
|
-
if (direction === "row")
|
|
166
|
-
cursorX += bounds.width + gap;
|
|
167
|
-
else
|
|
168
|
-
cursorY += bounds.height + gap;
|
|
169
|
-
}
|
|
170
|
-
return out;
|
|
171
|
-
}
|
|
172
|
-
function boundsFor(elements) {
|
|
173
|
-
const boxes = elements.map((element) => (0, utils_1.elementBox)(element)).filter(Boolean);
|
|
174
|
-
if (!boxes.length)
|
|
175
|
-
return undefined;
|
|
176
|
-
const left = Math.min(...boxes.map((box) => box.x));
|
|
177
|
-
const top = Math.min(...boxes.map((box) => box.y));
|
|
178
|
-
const right = Math.max(...boxes.map((box) => box.x + box.width));
|
|
179
|
-
const bottom = Math.max(...boxes.map((box) => box.y + box.height));
|
|
180
|
-
return { x: left, y: top, width: right - left, height: bottom - top };
|
|
181
|
-
}
|
|
182
|
-
function translateElement(element, dx, dy) {
|
|
183
|
-
const next = (0, utils_1.clone)(element);
|
|
184
|
-
if ("x" in next && typeof next.x === "number")
|
|
185
|
-
next.x += dx;
|
|
186
|
-
if ("y" in next && typeof next.y === "number")
|
|
187
|
-
next.y += dy;
|
|
188
|
-
if ("cx" in next && typeof next.cx === "number")
|
|
189
|
-
next.cx += dx;
|
|
190
|
-
if ("cy" in next && typeof next.cy === "number")
|
|
191
|
-
next.cy += dy;
|
|
192
|
-
if ((next.type === "line" || next.type === "arrow" || next.type === "curve") && Array.isArray(next.from) && Array.isArray(next.to)) {
|
|
193
|
-
next.from = [Number(next.from[0]) + dx, Number(next.from[1]) + dy];
|
|
194
|
-
next.to = [Number(next.to[0]) + dx, Number(next.to[1]) + dy];
|
|
195
|
-
}
|
|
196
|
-
if (next.type === "arc") {
|
|
197
|
-
next.cx += dx;
|
|
198
|
-
next.cy += dy;
|
|
199
|
-
}
|
|
200
|
-
if (next.type === "curve") {
|
|
201
|
-
next.control1 = [next.control1[0] + dx, next.control1[1] + dy];
|
|
202
|
-
if (next.control2)
|
|
203
|
-
next.control2 = [next.control2[0] + dx, next.control2[1] + dy];
|
|
204
|
-
}
|
|
205
|
-
if ((next.type === "polyline" || next.type === "polygon") && Array.isArray(next.points)) {
|
|
206
|
-
next.points = next.points.map((point) => [point[0] + dx, point[1] + dy]);
|
|
207
|
-
}
|
|
208
|
-
if (next.type === "group" && Array.isArray(next.children)) {
|
|
209
|
-
next.children = next.children.map((child) => translateElement(child, dx, dy));
|
|
210
|
-
}
|
|
211
|
-
return next;
|
|
212
|
-
}
|
package/dist/src/compounds.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { VisualDocument } from "./types";
|
|
2
|
-
type LooseElement = Record<string, unknown> & {
|
|
3
|
-
type?: string;
|
|
4
|
-
children?: LooseElement[];
|
|
5
|
-
};
|
|
6
|
-
type LooseDocument = Omit<VisualDocument, "elements" | "scenes"> & {
|
|
7
|
-
elements?: LooseElement[];
|
|
8
|
-
scenes?: Record<string, Record<string, unknown> & {
|
|
9
|
-
elements?: LooseElement[];
|
|
10
|
-
}>;
|
|
11
|
-
};
|
|
12
|
-
export declare function compileCompounds(input: LooseDocument): VisualDocument;
|
|
13
|
-
export {};
|
package/dist/src/compounds.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compileCompounds = compileCompounds;
|
|
4
|
-
const builders_1 = require("./builders");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
|
-
function compileCompounds(input) {
|
|
7
|
-
const document = (0, utils_1.clone)(input);
|
|
8
|
-
const elements = compileElementList(document.elements ?? []);
|
|
9
|
-
const scenes = {};
|
|
10
|
-
for (const [sceneId, scene] of Object.entries(document.scenes ?? {})) {
|
|
11
|
-
scenes[sceneId] = {
|
|
12
|
-
...scene,
|
|
13
|
-
elements: compileElementList(scene.elements ?? [])
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
return {
|
|
17
|
-
...document,
|
|
18
|
-
elements,
|
|
19
|
-
...(Object.keys(scenes).length ? { scenes } : {})
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function compileElementList(elements) {
|
|
23
|
-
return elements.flatMap((element) => compileElement(element));
|
|
24
|
-
}
|
|
25
|
-
function compileElement(element) {
|
|
26
|
-
switch (element.type) {
|
|
27
|
-
case "node":
|
|
28
|
-
return (0, builders_1.node)({
|
|
29
|
-
id: stringProp(element, "id"),
|
|
30
|
-
label: stringProp(element, "label"),
|
|
31
|
-
x: numberProp(element, "x"),
|
|
32
|
-
y: numberProp(element, "y"),
|
|
33
|
-
width: numberProp(element, "width"),
|
|
34
|
-
height: numberProp(element, "height"),
|
|
35
|
-
radius: optionalNumber(element, "radius"),
|
|
36
|
-
fill: optionalString(element, "fill"),
|
|
37
|
-
stroke: optionalString(element, "stroke"),
|
|
38
|
-
strokeWidth: optionalNumber(element, "strokeWidth"),
|
|
39
|
-
fontSize: optionalNumber(element, "fontSize"),
|
|
40
|
-
textFill: optionalString(element, "textFill")
|
|
41
|
-
});
|
|
42
|
-
case "flow":
|
|
43
|
-
return (0, builders_1.flow)({
|
|
44
|
-
id: stringProp(element, "id"),
|
|
45
|
-
from: element.from,
|
|
46
|
-
to: element.to,
|
|
47
|
-
stroke: optionalString(element, "stroke"),
|
|
48
|
-
strokeWidth: optionalNumber(element, "strokeWidth"),
|
|
49
|
-
label: optionalString(element, "label"),
|
|
50
|
-
labelX: optionalNumber(element, "labelX"),
|
|
51
|
-
labelY: optionalNumber(element, "labelY")
|
|
52
|
-
});
|
|
53
|
-
case "packet":
|
|
54
|
-
return [
|
|
55
|
-
(0, builders_1.packet)({
|
|
56
|
-
id: stringProp(element, "id"),
|
|
57
|
-
on: stringProp(element, "on"),
|
|
58
|
-
radius: optionalNumber(element, "radius"),
|
|
59
|
-
fill: optionalString(element, "fill"),
|
|
60
|
-
progress: element.progress
|
|
61
|
-
})
|
|
62
|
-
];
|
|
63
|
-
case "callout":
|
|
64
|
-
return (0, builders_1.callout)({
|
|
65
|
-
id: stringProp(element, "id"),
|
|
66
|
-
text: stringProp(element, "text"),
|
|
67
|
-
x: numberProp(element, "x"),
|
|
68
|
-
y: numberProp(element, "y"),
|
|
69
|
-
width: numberProp(element, "width"),
|
|
70
|
-
height: numberProp(element, "height"),
|
|
71
|
-
target: element.target,
|
|
72
|
-
fill: optionalString(element, "fill"),
|
|
73
|
-
textFill: optionalString(element, "textFill"),
|
|
74
|
-
stroke: optionalString(element, "stroke")
|
|
75
|
-
});
|
|
76
|
-
case "row":
|
|
77
|
-
return (0, builders_1.row)({
|
|
78
|
-
x: numberProp(element, "x"),
|
|
79
|
-
y: numberProp(element, "y"),
|
|
80
|
-
gap: optionalNumber(element, "gap"),
|
|
81
|
-
children: (element.children ?? []).map((child) => compileElement(child))
|
|
82
|
-
});
|
|
83
|
-
case "column":
|
|
84
|
-
return (0, builders_1.column)({
|
|
85
|
-
x: numberProp(element, "x"),
|
|
86
|
-
y: numberProp(element, "y"),
|
|
87
|
-
gap: optionalNumber(element, "gap"),
|
|
88
|
-
children: (element.children ?? []).map((child) => compileElement(child))
|
|
89
|
-
});
|
|
90
|
-
default: {
|
|
91
|
-
const next = (0, utils_1.clone)(element);
|
|
92
|
-
if (next.type === "group" && Array.isArray(next.children)) {
|
|
93
|
-
next.children = compileElementList(next.children);
|
|
94
|
-
}
|
|
95
|
-
return [next];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function stringProp(element, key) {
|
|
100
|
-
const value = element[key];
|
|
101
|
-
if (typeof value !== "string" || !value)
|
|
102
|
-
throw new Error(`Compound '${element.type}' requires string '${key}'.`);
|
|
103
|
-
return value;
|
|
104
|
-
}
|
|
105
|
-
function optionalString(element, key) {
|
|
106
|
-
const value = element[key];
|
|
107
|
-
return typeof value === "string" ? value : undefined;
|
|
108
|
-
}
|
|
109
|
-
function numberProp(element, key) {
|
|
110
|
-
const value = element[key];
|
|
111
|
-
if (typeof value !== "number" || !Number.isFinite(value))
|
|
112
|
-
throw new Error(`Compound '${element.type}' requires number '${key}'.`);
|
|
113
|
-
return value;
|
|
114
|
-
}
|
|
115
|
-
function optionalNumber(element, key) {
|
|
116
|
-
const value = element[key];
|
|
117
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
118
|
-
}
|
package/dist/src/deck.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ResolvedVisualDocument, VisualDocument } from "./types";
|
|
2
|
-
export declare function documentForDeckStep(document: VisualDocument, sceneId: string, stepIndex: number): VisualDocument;
|
|
3
|
-
export declare function resolvedFrameForDeckStep(document: VisualDocument, sceneId: string, stepIndex: number, time?: number): ResolvedVisualDocument;
|
|
4
|
-
export declare function renderDeckToHtml(document: VisualDocument, sceneId: string): string;
|
package/dist/src/deck.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.documentForDeckStep = documentForDeckStep;
|
|
4
|
-
exports.resolvedFrameForDeckStep = resolvedFrameForDeckStep;
|
|
5
|
-
exports.renderDeckToHtml = renderDeckToHtml;
|
|
6
|
-
const scenes_1 = require("./scenes");
|
|
7
|
-
const normalize_1 = require("./normalize");
|
|
8
|
-
const utils_1 = require("./utils");
|
|
9
|
-
const svg_1 = require("./render/svg");
|
|
10
|
-
function documentForDeckStep(document, sceneId, stepIndex) {
|
|
11
|
-
const scene = document.scenes?.[sceneId];
|
|
12
|
-
if (!scene)
|
|
13
|
-
throw new Error(`Unknown scene '${sceneId}'.`);
|
|
14
|
-
const frame = (0, scenes_1.documentForScene)(document, sceneId);
|
|
15
|
-
const activeSteps = (scene.steps ?? []).slice(0, Math.max(0, stepIndex + 1));
|
|
16
|
-
if (!activeSteps.length)
|
|
17
|
-
return frame;
|
|
18
|
-
const hidden = new Set();
|
|
19
|
-
const shown = new Set();
|
|
20
|
-
for (const step of activeSteps) {
|
|
21
|
-
for (const id of step.hide ?? [])
|
|
22
|
-
hidden.add(id);
|
|
23
|
-
for (const id of step.show ?? []) {
|
|
24
|
-
hidden.delete(id);
|
|
25
|
-
shown.add(id);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
frame.elements = applyDeckVisibility(frame.elements ?? [], hidden, shown);
|
|
29
|
-
return frame;
|
|
30
|
-
}
|
|
31
|
-
function resolvedFrameForDeckStep(document, sceneId, stepIndex, time = 0) {
|
|
32
|
-
return (0, normalize_1.resolveVisualFrame)(documentForDeckStep(document, sceneId, stepIndex), time);
|
|
33
|
-
}
|
|
34
|
-
function renderDeckToHtml(document, sceneId) {
|
|
35
|
-
const scene = document.scenes?.[sceneId];
|
|
36
|
-
if (!scene)
|
|
37
|
-
throw new Error(`Unknown scene '${sceneId}'.`);
|
|
38
|
-
const steps = scene.steps ?? [];
|
|
39
|
-
const frameCount = Math.max(1, steps.length + 1);
|
|
40
|
-
const frames = Array.from({ length: frameCount }, (_, index) => {
|
|
41
|
-
const stepIndex = index - 1;
|
|
42
|
-
const frame = stepIndex < 0 ? (0, scenes_1.documentForScene)(document, sceneId) : documentForDeckStep(document, sceneId, stepIndex);
|
|
43
|
-
return (0, svg_1.renderToSvg)(frame);
|
|
44
|
-
});
|
|
45
|
-
const labels = ["Base", ...steps.map((step) => step.id)];
|
|
46
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(sceneId)} Deck</title><style>
|
|
47
|
-
html,body{margin:0;width:100%;height:100%;background:#111827;color:#e5e7eb;font-family:Inter,Arial,sans-serif}
|
|
48
|
-
body{display:grid;grid-template-rows:1fr auto}
|
|
49
|
-
main{display:grid;place-items:center;padding:24px}
|
|
50
|
-
#stage svg{max-width:min(100vw,${document.canvas.width}px);max-height:calc(100vh - 112px);background:white;box-shadow:0 20px 50px rgba(0,0,0,.35)}
|
|
51
|
-
footer{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#020617;border-top:1px solid #1f2937}
|
|
52
|
-
button{border:0;border-radius:6px;padding:8px 12px;background:#2563eb;color:#fff;font-weight:700}
|
|
53
|
-
button:disabled{opacity:.45}
|
|
54
|
-
code{color:#93c5fd}
|
|
55
|
-
</style></head><body><main><div id="stage"></div></main><footer><button id="prev">Prev</button><button id="next">Next</button><span id="count"></span><code id="label"></code></footer><script>
|
|
56
|
-
const frames=${JSON.stringify(frames)};
|
|
57
|
-
const labels=${JSON.stringify(labels)};
|
|
58
|
-
let index=0;
|
|
59
|
-
const stage=document.getElementById("stage");
|
|
60
|
-
const prev=document.getElementById("prev");
|
|
61
|
-
const next=document.getElementById("next");
|
|
62
|
-
const count=document.getElementById("count");
|
|
63
|
-
const label=document.getElementById("label");
|
|
64
|
-
function show(){
|
|
65
|
-
stage.innerHTML=frames[index];
|
|
66
|
-
prev.disabled=index===0;
|
|
67
|
-
next.disabled=index===frames.length-1;
|
|
68
|
-
count.textContent=(index+1)+" / "+frames.length;
|
|
69
|
-
label.textContent=labels[index] || "";
|
|
70
|
-
}
|
|
71
|
-
prev.addEventListener("click",()=>{ index=Math.max(0,index-1); show(); });
|
|
72
|
-
next.addEventListener("click",()=>{ index=Math.min(frames.length-1,index+1); show(); });
|
|
73
|
-
window.addEventListener("keydown",(event)=>{ if(event.key==="ArrowRight") next.click(); if(event.key==="ArrowLeft") prev.click(); });
|
|
74
|
-
show();
|
|
75
|
-
</script></body></html>`;
|
|
76
|
-
}
|
|
77
|
-
function applyDeckVisibility(elements, hidden, shown) {
|
|
78
|
-
return elements.map((element) => {
|
|
79
|
-
const next = (0, utils_1.clone)(element);
|
|
80
|
-
if (next.id && hidden.has(next.id))
|
|
81
|
-
next.opacity = 0;
|
|
82
|
-
if (next.id && shown.has(next.id) && next.opacity === 0)
|
|
83
|
-
next.opacity = 1;
|
|
84
|
-
if (next.type === "group" && Array.isArray(next.children))
|
|
85
|
-
next.children = applyDeckVisibility(next.children, hidden, shown);
|
|
86
|
-
return next;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
function escapeHtml(value) {
|
|
90
|
-
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
91
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ExportOptions, VisualDocument } from "../types";
|
|
2
|
-
export interface ExportResult {
|
|
3
|
-
format: string;
|
|
4
|
-
content: string;
|
|
5
|
-
mimeType: string;
|
|
6
|
-
warnings?: string[];
|
|
7
|
-
}
|
|
8
|
-
export declare function exportVisual(document: VisualDocument, options?: ExportOptions): ExportResult;
|