sketchmark 2.0.0 → 2.1.1
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 +274 -188
- package/bin/editor-ui.cjs +2285 -0
- package/bin/preview-ui.cjs +74 -0
- package/bin/sketchmark.cjs +648 -2008
- package/dist/src/animatable.d.ts +21 -0
- package/dist/src/animatable.js +439 -0
- package/dist/src/builders/index.d.ts +1 -11
- package/dist/src/builders/index.js +1 -19
- package/dist/src/diagnostics.js +1 -64
- package/dist/src/edit.d.ts +27 -0
- package/dist/src/edit.js +162 -0
- package/dist/src/index.d.ts +4 -13
- package/dist/src/index.js +4 -13
- package/dist/src/keyframes.d.ts +48 -0
- package/dist/src/keyframes.js +182 -0
- package/dist/src/motion.d.ts +4 -0
- package/dist/src/motion.js +262 -0
- package/dist/src/normalize.js +120 -151
- package/dist/src/presets/characters.d.ts +15 -0
- package/dist/src/presets/characters.js +113 -0
- package/dist/src/presets/compose.d.ts +5 -0
- package/dist/src/presets/compose.js +80 -0
- package/dist/src/presets/effects.d.ts +40 -0
- package/dist/src/presets/effects.js +79 -0
- package/dist/src/presets/helpers.d.ts +33 -0
- package/dist/src/presets/helpers.js +165 -0
- package/dist/src/presets/index.d.ts +9 -0
- package/dist/src/presets/index.js +48 -0
- package/dist/src/presets/motions.d.ts +33 -0
- package/dist/src/presets/motions.js +75 -0
- package/dist/src/presets/scenes.d.ts +35 -0
- package/dist/src/presets/scenes.js +134 -0
- package/dist/src/presets/shapes.d.ts +71 -0
- package/dist/src/presets/shapes.js +96 -0
- package/dist/src/presets/transitions.d.ts +29 -0
- package/dist/src/presets/transitions.js +113 -0
- package/dist/src/presets/types.d.ts +34 -0
- package/dist/src/presets/types.js +2 -0
- package/dist/src/render/html.js +1 -4
- package/dist/src/render/svg.d.ts +2 -2
- package/dist/src/render/svg.js +86 -82
- package/dist/src/render/three-html.js +67 -113
- package/dist/src/scenes.js +1 -0
- package/dist/src/schema.js +218 -280
- package/dist/src/shapes/builtins.js +11 -47
- package/dist/src/shapes/common.js +12 -11
- package/dist/src/shapes/registry.d.ts +0 -1
- package/dist/src/shapes/registry.js +0 -4
- package/dist/src/shapes/types.d.ts +1 -3
- package/dist/src/types.d.ts +57 -288
- package/dist/src/utils.d.ts +2 -11
- package/dist/src/utils.js +13 -70
- package/dist/src/validate.js +321 -275
- package/dist/tests/run.js +576 -510
- package/package.json +46 -52
- package/schema/visual.schema.json +1086 -930
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fadeIn = fadeIn;
|
|
4
|
+
exports.fadeOut = fadeOut;
|
|
5
|
+
exports.slideIn = slideIn;
|
|
6
|
+
exports.riseIn = riseIn;
|
|
7
|
+
exports.scaleIn = scaleIn;
|
|
8
|
+
exports.pulse = pulse;
|
|
9
|
+
exports.bob = bob;
|
|
10
|
+
exports.shake = shake;
|
|
11
|
+
exports.drawOn = drawOn;
|
|
12
|
+
exports.stagger = stagger;
|
|
13
|
+
const helpers_1 = require("./helpers");
|
|
14
|
+
function fadeIn(options) {
|
|
15
|
+
const start = options.start ?? 0;
|
|
16
|
+
const duration = options.duration ?? 0.4;
|
|
17
|
+
return (0, helpers_1.timelineFragment)(options.id, { opacity: (0, helpers_1.track)([[start, 0], [start + duration, 1]], options.curve ?? helpers_1.curves.easeOut) });
|
|
18
|
+
}
|
|
19
|
+
function fadeOut(options) {
|
|
20
|
+
const start = options.start ?? 0;
|
|
21
|
+
const duration = options.duration ?? 0.4;
|
|
22
|
+
return (0, helpers_1.timelineFragment)(options.id, { opacity: (0, helpers_1.track)([[start, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeIn) });
|
|
23
|
+
}
|
|
24
|
+
function slideIn(options) {
|
|
25
|
+
const start = options.start ?? 0;
|
|
26
|
+
const duration = options.duration ?? 0.6;
|
|
27
|
+
const to = options.to ?? [0, 0];
|
|
28
|
+
const from = options.from ?? [to[0] - (options.distance ?? 80), to[1]];
|
|
29
|
+
return (0, helpers_1.timelineFragment)(options.id, { position: (0, helpers_1.track)([[start, from], [start + duration, to]], options.curve ?? helpers_1.curves.easeOut) });
|
|
30
|
+
}
|
|
31
|
+
function riseIn(options) {
|
|
32
|
+
const start = options.start ?? 0;
|
|
33
|
+
const duration = options.duration ?? 0.55;
|
|
34
|
+
const to = options.to ?? [0, 0];
|
|
35
|
+
const from = options.from ?? [to[0], to[1] + (options.distance ?? 36)];
|
|
36
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.id, { position: (0, helpers_1.track)([[start, from], [start + duration, to]], options.curve ?? helpers_1.curves.easeOut) }), fadeIn({ id: options.id, start, duration: Math.min(duration, 0.35), curve: options.curve ?? helpers_1.curves.easeOut }));
|
|
37
|
+
}
|
|
38
|
+
function scaleIn(options) {
|
|
39
|
+
const start = options.start ?? 0;
|
|
40
|
+
const duration = options.duration ?? 0.5;
|
|
41
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.id, { scale: (0, helpers_1.track)([[start, 0.85], [start + duration, 1]], options.curve ?? helpers_1.curves.easeOut) }), fadeIn({ id: options.id, start, duration: Math.min(duration, 0.3), curve: options.curve ?? helpers_1.curves.easeOut }));
|
|
42
|
+
}
|
|
43
|
+
function pulse(options) {
|
|
44
|
+
const start = options.start ?? 0;
|
|
45
|
+
const duration = options.duration ?? 0.8;
|
|
46
|
+
const amount = options.amount ?? 0.08;
|
|
47
|
+
return (0, helpers_1.timelineFragment)(options.id, { scale: (0, helpers_1.track)([[start, 1], [start + duration * 0.5, 1 + amount], [start + duration, 1]], options.curve ?? helpers_1.curves.easeInOut) });
|
|
48
|
+
}
|
|
49
|
+
function bob(options) {
|
|
50
|
+
const start = options.start ?? 0;
|
|
51
|
+
const duration = options.duration ?? 1.2;
|
|
52
|
+
const base = options.to ?? [0, 0];
|
|
53
|
+
const lift = options.distance ?? 16;
|
|
54
|
+
return (0, helpers_1.timelineFragment)(options.id, { position: (0, helpers_1.track)([[start, base], [start + duration * 0.5, [base[0], base[1] - lift]], [start + duration, base]], options.curve ?? helpers_1.curves.easeInOut) });
|
|
55
|
+
}
|
|
56
|
+
function shake(options) {
|
|
57
|
+
const start = options.start ?? 0;
|
|
58
|
+
const duration = options.duration ?? 0.45;
|
|
59
|
+
const amount = options.amount ?? 8;
|
|
60
|
+
return (0, helpers_1.timelineFragment)(options.id, { x: (0, helpers_1.track)([[start, 0], [start + duration * 0.25, -amount], [start + duration * 0.5, amount], [start + duration * 0.75, -amount * 0.5], [start + duration, 0]], options.curve ?? helpers_1.curves.linear) });
|
|
61
|
+
}
|
|
62
|
+
function drawOn(options) {
|
|
63
|
+
const start = options.start ?? 0;
|
|
64
|
+
const duration = options.duration ?? 0.8;
|
|
65
|
+
return (0, helpers_1.timelineFragment)(options.id, {
|
|
66
|
+
drawStart: (0, helpers_1.track)([[start, options.from ?? 0], [start + duration, options.from ?? 0]], helpers_1.curves.linear),
|
|
67
|
+
drawEnd: (0, helpers_1.track)([[start, options.from ?? 0], [start + duration, options.to ?? 1]], options.curve ?? helpers_1.curves.easeOut)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function stagger(options) {
|
|
71
|
+
const start = options.start ?? 0;
|
|
72
|
+
const duration = options.duration ?? 0.4;
|
|
73
|
+
const each = options.each ?? 0.08;
|
|
74
|
+
return (0, helpers_1.mergeFragments)(...options.ids.map((id, index) => fadeIn({ id, start: start + index * each, duration, curve: options.curve ?? helpers_1.curves.easeOut })));
|
|
75
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BasePresetOptions, PresetFragment } from "./types";
|
|
2
|
+
export interface SceneOptions extends BasePresetOptions {
|
|
3
|
+
x?: number;
|
|
4
|
+
y?: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
export interface TitleCardOptions extends SceneOptions {
|
|
9
|
+
title: string;
|
|
10
|
+
subtitle?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LowerThirdOptions extends SceneOptions {
|
|
13
|
+
title: string;
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CaptionBubbleOptions extends SceneOptions {
|
|
17
|
+
text: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ComparisonSplitOptions extends SceneOptions {
|
|
20
|
+
leftTitle?: string;
|
|
21
|
+
rightTitle?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DeviceFrameOptions extends SceneOptions {
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface GridBackgroundOptions extends SceneOptions {
|
|
27
|
+
step?: number;
|
|
28
|
+
stroke?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function titleCard(options: TitleCardOptions): PresetFragment;
|
|
31
|
+
export declare function lowerThird(options: LowerThirdOptions): PresetFragment;
|
|
32
|
+
export declare function captionBubble(options: CaptionBubbleOptions): PresetFragment;
|
|
33
|
+
export declare function comparisonSplit(options: ComparisonSplitOptions): PresetFragment;
|
|
34
|
+
export declare function deviceFrame(options: DeviceFrameOptions): PresetFragment;
|
|
35
|
+
export declare function gridBackground(options: GridBackgroundOptions): PresetFragment;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.titleCard = titleCard;
|
|
4
|
+
exports.lowerThird = lowerThird;
|
|
5
|
+
exports.captionBubble = captionBubble;
|
|
6
|
+
exports.comparisonSplit = comparisonSplit;
|
|
7
|
+
exports.deviceFrame = deviceFrame;
|
|
8
|
+
exports.gridBackground = gridBackground;
|
|
9
|
+
const helpers_1 = require("./helpers");
|
|
10
|
+
function titleCard(options) {
|
|
11
|
+
const id = options.id ?? "titleCard";
|
|
12
|
+
const x = options.x ?? 0;
|
|
13
|
+
const y = options.y ?? 0;
|
|
14
|
+
const children = [
|
|
15
|
+
path(`${id}.bg`, (0, helpers_1.rectPath)(0, 0, options.width, options.height), { fill: "#0f172a" }),
|
|
16
|
+
text(`${id}.title`, options.title, options.width / 2, options.height * 0.43, 42, "#ffffff", "center"),
|
|
17
|
+
];
|
|
18
|
+
if (options.subtitle)
|
|
19
|
+
children.push(text(`${id}.subtitle`, options.subtitle, options.width / 2, options.height * 0.57, 20, "#cbd5e1", "center"));
|
|
20
|
+
return (0, helpers_1.fragment)([{ id, type: "group", x, y, width: options.width, height: options.height, children }]);
|
|
21
|
+
}
|
|
22
|
+
function lowerThird(options) {
|
|
23
|
+
const id = options.id ?? "lowerThird";
|
|
24
|
+
const x = options.x ?? 0;
|
|
25
|
+
const y = options.y ?? 0;
|
|
26
|
+
const children = [
|
|
27
|
+
path(`${id}.panel`, (0, helpers_1.roundedRectPath)(0, 0, options.width, options.height, 10), { fill: "#ffffff", stroke: "#cbd5e1", strokeWidth: 1 }),
|
|
28
|
+
path(`${id}.accent`, (0, helpers_1.roundedRectPath)(0, 0, 8, options.height, 4), { fill: "#2563eb" }),
|
|
29
|
+
text(`${id}.title`, options.title, 24, options.height * 0.38, 18, "#0f172a", "left")
|
|
30
|
+
];
|
|
31
|
+
if (options.subtitle)
|
|
32
|
+
children.push(text(`${id}.subtitle`, options.subtitle, 24, options.height * 0.68, 13, "#64748b", "left"));
|
|
33
|
+
return (0, helpers_1.fragment)([{ id, type: "group", x, y, width: options.width, height: options.height, children }]);
|
|
34
|
+
}
|
|
35
|
+
function captionBubble(options) {
|
|
36
|
+
const id = options.id ?? "captionBubble";
|
|
37
|
+
const x = options.x ?? 0;
|
|
38
|
+
const y = options.y ?? 0;
|
|
39
|
+
return (0, helpers_1.fragment)([
|
|
40
|
+
{
|
|
41
|
+
id,
|
|
42
|
+
type: "group",
|
|
43
|
+
x,
|
|
44
|
+
y,
|
|
45
|
+
width: options.width,
|
|
46
|
+
height: options.height,
|
|
47
|
+
children: [
|
|
48
|
+
path(`${id}.bubble`, (0, helpers_1.roundedRectPath)(0, 0, options.width, options.height, 14), { fill: "#ffffff", stroke: "#94a3b8", strokeWidth: 1 }),
|
|
49
|
+
text(`${id}.text`, options.text, options.width / 2, options.height / 2, 16, "#111827", "center")
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
function comparisonSplit(options) {
|
|
55
|
+
const id = options.id ?? "comparisonSplit";
|
|
56
|
+
const x = options.x ?? 0;
|
|
57
|
+
const y = options.y ?? 0;
|
|
58
|
+
const half = options.width / 2;
|
|
59
|
+
return (0, helpers_1.fragment)([
|
|
60
|
+
{
|
|
61
|
+
id,
|
|
62
|
+
type: "group",
|
|
63
|
+
x,
|
|
64
|
+
y,
|
|
65
|
+
width: options.width,
|
|
66
|
+
height: options.height,
|
|
67
|
+
children: [
|
|
68
|
+
path(`${id}.left`, (0, helpers_1.rectPath)(0, 0, half, options.height), { fill: "#eff6ff" }),
|
|
69
|
+
path(`${id}.right`, (0, helpers_1.rectPath)(half, 0, half, options.height), { fill: "#f8fafc" }),
|
|
70
|
+
path(`${id}.divider`, (0, helpers_1.linePath)([half, 0], [half, options.height]), { fill: "none", stroke: "#cbd5e1", strokeWidth: 2 }),
|
|
71
|
+
text(`${id}.leftTitle`, options.leftTitle ?? "Before", half / 2, 32, 18, "#0f172a", "center"),
|
|
72
|
+
text(`${id}.rightTitle`, options.rightTitle ?? "After", half + half / 2, 32, 18, "#0f172a", "center")
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
function deviceFrame(options) {
|
|
78
|
+
const id = options.id ?? "deviceFrame";
|
|
79
|
+
const x = options.x ?? 0;
|
|
80
|
+
const y = options.y ?? 0;
|
|
81
|
+
return (0, helpers_1.fragment)([
|
|
82
|
+
{
|
|
83
|
+
id,
|
|
84
|
+
type: "group",
|
|
85
|
+
x,
|
|
86
|
+
y,
|
|
87
|
+
width: options.width,
|
|
88
|
+
height: options.height,
|
|
89
|
+
children: [
|
|
90
|
+
path(`${id}.outer`, (0, helpers_1.roundedRectPath)(0, 0, options.width, options.height, 24), { fill: "#111827", stroke: "#020617", strokeWidth: 2 }),
|
|
91
|
+
path(`${id}.screen`, (0, helpers_1.roundedRectPath)(14, 22, options.width - 28, options.height - 44, 14), { fill: "#f8fafc" }),
|
|
92
|
+
path(`${id}.camera`, (0, helpers_1.ellipsePath)(options.width / 2, 11, 3, 3), { fill: "#475569" }),
|
|
93
|
+
...(options.label ? [text(`${id}.label`, options.label, options.width / 2, options.height - 18, 12, "#94a3b8", "center")] : [])
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
function gridBackground(options) {
|
|
99
|
+
const id = options.id ?? "gridBackground";
|
|
100
|
+
const x = options.x ?? 0;
|
|
101
|
+
const y = options.y ?? 0;
|
|
102
|
+
const step = options.step ?? 32;
|
|
103
|
+
const stroke = options.stroke ?? "#e2e8f0";
|
|
104
|
+
const children = [path(`${id}.bg`, (0, helpers_1.rectPath)(0, 0, options.width, options.height), { fill: "#ffffff" })];
|
|
105
|
+
for (let gx = 0; gx <= options.width; gx += step)
|
|
106
|
+
children.push(path(`${id}.v${Math.round(gx)}`, (0, helpers_1.linePath)([gx, 0], [gx, options.height]), { fill: "none", stroke, strokeWidth: 1 }));
|
|
107
|
+
for (let gy = 0; gy <= options.height; gy += step)
|
|
108
|
+
children.push(path(`${id}.h${Math.round(gy)}`, (0, helpers_1.linePath)([0, gy], [options.width, gy]), { fill: "none", stroke, strokeWidth: 1 }));
|
|
109
|
+
return (0, helpers_1.fragment)([{ id, type: "group", x, y, width: options.width, height: options.height, children }]);
|
|
110
|
+
}
|
|
111
|
+
function path(id, d, options) {
|
|
112
|
+
return {
|
|
113
|
+
id,
|
|
114
|
+
type: "path",
|
|
115
|
+
d,
|
|
116
|
+
...(options.fill !== undefined ? { fill: options.fill } : {}),
|
|
117
|
+
...(options.stroke !== undefined ? { stroke: options.stroke } : {}),
|
|
118
|
+
...(options.strokeWidth !== undefined ? { strokeWidth: options.strokeWidth } : {})
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function text(id, content, x, y, fontSize, fill, align) {
|
|
122
|
+
return {
|
|
123
|
+
id,
|
|
124
|
+
type: "text",
|
|
125
|
+
text: content,
|
|
126
|
+
x,
|
|
127
|
+
y,
|
|
128
|
+
align,
|
|
129
|
+
valign: "middle",
|
|
130
|
+
fontSize,
|
|
131
|
+
weight: 700,
|
|
132
|
+
fill
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Point2 } from "../types";
|
|
2
|
+
import type { BasePresetOptions, PresetFragment, StylePresetOptions } from "./types";
|
|
3
|
+
export interface RectOptions extends BasePresetOptions, StylePresetOptions {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RoundedRectOptions extends RectOptions {
|
|
10
|
+
radius?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface EllipseOptions extends BasePresetOptions, StylePresetOptions {
|
|
13
|
+
cx: number;
|
|
14
|
+
cy: number;
|
|
15
|
+
rx: number;
|
|
16
|
+
ry: number;
|
|
17
|
+
}
|
|
18
|
+
export interface CircleOptions extends BasePresetOptions, StylePresetOptions {
|
|
19
|
+
cx: number;
|
|
20
|
+
cy: number;
|
|
21
|
+
radius: number;
|
|
22
|
+
}
|
|
23
|
+
export interface LineOptions extends BasePresetOptions, StylePresetOptions {
|
|
24
|
+
from: Point2;
|
|
25
|
+
to: Point2;
|
|
26
|
+
strokeCap?: "butt" | "round" | "square";
|
|
27
|
+
}
|
|
28
|
+
export interface PolylineOptions extends BasePresetOptions, StylePresetOptions {
|
|
29
|
+
points: Point2[];
|
|
30
|
+
closed?: boolean;
|
|
31
|
+
strokeCap?: "butt" | "round" | "square";
|
|
32
|
+
strokeJoin?: "miter" | "round" | "bevel";
|
|
33
|
+
}
|
|
34
|
+
export interface ArrowOptions extends BasePresetOptions, StylePresetOptions {
|
|
35
|
+
from: Point2;
|
|
36
|
+
to: Point2;
|
|
37
|
+
headLength?: number;
|
|
38
|
+
headWidth?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface RegularPolygonOptions extends BasePresetOptions, StylePresetOptions {
|
|
41
|
+
cx: number;
|
|
42
|
+
cy: number;
|
|
43
|
+
radius: number;
|
|
44
|
+
sides: number;
|
|
45
|
+
rotation?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface StarOptions extends BasePresetOptions, StylePresetOptions {
|
|
48
|
+
cx: number;
|
|
49
|
+
cy: number;
|
|
50
|
+
outerRadius: number;
|
|
51
|
+
innerRadius?: number;
|
|
52
|
+
points?: number;
|
|
53
|
+
rotation?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SpeechBubbleOptions extends RectOptions {
|
|
56
|
+
radius?: number;
|
|
57
|
+
tail?: Point2;
|
|
58
|
+
text?: string;
|
|
59
|
+
fontSize?: number;
|
|
60
|
+
textFill?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function rect(options: RectOptions): PresetFragment;
|
|
63
|
+
export declare function roundedRect(options: RoundedRectOptions): PresetFragment;
|
|
64
|
+
export declare function ellipse(options: EllipseOptions): PresetFragment;
|
|
65
|
+
export declare function circle(options: CircleOptions): PresetFragment;
|
|
66
|
+
export declare function line(options: LineOptions): PresetFragment;
|
|
67
|
+
export declare function polyline(options: PolylineOptions): PresetFragment;
|
|
68
|
+
export declare function arrow(options: ArrowOptions): PresetFragment;
|
|
69
|
+
export declare function regularPolygon(options: RegularPolygonOptions): PresetFragment;
|
|
70
|
+
export declare function star(options: StarOptions): PresetFragment;
|
|
71
|
+
export declare function speechBubble(options: SpeechBubbleOptions): PresetFragment;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rect = rect;
|
|
4
|
+
exports.roundedRect = roundedRect;
|
|
5
|
+
exports.ellipse = ellipse;
|
|
6
|
+
exports.circle = circle;
|
|
7
|
+
exports.line = line;
|
|
8
|
+
exports.polyline = polyline;
|
|
9
|
+
exports.arrow = arrow;
|
|
10
|
+
exports.regularPolygon = regularPolygon;
|
|
11
|
+
exports.star = star;
|
|
12
|
+
exports.speechBubble = speechBubble;
|
|
13
|
+
const helpers_1 = require("./helpers");
|
|
14
|
+
function rect(options) {
|
|
15
|
+
return (0, helpers_1.fragment)([path(options.id ?? "rect", (0, helpers_1.rectPath)(options.x, options.y, options.width, options.height), { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 1, opacity: options.opacity })]);
|
|
16
|
+
}
|
|
17
|
+
function roundedRect(options) {
|
|
18
|
+
return (0, helpers_1.fragment)([path(options.id ?? "roundedRect", (0, helpers_1.roundedRectPath)(options.x, options.y, options.width, options.height, options.radius ?? 8), { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 1, opacity: options.opacity })]);
|
|
19
|
+
}
|
|
20
|
+
function ellipse(options) {
|
|
21
|
+
return (0, helpers_1.fragment)([path(options.id ?? "ellipse", (0, helpers_1.ellipsePath)(options.cx, options.cy, options.rx, options.ry), { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 1, opacity: options.opacity })]);
|
|
22
|
+
}
|
|
23
|
+
function circle(options) {
|
|
24
|
+
return ellipse({ ...options, rx: options.radius, ry: options.radius, id: options.id ?? "circle" });
|
|
25
|
+
}
|
|
26
|
+
function line(options) {
|
|
27
|
+
return (0, helpers_1.fragment)([path(options.id ?? "line", (0, helpers_1.linePath)(options.from, options.to), { fill: "none", stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 2, strokeCap: options.strokeCap ?? "round", opacity: options.opacity })]);
|
|
28
|
+
}
|
|
29
|
+
function polyline(options) {
|
|
30
|
+
return (0, helpers_1.fragment)([path(options.id ?? "polyline", (0, helpers_1.polygonPath)(options.points, !!options.closed), { fill: options.closed ? (0, helpers_1.withPaint)(options.fill, "none") : "none", stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 2, strokeCap: options.strokeCap ?? "round", strokeJoin: options.strokeJoin ?? "round", opacity: options.opacity })]);
|
|
31
|
+
}
|
|
32
|
+
function arrow(options) {
|
|
33
|
+
const id = options.id ?? "arrow";
|
|
34
|
+
const headLength = options.headLength ?? 16;
|
|
35
|
+
const headWidth = options.headWidth ?? 12;
|
|
36
|
+
const angle = Math.atan2(options.to[1] - options.from[1], options.to[0] - options.from[0]);
|
|
37
|
+
const back = [options.to[0] - Math.cos(angle) * headLength, options.to[1] - Math.sin(angle) * headLength];
|
|
38
|
+
const normal = angle + Math.PI / 2;
|
|
39
|
+
const left = [back[0] + Math.cos(normal) * headWidth * 0.5, back[1] + Math.sin(normal) * headWidth * 0.5];
|
|
40
|
+
const right = [back[0] - Math.cos(normal) * headWidth * 0.5, back[1] - Math.sin(normal) * headWidth * 0.5];
|
|
41
|
+
return (0, helpers_1.fragment)([
|
|
42
|
+
{
|
|
43
|
+
id,
|
|
44
|
+
type: "group",
|
|
45
|
+
x: 0,
|
|
46
|
+
y: 0,
|
|
47
|
+
children: [
|
|
48
|
+
path(`${id}.shaft`, (0, helpers_1.linePath)(options.from, back), { fill: "none", stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 2, strokeCap: "round" }),
|
|
49
|
+
path(`${id}.head`, (0, helpers_1.polygonPath)([options.to, left, right]), { fill: (0, helpers_1.withPaint)(options.fill, options.stroke ?? "#111827"), stroke: options.stroke ?? "#111827", strokeWidth: 1 })
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
function regularPolygon(options) {
|
|
55
|
+
return (0, helpers_1.fragment)([path(options.id ?? "polygon", (0, helpers_1.polygonPath)((0, helpers_1.regularPoints)(options.cx, options.cy, options.radius, options.sides, options.rotation)), { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 1, opacity: options.opacity })]);
|
|
56
|
+
}
|
|
57
|
+
function star(options) {
|
|
58
|
+
const outer = options.outerRadius;
|
|
59
|
+
return (0, helpers_1.fragment)([path(options.id ?? "star", (0, helpers_1.polygonPath)((0, helpers_1.starPoints)(options.cx, options.cy, outer, options.innerRadius ?? outer * 0.45, options.points ?? 5, options.rotation)), { fill: (0, helpers_1.withPaint)(options.fill, "#facc15"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 1, opacity: options.opacity })]);
|
|
60
|
+
}
|
|
61
|
+
function speechBubble(options) {
|
|
62
|
+
const id = options.id ?? "speechBubble";
|
|
63
|
+
const tail = options.tail ?? [options.x + options.width * 0.25, options.y + options.height + 24];
|
|
64
|
+
const tailBaseLeft = [options.x + options.width * 0.25, options.y + options.height - 2];
|
|
65
|
+
const tailBaseRight = [options.x + options.width * 0.38, options.y + options.height - 2];
|
|
66
|
+
const bubble = (0, helpers_1.roundedRectPath)(options.x, options.y, options.width, options.height, options.radius ?? 14);
|
|
67
|
+
const tailPath = (0, helpers_1.polygonPath)([tailBaseLeft, tail, tailBaseRight]);
|
|
68
|
+
const children = [
|
|
69
|
+
path(`${id}.bubble`, bubble, { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 2 }),
|
|
70
|
+
path(`${id}.tail`, tailPath, { fill: (0, helpers_1.withPaint)(options.fill, "#ffffff"), stroke: options.stroke ?? "#111827", strokeWidth: options.strokeWidth ?? 2 })
|
|
71
|
+
];
|
|
72
|
+
if (options.text) {
|
|
73
|
+
children.push({
|
|
74
|
+
id: `${id}.text`,
|
|
75
|
+
type: "text",
|
|
76
|
+
text: options.text,
|
|
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
|
+
return (0, helpers_1.fragment)([{ id, type: "group", x: 0, y: 0, width: options.width, height: options.height, children }]);
|
|
86
|
+
}
|
|
87
|
+
function path(id, d, options = {}) {
|
|
88
|
+
return {
|
|
89
|
+
id,
|
|
90
|
+
type: "path",
|
|
91
|
+
d,
|
|
92
|
+
...(0, helpers_1.pathStyle)(options),
|
|
93
|
+
...(options.strokeCap ? { strokeCap: options.strokeCap } : {}),
|
|
94
|
+
...(options.strokeJoin ? { strokeJoin: options.strokeJoin } : {})
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Point2 } from "../types";
|
|
2
|
+
import type { Box, MotionPresetOptions, PresetFragment, TransitionPair } from "./types";
|
|
3
|
+
export interface TransitionOptions extends TransitionPair, MotionPresetOptions {
|
|
4
|
+
distance?: number;
|
|
5
|
+
fromPosition?: Point2;
|
|
6
|
+
toPosition?: Point2;
|
|
7
|
+
}
|
|
8
|
+
export interface WipeOptions extends TransitionOptions, Box {
|
|
9
|
+
}
|
|
10
|
+
export interface CanvasTransitionOptions extends TransitionOptions {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
id?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface IrisOptions extends MotionPresetOptions, Box {
|
|
16
|
+
id: string;
|
|
17
|
+
cx?: number;
|
|
18
|
+
cy?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function crossfade(options: TransitionOptions): PresetFragment;
|
|
21
|
+
export declare function pushLeft(options: TransitionOptions): PresetFragment;
|
|
22
|
+
export declare function pushRight(options: TransitionOptions): PresetFragment;
|
|
23
|
+
export declare function slideUp(options: TransitionOptions): PresetFragment;
|
|
24
|
+
export declare function wipeLeft(options: WipeOptions): PresetFragment;
|
|
25
|
+
export declare function wipeRight(options: WipeOptions): PresetFragment;
|
|
26
|
+
export declare function zoomCut(options: TransitionOptions): PresetFragment;
|
|
27
|
+
export declare function fadeThroughBlack(options: CanvasTransitionOptions): PresetFragment;
|
|
28
|
+
export declare function irisIn(options: IrisOptions): PresetFragment;
|
|
29
|
+
export declare function irisOut(options: IrisOptions): PresetFragment;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.crossfade = crossfade;
|
|
4
|
+
exports.pushLeft = pushLeft;
|
|
5
|
+
exports.pushRight = pushRight;
|
|
6
|
+
exports.slideUp = slideUp;
|
|
7
|
+
exports.wipeLeft = wipeLeft;
|
|
8
|
+
exports.wipeRight = wipeRight;
|
|
9
|
+
exports.zoomCut = zoomCut;
|
|
10
|
+
exports.fadeThroughBlack = fadeThroughBlack;
|
|
11
|
+
exports.irisIn = irisIn;
|
|
12
|
+
exports.irisOut = irisOut;
|
|
13
|
+
const helpers_1 = require("./helpers");
|
|
14
|
+
function crossfade(options) {
|
|
15
|
+
const start = options.start ?? 0;
|
|
16
|
+
const duration = options.duration ?? 0.5;
|
|
17
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.fromId, { opacity: (0, helpers_1.track)([[start, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeInOut) }), (0, helpers_1.timelineFragment)(options.toId, { opacity: (0, helpers_1.track)([[start, 0], [start + duration, 1]], options.curve ?? helpers_1.curves.easeInOut) }));
|
|
18
|
+
}
|
|
19
|
+
function pushLeft(options) {
|
|
20
|
+
return push(options, -Math.abs(options.distance ?? 120), 0);
|
|
21
|
+
}
|
|
22
|
+
function pushRight(options) {
|
|
23
|
+
return push(options, Math.abs(options.distance ?? 120), 0);
|
|
24
|
+
}
|
|
25
|
+
function slideUp(options) {
|
|
26
|
+
const distance = Math.abs(options.distance ?? 90);
|
|
27
|
+
const start = options.start ?? 0;
|
|
28
|
+
const duration = options.duration ?? 0.5;
|
|
29
|
+
const fromBase = options.fromPosition ?? [0, 0];
|
|
30
|
+
const toBase = options.toPosition ?? [0, 0];
|
|
31
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.fromId, { position: (0, helpers_1.track)([[start, fromBase], [start + duration, [fromBase[0], fromBase[1] - distance]]], options.curve ?? helpers_1.curves.easeInOut), opacity: (0, helpers_1.track)([[start, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeInOut) }), (0, helpers_1.timelineFragment)(options.toId, { position: (0, helpers_1.track)([[start, [toBase[0], toBase[1] + distance]], [start + duration, toBase]], options.curve ?? helpers_1.curves.easeInOut), opacity: (0, helpers_1.track)([[start, 0], [start + duration, 1]], options.curve ?? helpers_1.curves.easeInOut) }));
|
|
32
|
+
}
|
|
33
|
+
function wipeLeft(options) {
|
|
34
|
+
return wipe(options, "left");
|
|
35
|
+
}
|
|
36
|
+
function wipeRight(options) {
|
|
37
|
+
return wipe(options, "right");
|
|
38
|
+
}
|
|
39
|
+
function zoomCut(options) {
|
|
40
|
+
const start = options.start ?? 0;
|
|
41
|
+
const duration = options.duration ?? 0.45;
|
|
42
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.fromId, { scale: (0, helpers_1.track)([[start, 1], [start + duration, 1.08]], options.curve ?? helpers_1.curves.easeIn), opacity: (0, helpers_1.track)([[start, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeIn) }), (0, helpers_1.timelineFragment)(options.toId, { scale: (0, helpers_1.track)([[start, 0.92], [start + duration, 1]], options.curve ?? helpers_1.curves.easeOut), opacity: (0, helpers_1.track)([[start, 0], [start + duration, 1]], options.curve ?? helpers_1.curves.easeOut) }));
|
|
43
|
+
}
|
|
44
|
+
function fadeThroughBlack(options) {
|
|
45
|
+
const start = options.start ?? 0;
|
|
46
|
+
const duration = options.duration ?? 0.8;
|
|
47
|
+
const id = options.id ?? "transition.black";
|
|
48
|
+
return (0, helpers_1.mergeFragments)(crossfade({ fromId: options.fromId, toId: options.toId, start, duration, curve: options.curve ?? helpers_1.curves.easeInOut }), {
|
|
49
|
+
elements: [{ id, type: "path", d: (0, helpers_1.rectPath)(0, 0, options.width, options.height), fill: "#000000", opacity: 0 }],
|
|
50
|
+
timelines: {
|
|
51
|
+
[id]: {
|
|
52
|
+
opacity: (0, helpers_1.track)([[start, 0], [start + duration * 0.5, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeInOut)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function irisIn(options) {
|
|
58
|
+
const start = options.start ?? 0;
|
|
59
|
+
const duration = options.duration ?? 0.8;
|
|
60
|
+
const cx = options.cx ?? options.x + options.width / 2;
|
|
61
|
+
const cy = options.cy ?? options.y + options.height / 2;
|
|
62
|
+
const maxRadius = Math.hypot(options.width, options.height);
|
|
63
|
+
return (0, helpers_1.timelineFragment)(options.id, {
|
|
64
|
+
"clip.d": {
|
|
65
|
+
keyframes: sampledClip(start, duration, 12, (progress) => (0, helpers_1.ellipsePath)(cx, cy, maxRadius * progress, maxRadius * progress), options.curve ?? helpers_1.curves.easeOut)
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function irisOut(options) {
|
|
70
|
+
const start = options.start ?? 0;
|
|
71
|
+
const duration = options.duration ?? 0.8;
|
|
72
|
+
const cx = options.cx ?? options.x + options.width / 2;
|
|
73
|
+
const cy = options.cy ?? options.y + options.height / 2;
|
|
74
|
+
const maxRadius = Math.hypot(options.width, options.height);
|
|
75
|
+
return (0, helpers_1.timelineFragment)(options.id, {
|
|
76
|
+
"clip.d": {
|
|
77
|
+
keyframes: sampledClip(start, duration, 12, (progress) => (0, helpers_1.ellipsePath)(cx, cy, maxRadius * (1 - progress), maxRadius * (1 - progress)), options.curve ?? helpers_1.curves.easeIn)
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function push(options, dx, dy) {
|
|
82
|
+
const start = options.start ?? 0;
|
|
83
|
+
const duration = options.duration ?? 0.55;
|
|
84
|
+
const fromBase = options.fromPosition ?? [0, 0];
|
|
85
|
+
const toBase = options.toPosition ?? [0, 0];
|
|
86
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.fromId, { position: (0, helpers_1.track)([[start, fromBase], [start + duration, [fromBase[0] + dx, fromBase[1] + dy]]], options.curve ?? helpers_1.curves.easeInOut) }), (0, helpers_1.timelineFragment)(options.toId, { position: (0, helpers_1.track)([[start, [toBase[0] - dx, toBase[1] - dy]], [start + duration, toBase]], options.curve ?? helpers_1.curves.easeInOut) }));
|
|
87
|
+
}
|
|
88
|
+
function wipe(options, direction) {
|
|
89
|
+
const start = options.start ?? 0;
|
|
90
|
+
const duration = options.duration ?? 0.6;
|
|
91
|
+
const full = (0, helpers_1.rectPath)(options.x, options.y, options.width, options.height);
|
|
92
|
+
const empty = direction === "right" ? (0, helpers_1.rectPath)(options.x, options.y, 0, options.height) : (0, helpers_1.rectPath)(options.x + options.width, options.y, 0, options.height);
|
|
93
|
+
return (0, helpers_1.mergeFragments)((0, helpers_1.timelineFragment)(options.fromId, { opacity: (0, helpers_1.track)([[start, 1], [start + duration, 0]], options.curve ?? helpers_1.curves.easeInOut) }), (0, helpers_1.timelineFragment)(options.toId, {
|
|
94
|
+
"mask.d": {
|
|
95
|
+
keyframes: [
|
|
96
|
+
{ time: start, value: empty, out: options.curve ?? helpers_1.curves.easeInOut },
|
|
97
|
+
{ time: start + duration, value: full }
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"mask.opacity": (0, helpers_1.track)([[start, 1], [start + duration, 1]], helpers_1.curves.linear),
|
|
101
|
+
opacity: (0, helpers_1.track)([[start, 0], [start + 0.001, 1]], helpers_1.curves.linear)
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
function sampledClip(start, duration, samples, makePath, curve) {
|
|
105
|
+
return Array.from({ length: samples + 1 }, (_, index) => {
|
|
106
|
+
const progress = index / samples;
|
|
107
|
+
return {
|
|
108
|
+
time: start + duration * progress,
|
|
109
|
+
value: makePath(progress),
|
|
110
|
+
...(index < samples ? { out: curve } : {})
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Paint, Point2, TimelineCurve, TimelineTrack, VisualElement } from "../types";
|
|
2
|
+
export type PresetTimelineMap = Record<string, Record<string, TimelineTrack>>;
|
|
3
|
+
export interface PresetFragment {
|
|
4
|
+
elements?: VisualElement[];
|
|
5
|
+
timelines?: PresetTimelineMap;
|
|
6
|
+
}
|
|
7
|
+
export interface ApplyPresetOptions {
|
|
8
|
+
validate?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface BasePresetOptions {
|
|
11
|
+
id?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface StylePresetOptions {
|
|
14
|
+
fill?: Paint;
|
|
15
|
+
stroke?: Paint;
|
|
16
|
+
strokeWidth?: number;
|
|
17
|
+
opacity?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface MotionPresetOptions {
|
|
20
|
+
start?: number;
|
|
21
|
+
duration?: number;
|
|
22
|
+
curve?: TimelineCurve;
|
|
23
|
+
}
|
|
24
|
+
export type TransitionPair = {
|
|
25
|
+
fromId: string;
|
|
26
|
+
toId: string;
|
|
27
|
+
};
|
|
28
|
+
export type Box = {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
};
|
|
34
|
+
export type PointLike = Point2;
|
package/dist/src/render/html.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.renderToHtml = renderToHtml;
|
|
4
|
-
const three_html_1 = require("./three-html");
|
|
5
4
|
const svg_1 = require("./svg");
|
|
6
5
|
function renderToHtml(document, options = {}) {
|
|
7
|
-
if (document.canvas.renderer === "three")
|
|
8
|
-
return (0, three_html_1.renderToThreeHtml)(document, options);
|
|
9
6
|
const svg = (0, svg_1.renderToSvg)(document, options);
|
|
10
7
|
const duration = Number(document.canvas.duration ?? 0);
|
|
11
8
|
const background = options.transparent ? "transparent" : "#111827";
|
|
12
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Sketchmark Visual</title><style>html,body{margin:0;width:100%;height:100%;background:${background};display:grid;place-items:center}.sketchmark-frame{max-width:100vw;max-height:100vh}</style></head><body><div class="sketchmark-frame" data-duration="${duration}">${svg}</div></body></html>`;
|
|
9
|
+
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Sketchmark Kernel Visual</title><style>html,body{margin:0;width:100%;height:100%;background:${background};display:grid;place-items:center}.sketchmark-frame{max-width:100vw;max-height:100vh}</style></head><body><div class="sketchmark-frame" data-duration="${duration}">${svg}</div></body></html>`;
|
|
13
10
|
}
|
package/dist/src/render/svg.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RenderOptions, ResolvedVisualDocument, VisualDocument } from "../types";
|
|
2
2
|
export declare function renderToSvg(document: VisualDocument, options?: RenderOptions): string;
|
|
3
|
-
export declare function renderResolvedSvg(document: ResolvedVisualDocument
|
|
3
|
+
export declare function renderResolvedSvg(document: ResolvedVisualDocument, options?: RenderOptions): string;
|