sketchmark 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/ANIMATABLE_MATRIX.md +177 -0
  2. package/KERNEL_SPEC.md +412 -0
  3. package/PACKS.md +81 -0
  4. package/PRESETS.md +182 -0
  5. package/README.md +274 -188
  6. package/bin/editor-ui.cjs +2285 -0
  7. package/bin/preview-ui.cjs +74 -0
  8. package/bin/sketchmark.cjs +648 -2008
  9. package/dist/src/animatable.d.ts +21 -0
  10. package/dist/src/animatable.js +439 -0
  11. package/dist/src/builders/index.d.ts +1 -11
  12. package/dist/src/builders/index.js +1 -19
  13. package/dist/src/diagnostics.js +1 -64
  14. package/dist/src/edit.d.ts +27 -0
  15. package/dist/src/edit.js +162 -0
  16. package/dist/src/index.d.ts +4 -13
  17. package/dist/src/index.js +4 -13
  18. package/dist/src/keyframes.d.ts +48 -0
  19. package/dist/src/keyframes.js +182 -0
  20. package/dist/src/motion.d.ts +4 -0
  21. package/dist/src/motion.js +262 -0
  22. package/dist/src/normalize.js +120 -151
  23. package/dist/src/presets/characters.d.ts +15 -0
  24. package/dist/src/presets/characters.js +113 -0
  25. package/dist/src/presets/compose.d.ts +5 -0
  26. package/dist/src/presets/compose.js +80 -0
  27. package/dist/src/presets/effects.d.ts +40 -0
  28. package/dist/src/presets/effects.js +79 -0
  29. package/dist/src/presets/helpers.d.ts +33 -0
  30. package/dist/src/presets/helpers.js +165 -0
  31. package/dist/src/presets/index.d.ts +9 -0
  32. package/dist/src/presets/index.js +48 -0
  33. package/dist/src/presets/motions.d.ts +33 -0
  34. package/dist/src/presets/motions.js +75 -0
  35. package/dist/src/presets/scenes.d.ts +35 -0
  36. package/dist/src/presets/scenes.js +134 -0
  37. package/dist/src/presets/shapes.d.ts +71 -0
  38. package/dist/src/presets/shapes.js +96 -0
  39. package/dist/src/presets/transitions.d.ts +29 -0
  40. package/dist/src/presets/transitions.js +113 -0
  41. package/dist/src/presets/types.d.ts +34 -0
  42. package/dist/src/presets/types.js +2 -0
  43. package/dist/src/render/html.js +1 -4
  44. package/dist/src/render/svg.d.ts +2 -2
  45. package/dist/src/render/svg.js +86 -82
  46. package/dist/src/render/three-html.js +67 -113
  47. package/dist/src/scenes.js +1 -0
  48. package/dist/src/schema.js +218 -280
  49. package/dist/src/shapes/builtins.js +11 -47
  50. package/dist/src/shapes/common.js +12 -11
  51. package/dist/src/shapes/registry.d.ts +0 -1
  52. package/dist/src/shapes/registry.js +0 -4
  53. package/dist/src/shapes/types.d.ts +1 -3
  54. package/dist/src/types.d.ts +57 -288
  55. package/dist/src/utils.d.ts +2 -11
  56. package/dist/src/utils.js +13 -70
  57. package/dist/src/validate.js +321 -275
  58. package/dist/tests/run.js +576 -510
  59. package/examples/1730642890464.jpg +0 -0
  60. package/examples/app-screen.svg +1 -0
  61. package/examples/app-screen.visual.json +503 -0
  62. package/examples/dashboard-table.svg +1 -0
  63. package/examples/dashboard-table.visual.json +708 -0
  64. package/examples/dev-docs.svg +1 -0
  65. package/examples/dev-docs.visual.json +248 -0
  66. package/examples/explainer.mp4 +0 -0
  67. package/examples/explainer.visual.json +1713 -0
  68. package/examples/group-origin-effects-lab-check.svg +1 -0
  69. package/examples/group-origin-effects-lab.visual.json +1880 -0
  70. package/examples/image-clip-radius.visual.json +271 -0
  71. package/examples/make-app-screen.cjs +368 -0
  72. package/examples/make-dashboard-table.cjs +277 -0
  73. package/examples/make-dev-docs.cjs +233 -0
  74. package/examples/make-explainer.cjs +438 -0
  75. package/examples/make-group-origin-effects-lab.cjs +370 -0
  76. package/examples/make-image-clip-radius.cjs +169 -0
  77. package/examples/make-modal-dialog.cjs +355 -0
  78. package/examples/make-origin-effects-lab.cjs +311 -0
  79. package/examples/make-preset-character-motion.cjs +32 -0
  80. package/examples/make-presets-demo.cjs +30 -0
  81. package/examples/make-pricing.cjs +286 -0
  82. package/examples/make-product-demo.cjs +468 -0
  83. package/examples/make-product-hero.cjs +223 -0
  84. package/examples/make-release-notes.cjs +333 -0
  85. package/examples/make-settings-panel.cjs +435 -0
  86. package/examples/make-split-preview.cjs +248 -0
  87. package/examples/make-storyboard.cjs +215 -0
  88. package/examples/make-transcript.cjs +234 -0
  89. package/examples/make-typography-test.cjs +397 -0
  90. package/examples/make-ui-demo-explainer.cjs +1094 -0
  91. package/examples/make-ui-flow.cjs +762 -0
  92. package/examples/make-walkthrough.cjs +815 -0
  93. package/examples/modal-dialog.svg +1 -0
  94. package/examples/modal-dialog.visual.json +239 -0
  95. package/examples/origin-effects-lab-check.svg +1 -0
  96. package/examples/origin-effects-lab.visual.json +1412 -0
  97. package/examples/preset-character-motion.visual.json +949 -0
  98. package/examples/presets-demo.visual.json +787 -0
  99. package/examples/pricing.svg +1 -0
  100. package/examples/pricing.visual.json +652 -0
  101. package/examples/product-demo.mp4 +0 -0
  102. package/examples/product-demo.visual.json +866 -0
  103. package/examples/product-hero.svg +1 -0
  104. package/examples/product-hero.visual.json +242 -0
  105. package/examples/release-notes.svg +1 -0
  106. package/examples/release-notes.visual.json +467 -0
  107. package/examples/settings-panel.svg +1 -0
  108. package/examples/settings-panel.visual.json +501 -0
  109. package/examples/split-preview.svg +1 -0
  110. package/examples/split-preview.visual.json +124 -0
  111. package/examples/storyboard.svg +1 -0
  112. package/examples/storyboard.visual.json +312 -0
  113. package/examples/transcript.svg +1 -0
  114. package/examples/transcript.visual.json +407 -0
  115. package/examples/typography-indent-check.svg +1 -0
  116. package/examples/typography-lineheight-0.svg +1 -0
  117. package/examples/typography-lineheight-2.svg +1 -0
  118. package/examples/typography-test-check.svg +1 -0
  119. package/examples/typography-test.svg +1 -0
  120. package/examples/typography-test.visual.json +757 -0
  121. package/examples/ui-demo-explainer-billing.svg +1 -0
  122. package/examples/ui-demo-explainer-check.svg +1 -0
  123. package/examples/ui-demo-explainer-save.svg +1 -0
  124. package/examples/ui-demo-explainer-toggle.svg +1 -0
  125. package/examples/ui-demo-explainer.mp4 +0 -0
  126. package/examples/ui-demo-explainer.visual.json +2597 -0
  127. package/examples/ui-flow.mp4 +0 -0
  128. package/examples/ui-flow.visual.json +1211 -0
  129. package/examples/walkthrough.mp4 +0 -0
  130. package/examples/walkthrough.visual.json +1372 -0
  131. package/package.json +52 -52
  132. package/schema/visual.schema.json +1086 -930
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stickPerson = stickPerson;
4
+ exports.talkingHead = talkingHead;
5
+ exports.simpleDog = simpleDog;
6
+ exports.simpleSpider = simpleSpider;
7
+ exports.cursorHand = cursorHand;
8
+ exports.simpleMascot = simpleMascot;
9
+ const helpers_1 = require("./helpers");
10
+ function stickPerson(options = {}) {
11
+ const id = options.id ?? "person";
12
+ const height = options.height ?? 180;
13
+ const stroke = options.stroke ?? "#111827";
14
+ const headRadius = height * 0.12;
15
+ const hipY = height * 0.58;
16
+ return group(id, options, height * 0.5, height, [
17
+ path(`${id}.head`, (0, helpers_1.ellipsePath)(height * 0.5, headRadius + 2, headRadius, headRadius), { fill: "#ffffff", stroke, strokeWidth: 5 }),
18
+ path(`${id}.body`, (0, helpers_1.linePath)([height * 0.5, headRadius * 2 + 4], [height * 0.48, hipY]), { stroke, strokeWidth: 7 }),
19
+ path(`${id}.leftArm`, (0, helpers_1.linePath)([height * 0.49, height * 0.25], [height * 0.27, height * 0.48]), { stroke, strokeWidth: 6 }),
20
+ path(`${id}.rightArm`, (0, helpers_1.linePath)([height * 0.5, height * 0.25], [height * 0.72, height * 0.48]), { stroke: "#64748b", strokeWidth: 6 }),
21
+ path(`${id}.leftLeg`, (0, helpers_1.linePath)([height * 0.48, hipY], [height * 0.3, height * 0.96]), { stroke: "#64748b", strokeWidth: 7 }),
22
+ path(`${id}.rightLeg`, (0, helpers_1.linePath)([height * 0.48, hipY], [height * 0.68, height * 0.96]), { stroke, strokeWidth: 7 })
23
+ ]);
24
+ }
25
+ function talkingHead(options = {}) {
26
+ const id = options.id ?? "talkingHead";
27
+ const size = options.width ?? options.height ?? 140;
28
+ const stroke = options.stroke ?? "#111827";
29
+ return group(id, options, size, size * 1.1, [
30
+ path(`${id}.shoulders`, `M ${size * 0.18} ${size} C ${size * 0.32} ${size * 0.82} ${size * 0.68} ${size * 0.82} ${size * 0.82} ${size}`, { fill: "none", stroke, strokeWidth: 8 }),
31
+ path(`${id}.head`, (0, helpers_1.ellipsePath)(size * 0.5, size * 0.38, size * 0.28, size * 0.31), { fill: options.fill ?? "#ffffff", stroke, strokeWidth: 5 }),
32
+ path(`${id}.leftEye`, (0, helpers_1.ellipsePath)(size * 0.4, size * 0.34, 3, 3), { fill: stroke }),
33
+ path(`${id}.rightEye`, (0, helpers_1.ellipsePath)(size * 0.6, size * 0.34, 3, 3), { fill: stroke }),
34
+ path(`${id}.mouth`, `M ${size * 0.4} ${size * 0.48} Q ${size * 0.5} ${size * 0.56} ${size * 0.62} ${size * 0.48}`, { fill: "none", stroke, strokeWidth: 4 })
35
+ ]);
36
+ }
37
+ function simpleDog(options = {}) {
38
+ const id = options.id ?? "dog";
39
+ const width = options.width ?? 180;
40
+ const height = options.height ?? 100;
41
+ const stroke = options.stroke ?? "#111827";
42
+ const fur = options.fill ?? "#fbbf24";
43
+ return group(id, options, width, height, [
44
+ path(`${id}.body`, (0, helpers_1.roundedRectPath)(width * 0.18, height * 0.32, width * 0.5, height * 0.28, 18), { fill: fur, stroke, strokeWidth: 4 }),
45
+ path(`${id}.head`, (0, helpers_1.ellipsePath)(width * 0.78, height * 0.35, width * 0.16, height * 0.18), { fill: fur, stroke, strokeWidth: 4 }),
46
+ path(`${id}.ear`, (0, helpers_1.polygonPath)([[width * 0.7, height * 0.22], [width * 0.64, height * 0.02], [width * 0.82, height * 0.2]]), { fill: "#92400e", stroke, strokeWidth: 3 }),
47
+ path(`${id}.tail`, `M ${width * 0.18} ${height * 0.38} Q ${width * 0.04} ${height * 0.22} ${width * 0.08} ${height * 0.12}`, { fill: "none", stroke, strokeWidth: 5 }),
48
+ path(`${id}.frontLeg`, (0, helpers_1.linePath)([width * 0.58, height * 0.58], [width * 0.63, height * 0.95]), { stroke, strokeWidth: 5 }),
49
+ path(`${id}.backLeg`, (0, helpers_1.linePath)([width * 0.3, height * 0.58], [width * 0.24, height * 0.95]), { stroke, strokeWidth: 5 }),
50
+ path(`${id}.eye`, (0, helpers_1.ellipsePath)(width * 0.84, height * 0.32, 3, 3), { fill: stroke })
51
+ ]);
52
+ }
53
+ function simpleSpider(options = {}) {
54
+ const id = options.id ?? "spider";
55
+ const size = options.width ?? options.height ?? 150;
56
+ const stroke = options.stroke ?? "#111827";
57
+ const body = options.fill ?? "#334155";
58
+ const children = [
59
+ path(`${id}.body`, (0, helpers_1.ellipsePath)(size * 0.5, size * 0.48, size * 0.18, size * 0.16), { fill: body, stroke, strokeWidth: 4 }),
60
+ path(`${id}.head`, (0, helpers_1.ellipsePath)(size * 0.68, size * 0.45, size * 0.1, size * 0.1), { fill: body, stroke, strokeWidth: 4 }),
61
+ path(`${id}.eyeLeft`, (0, helpers_1.ellipsePath)(size * 0.7, size * 0.42, 2.5, 2.5), { fill: "#ffffff" }),
62
+ path(`${id}.eyeRight`, (0, helpers_1.ellipsePath)(size * 0.75, size * 0.43, 2.5, 2.5), { fill: "#ffffff" })
63
+ ];
64
+ for (let i = 0; i < 4; i += 1) {
65
+ const y = size * (0.33 + i * 0.08);
66
+ children.push(path(`${id}.leftLeg${i + 1}`, `M ${size * 0.38} ${y} L ${size * 0.17} ${y - size * 0.08} L ${size * 0.08} ${y + size * 0.02}`, { fill: "none", stroke, strokeWidth: 4 }));
67
+ children.push(path(`${id}.rightLeg${i + 1}`, `M ${size * 0.62} ${y} L ${size * 0.85} ${y - size * 0.08} L ${size * 0.94} ${y + size * 0.02}`, { fill: "none", stroke, strokeWidth: 4 }));
68
+ }
69
+ return group(id, options, size, size, children);
70
+ }
71
+ function cursorHand(options = {}) {
72
+ const id = options.id ?? "cursorHand";
73
+ const size = options.width ?? options.height ?? 120;
74
+ const stroke = options.stroke ?? "#111827";
75
+ const d = [
76
+ `M ${size * 0.22} ${size * 0.08}`,
77
+ `L ${size * 0.78} ${size * 0.5}`,
78
+ `L ${size * 0.53} ${size * 0.57}`,
79
+ `L ${size * 0.66} ${size * 0.88}`,
80
+ `L ${size * 0.5} ${size * 0.94}`,
81
+ `L ${size * 0.38} ${size * 0.62}`,
82
+ `L ${size * 0.18} ${size * 0.78}`,
83
+ "Z"
84
+ ].join(" ");
85
+ return group(id, options, size, size, [path(`${id}.shape`, d, { fill: options.fill ?? "#ffffff", stroke, strokeWidth: 4 })]);
86
+ }
87
+ function simpleMascot(options = {}) {
88
+ const id = options.id ?? "mascot";
89
+ const size = options.width ?? options.height ?? 150;
90
+ const stroke = options.stroke ?? "#111827";
91
+ return group(id, options, size, size, [
92
+ path(`${id}.body`, (0, helpers_1.roundedRectPath)(size * 0.22, size * 0.4, size * 0.56, size * 0.44, 24), { fill: options.fill ?? "#bfdbfe", stroke, strokeWidth: 5 }),
93
+ path(`${id}.head`, (0, helpers_1.ellipsePath)(size * 0.5, size * 0.28, size * 0.24, size * 0.22), { fill: "#ffffff", stroke, strokeWidth: 5 }),
94
+ path(`${id}.leftEye`, (0, helpers_1.ellipsePath)(size * 0.42, size * 0.25, 4, 4), { fill: stroke }),
95
+ path(`${id}.rightEye`, (0, helpers_1.ellipsePath)(size * 0.58, size * 0.25, 4, 4), { fill: stroke }),
96
+ path(`${id}.smile`, `M ${size * 0.39} ${size * 0.36} Q ${size * 0.5} ${size * 0.43} ${size * 0.61} ${size * 0.36}`, { fill: "none", stroke, strokeWidth: 4 }),
97
+ path(`${id}.leftArm`, (0, helpers_1.linePath)([size * 0.22, size * 0.5], [size * 0.06, size * 0.66]), { stroke, strokeWidth: 5 }),
98
+ path(`${id}.rightArm`, (0, helpers_1.linePath)([size * 0.78, size * 0.5], [size * 0.94, size * 0.66]), { stroke, strokeWidth: 5 })
99
+ ]);
100
+ }
101
+ function group(id, options, width, height, children) {
102
+ return (0, helpers_1.fragment)([{ id, type: "group", x: options.x ?? 0, y: options.y ?? 0, width, height, children }]);
103
+ }
104
+ function path(id, d, options = {}) {
105
+ return {
106
+ id,
107
+ type: "path",
108
+ d,
109
+ ...(options.fill !== undefined ? { fill: options.fill } : { fill: "none" }),
110
+ ...(options.stroke !== undefined ? { stroke: options.stroke } : {}),
111
+ ...(options.strokeWidth !== undefined ? { strokeWidth: options.strokeWidth } : {})
112
+ };
113
+ }
@@ -0,0 +1,5 @@
1
+ import type { VisualDocument } from "../types";
2
+ import type { ApplyPresetOptions, PresetFragment } from "./types";
3
+ export declare function applyPresetFragments(document: VisualDocument, fragments: PresetFragment | PresetFragment[], options?: ApplyPresetOptions): VisualDocument;
4
+ export declare function mergePresetFragments(fragments: PresetFragment[]): PresetFragment;
5
+ export declare function prefixPresetFragment(fragment: PresetFragment, prefix: string): PresetFragment;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyPresetFragments = applyPresetFragments;
4
+ exports.mergePresetFragments = mergePresetFragments;
5
+ exports.prefixPresetFragment = prefixPresetFragment;
6
+ const validate_1 = require("../validate");
7
+ const helpers_1 = require("./helpers");
8
+ function applyPresetFragments(document, fragments, options = {}) {
9
+ const list = Array.isArray(fragments) ? fragments : [fragments];
10
+ const next = (0, helpers_1.cloneValue)(document);
11
+ next.elements ?? (next.elements = []);
12
+ for (const item of list) {
13
+ for (const element of item.elements ?? [])
14
+ next.elements.push((0, helpers_1.cloneElement)(element));
15
+ }
16
+ const byId = elementMap(next.elements);
17
+ for (const item of list) {
18
+ applyTimelineMap(byId, item.timelines ?? {});
19
+ }
20
+ if (options.validate !== false) {
21
+ const result = (0, validate_1.validateVisualDocument)(next);
22
+ if (!result.ok) {
23
+ const first = result.issues[0];
24
+ throw new Error(first ? `${first.path}: ${first.message}` : "Preset output is not a valid Sketchmark kernel document.");
25
+ }
26
+ }
27
+ return next;
28
+ }
29
+ function mergePresetFragments(fragments) {
30
+ return (0, helpers_1.mergeFragments)(...fragments);
31
+ }
32
+ function prefixPresetFragment(fragment, prefix) {
33
+ const normalizedPrefix = prefix.trim().replace(/\.+$/g, "");
34
+ if (!normalizedPrefix)
35
+ return (0, helpers_1.cloneValue)(fragment);
36
+ const elements = (fragment.elements ?? []).map((element) => prefixElement(element, normalizedPrefix));
37
+ const timelines = {};
38
+ for (const [id, tracks] of Object.entries(fragment.timelines ?? {})) {
39
+ timelines[`${normalizedPrefix}.${id}`] = cloneTracks(tracks);
40
+ }
41
+ return {
42
+ ...(elements.length ? { elements } : {}),
43
+ ...(Object.keys(timelines).length ? { timelines } : {})
44
+ };
45
+ }
46
+ function applyTimelineMap(byId, timelines) {
47
+ var _a;
48
+ for (const [id, tracks] of Object.entries(timelines)) {
49
+ const element = byId.get(id);
50
+ if (!element)
51
+ throw new Error(`Cannot apply preset timeline to unknown element '${id}'.`);
52
+ element.timeline ?? (element.timeline = {});
53
+ (_a = element.timeline).tracks ?? (_a.tracks = {});
54
+ for (const [property, track] of Object.entries(tracks)) {
55
+ element.timeline.tracks[property] = (0, helpers_1.mergeTrack)(element.timeline.tracks[property], track);
56
+ }
57
+ }
58
+ }
59
+ function elementMap(elements) {
60
+ const map = new Map();
61
+ const visit = (element) => {
62
+ if (element.id)
63
+ map.set(element.id, element);
64
+ if (element.type === "group")
65
+ element.children.forEach(visit);
66
+ };
67
+ elements.forEach(visit);
68
+ return map;
69
+ }
70
+ function prefixElement(element, prefix) {
71
+ const next = (0, helpers_1.cloneElement)(element);
72
+ if (next.id)
73
+ next.id = `${prefix}.${next.id}`;
74
+ if (next.type === "group")
75
+ next.children = next.children.map((child) => prefixElement(child, prefix));
76
+ return next;
77
+ }
78
+ function cloneTracks(tracks) {
79
+ return Object.fromEntries(Object.entries(tracks).map(([property, track]) => [property, (0, helpers_1.cloneTrack)(track)]));
80
+ }
@@ -0,0 +1,40 @@
1
+ import type { Point2 } from "../types";
2
+ import type { Box, MotionPresetOptions, PresetFragment } from "./types";
3
+ export interface TargetEffectOptions {
4
+ id: string;
5
+ start?: number;
6
+ }
7
+ export interface ShadowOptions extends TargetEffectOptions {
8
+ dx?: number;
9
+ dy?: number;
10
+ blur?: number;
11
+ color?: string;
12
+ opacity?: number;
13
+ }
14
+ export interface AnimatedEffectOptions extends TargetEffectOptions, MotionPresetOptions {
15
+ }
16
+ export interface RoundedImageClipOptions extends TargetEffectOptions, Box {
17
+ radius?: number;
18
+ radii?: Array<[number, number]>;
19
+ }
20
+ export interface MaskRevealOptions extends TargetEffectOptions, Box, MotionPresetOptions {
21
+ direction?: "left" | "right" | "up" | "down";
22
+ }
23
+ export declare function dropShadow(options: ShadowOptions): PresetFragment;
24
+ export declare function softBlur(options: TargetEffectOptions & {
25
+ amount?: number;
26
+ }): PresetFragment;
27
+ export declare function glow(options: ShadowOptions): PresetFragment;
28
+ export declare function dim(options: AnimatedEffectOptions & {
29
+ opacity?: number;
30
+ }): PresetFragment;
31
+ export declare function tintFill(options: TargetEffectOptions & {
32
+ color?: string;
33
+ }): PresetFragment;
34
+ export declare function gradientSweep(options: AnimatedEffectOptions & {
35
+ from?: Point2;
36
+ to?: Point2;
37
+ colors?: [string, string];
38
+ }): PresetFragment;
39
+ export declare function roundedImageClip(options: RoundedImageClipOptions): PresetFragment;
40
+ export declare function maskReveal(options: MaskRevealOptions): PresetFragment;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dropShadow = dropShadow;
4
+ exports.softBlur = softBlur;
5
+ exports.glow = glow;
6
+ exports.dim = dim;
7
+ exports.tintFill = tintFill;
8
+ exports.gradientSweep = gradientSweep;
9
+ exports.roundedImageClip = roundedImageClip;
10
+ exports.maskReveal = maskReveal;
11
+ const helpers_1 = require("./helpers");
12
+ function dropShadow(options) {
13
+ const time = options.start ?? 0;
14
+ return (0, helpers_1.timelineFragment)(options.id, {
15
+ "effects.shadow.dx": (0, helpers_1.constantTrack)(options.dx ?? 0, time),
16
+ "effects.shadow.dy": (0, helpers_1.constantTrack)(options.dy ?? 8, time),
17
+ "effects.shadow.blur": (0, helpers_1.constantTrack)(options.blur ?? 18, time),
18
+ "effects.shadow.color": (0, helpers_1.constantTrack)(options.color ?? "#000000", time),
19
+ "effects.shadow.opacity": (0, helpers_1.constantTrack)(options.opacity ?? 0.22, time)
20
+ });
21
+ }
22
+ function softBlur(options) {
23
+ return (0, helpers_1.timelineFragment)(options.id, { "effects.blur": (0, helpers_1.constantTrack)(options.amount ?? 6, options.start ?? 0) });
24
+ }
25
+ function glow(options) {
26
+ return dropShadow({ ...options, dx: options.dx ?? 0, dy: options.dy ?? 0, blur: options.blur ?? 24, color: options.color ?? "#38bdf8", opacity: options.opacity ?? 0.55 });
27
+ }
28
+ function dim(options) {
29
+ const start = options.start ?? 0;
30
+ const duration = options.duration ?? 0.25;
31
+ return (0, helpers_1.timelineFragment)(options.id, { opacity: (0, helpers_1.track)([[start, 1], [start + duration, options.opacity ?? 0.35]], options.curve ?? helpers_1.curves.easeOut) });
32
+ }
33
+ function tintFill(options) {
34
+ return (0, helpers_1.timelineFragment)(options.id, { fill: (0, helpers_1.constantTrack)(options.color ?? "#dbeafe", options.start ?? 0) });
35
+ }
36
+ function gradientSweep(options) {
37
+ const start = options.start ?? 0;
38
+ const duration = options.duration ?? 1;
39
+ const from = options.from ?? [0, 0];
40
+ const to = options.to ?? [180, 0];
41
+ const colors = options.colors ?? ["#38bdf8", "#8b5cf6"];
42
+ return (0, helpers_1.timelineFragment)(options.id, {
43
+ fill: (0, helpers_1.track)([
44
+ [start, { type: "linearGradient", from, to, stops: [[0, colors[0]], [1, colors[1]]] }],
45
+ [start + duration, { type: "linearGradient", from: [to[0], to[1]], to: [to[0] + (to[0] - from[0]), to[1] + (to[1] - from[1])], stops: [[0, colors[1]], [1, colors[0]]] }]
46
+ ], options.curve ?? helpers_1.curves.linear)
47
+ });
48
+ }
49
+ function roundedImageClip(options) {
50
+ const keyframes = options.radii?.length
51
+ ? options.radii.map(([time, radius]) => ({ time, value: (0, helpers_1.roundedRectPath)(options.x, options.y, options.width, options.height, radius) }))
52
+ : [{ time: options.start ?? 0, value: (0, helpers_1.roundedRectPath)(options.x, options.y, options.width, options.height, options.radius ?? 12) }];
53
+ return (0, helpers_1.timelineFragment)(options.id, { "clip.d": { keyframes } });
54
+ }
55
+ function maskReveal(options) {
56
+ const start = options.start ?? 0;
57
+ const duration = options.duration ?? 0.7;
58
+ const from = revealPath(options, 0);
59
+ const to = revealPath(options, 1);
60
+ return (0, helpers_1.timelineFragment)(options.id, {
61
+ "mask.d": {
62
+ keyframes: [
63
+ { time: start, value: from, out: options.curve ?? helpers_1.curves.easeOut },
64
+ { time: start + duration, value: to }
65
+ ]
66
+ },
67
+ "mask.opacity": (0, helpers_1.track)([[start, 1], [start + duration, 1]], helpers_1.curves.linear)
68
+ });
69
+ }
70
+ function revealPath(options, progress) {
71
+ const direction = options.direction ?? "right";
72
+ if (direction === "right")
73
+ return (0, helpers_1.roundedRectPath)(options.x, options.y, options.width * progress, options.height, 0);
74
+ if (direction === "left")
75
+ return (0, helpers_1.roundedRectPath)(options.x + options.width * (1 - progress), options.y, options.width * progress, options.height, 0);
76
+ if (direction === "down")
77
+ return (0, helpers_1.roundedRectPath)(options.x, options.y, options.width, options.height * progress, 0);
78
+ return (0, helpers_1.roundedRectPath)(options.x, options.y + options.height * (1 - progress), options.width, options.height * progress, 0);
79
+ }
@@ -0,0 +1,33 @@
1
+ import type { MotionValue, Paint, Point2, TimelineCurve, TimelineKeyframe, TimelineTrack, VisualElement } from "../types";
2
+ import type { PresetFragment, StylePresetOptions } from "./types";
3
+ export declare const curves: {
4
+ linear: TimelineCurve;
5
+ easeIn: TimelineCurve;
6
+ easeOut: TimelineCurve;
7
+ easeInOut: TimelineCurve;
8
+ hold: TimelineCurve;
9
+ };
10
+ export declare function fragment(elements?: VisualElement[]): PresetFragment;
11
+ export declare function timelineFragment(targetId: string, tracks: Record<string, TimelineTrack>): PresetFragment;
12
+ export declare function mergeFragments(...fragments: PresetFragment[]): PresetFragment;
13
+ export declare function track(values: Array<[number, MotionValue]>, curve?: TimelineCurve): TimelineTrack;
14
+ export declare function constantTrack(value: MotionValue, time?: number): TimelineTrack;
15
+ export declare function pathStyle(options?: StylePresetOptions): {
16
+ fill?: Paint;
17
+ stroke?: Paint;
18
+ strokeWidth?: number;
19
+ opacity?: number;
20
+ };
21
+ export declare function rectPath(x: number, y: number, width: number, height: number): string;
22
+ export declare function roundedRectPath(x: number, y: number, width: number, height: number, radius?: number): string;
23
+ export declare function ellipsePath(cx: number, cy: number, rx: number, ry: number): string;
24
+ export declare function polygonPath(points: Point2[], close?: boolean): string;
25
+ export declare function regularPoints(cx: number, cy: number, radius: number, sides: number, rotation?: number): Point2[];
26
+ export declare function starPoints(cx: number, cy: number, outerRadius: number, innerRadius: number, points: number, rotation?: number): Point2[];
27
+ export declare function linePath(from: Point2, to: Point2): string;
28
+ export declare function withPaint(fill: Paint | undefined, fallback: Paint): Paint;
29
+ export declare function keyframeTime(frame: TimelineKeyframe): number;
30
+ export declare function mergeTrack(left: TimelineTrack | undefined, right: TimelineTrack): TimelineTrack;
31
+ export declare function cloneTrack(trackValue: TimelineTrack): TimelineTrack;
32
+ export declare function cloneElement<T extends VisualElement>(element: T): T;
33
+ export declare function cloneValue<T>(value: T): T;
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.curves = void 0;
4
+ exports.fragment = fragment;
5
+ exports.timelineFragment = timelineFragment;
6
+ exports.mergeFragments = mergeFragments;
7
+ exports.track = track;
8
+ exports.constantTrack = constantTrack;
9
+ exports.pathStyle = pathStyle;
10
+ exports.rectPath = rectPath;
11
+ exports.roundedRectPath = roundedRectPath;
12
+ exports.ellipsePath = ellipsePath;
13
+ exports.polygonPath = polygonPath;
14
+ exports.regularPoints = regularPoints;
15
+ exports.starPoints = starPoints;
16
+ exports.linePath = linePath;
17
+ exports.withPaint = withPaint;
18
+ exports.keyframeTime = keyframeTime;
19
+ exports.mergeTrack = mergeTrack;
20
+ exports.cloneTrack = cloneTrack;
21
+ exports.cloneElement = cloneElement;
22
+ exports.cloneValue = cloneValue;
23
+ exports.curves = {
24
+ linear: { type: "graph", points: [[0, 0], [1, 1]] },
25
+ easeIn: { type: "cubicBezier", x1: 0.42, y1: 0, x2: 1, y2: 1 },
26
+ easeOut: { type: "cubicBezier", x1: 0, y1: 0, x2: 0.58, y2: 1 },
27
+ easeInOut: { type: "cubicBezier", x1: 0.42, y1: 0, x2: 0.58, y2: 1 },
28
+ hold: { type: "hold" }
29
+ };
30
+ function fragment(elements = []) {
31
+ return { elements };
32
+ }
33
+ function timelineFragment(targetId, tracks) {
34
+ return { timelines: { [targetId]: tracks } };
35
+ }
36
+ function mergeFragments(...fragments) {
37
+ const elements = fragments.flatMap((item) => item.elements ?? []);
38
+ const timelines = {};
39
+ for (const item of fragments) {
40
+ for (const [id, tracks] of Object.entries(item.timelines ?? {})) {
41
+ timelines[id] ?? (timelines[id] = {});
42
+ for (const [property, track] of Object.entries(tracks)) {
43
+ timelines[id][property] = mergeTrack(timelines[id][property], track);
44
+ }
45
+ }
46
+ }
47
+ return {
48
+ ...(elements.length ? { elements } : {}),
49
+ ...(Object.keys(timelines).length ? { timelines } : {})
50
+ };
51
+ }
52
+ function track(values, curve = exports.curves.linear) {
53
+ return {
54
+ keyframes: values.map(([time, value], index) => ({
55
+ time,
56
+ value,
57
+ ...(index < values.length - 1 ? { out: curve } : {})
58
+ }))
59
+ };
60
+ }
61
+ function constantTrack(value, time = 0) {
62
+ return { keyframes: [{ time, value }] };
63
+ }
64
+ function pathStyle(options = {}) {
65
+ return {
66
+ ...(options.fill !== undefined ? { fill: options.fill } : {}),
67
+ ...(options.stroke !== undefined ? { stroke: options.stroke } : {}),
68
+ ...(options.strokeWidth !== undefined ? { strokeWidth: options.strokeWidth } : {}),
69
+ ...(options.opacity !== undefined ? { opacity: options.opacity } : {})
70
+ };
71
+ }
72
+ function rectPath(x, y, width, height) {
73
+ return `M ${x} ${y} H ${x + width} V ${y + height} H ${x} Z`;
74
+ }
75
+ function roundedRectPath(x, y, width, height, radius = 0) {
76
+ const r = Math.min(Math.max(0, radius), Math.max(0, width) / 2, Math.max(0, height) / 2);
77
+ if (r <= 0)
78
+ return rectPath(x, y, width, height);
79
+ return [
80
+ `M ${x + r} ${y}`,
81
+ `H ${x + width - r}`,
82
+ `Q ${x + width} ${y} ${x + width} ${y + r}`,
83
+ `V ${y + height - r}`,
84
+ `Q ${x + width} ${y + height} ${x + width - r} ${y + height}`,
85
+ `H ${x + r}`,
86
+ `Q ${x} ${y + height} ${x} ${y + height - r}`,
87
+ `V ${y + r}`,
88
+ `Q ${x} ${y} ${x + r} ${y}`,
89
+ "Z"
90
+ ].join(" ");
91
+ }
92
+ function ellipsePath(cx, cy, rx, ry) {
93
+ return `M ${cx - rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx + rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx - rx} ${cy} Z`;
94
+ }
95
+ function polygonPath(points, close = true) {
96
+ if (!points.length)
97
+ return "";
98
+ const commands = [`M ${points[0][0]} ${points[0][1]}`];
99
+ for (const point of points.slice(1))
100
+ commands.push(`L ${point[0]} ${point[1]}`);
101
+ if (close)
102
+ commands.push("Z");
103
+ return commands.join(" ");
104
+ }
105
+ function regularPoints(cx, cy, radius, sides, rotation = -90) {
106
+ const count = Math.max(3, Math.floor(sides));
107
+ const start = (rotation * Math.PI) / 180;
108
+ return Array.from({ length: count }, (_, index) => {
109
+ const angle = start + (index / count) * Math.PI * 2;
110
+ return [cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius];
111
+ });
112
+ }
113
+ function starPoints(cx, cy, outerRadius, innerRadius, points, rotation = -90) {
114
+ const count = Math.max(2, Math.floor(points)) * 2;
115
+ const start = (rotation * Math.PI) / 180;
116
+ return Array.from({ length: count }, (_, index) => {
117
+ const radius = index % 2 === 0 ? outerRadius : innerRadius;
118
+ const angle = start + (index / count) * Math.PI * 2;
119
+ return [cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius];
120
+ });
121
+ }
122
+ function linePath(from, to) {
123
+ return `M ${from[0]} ${from[1]} L ${to[0]} ${to[1]}`;
124
+ }
125
+ function withPaint(fill, fallback) {
126
+ return fill === undefined ? fallback : fill;
127
+ }
128
+ function keyframeTime(frame) {
129
+ return Array.isArray(frame) ? frame[0] : frame.time;
130
+ }
131
+ function mergeTrack(left, right) {
132
+ if (!left)
133
+ return cloneTrack(right);
134
+ const frames = left.keyframes.map(cloneKeyframe);
135
+ for (const frame of right.keyframes) {
136
+ const next = cloneKeyframe(frame);
137
+ const existing = frames.findIndex((item) => keyframeTime(item) === keyframeTime(next));
138
+ if (existing >= 0)
139
+ frames[existing] = next;
140
+ else
141
+ frames.push(next);
142
+ }
143
+ frames.sort((a, b) => keyframeTime(a) - keyframeTime(b));
144
+ return {
145
+ keyframes: frames,
146
+ ...(right.curve ?? left.curve ? { curve: right.curve ?? left.curve } : {}),
147
+ ...(right.ease ?? left.ease ? { ease: right.ease ?? left.ease } : {})
148
+ };
149
+ }
150
+ function cloneTrack(trackValue) {
151
+ return {
152
+ keyframes: trackValue.keyframes.map(cloneKeyframe),
153
+ ...(trackValue.curve ? { curve: cloneValue(trackValue.curve) } : {}),
154
+ ...(trackValue.ease ? { ease: trackValue.ease } : {})
155
+ };
156
+ }
157
+ function cloneElement(element) {
158
+ return cloneValue(element);
159
+ }
160
+ function cloneValue(value) {
161
+ return JSON.parse(JSON.stringify(value));
162
+ }
163
+ function cloneKeyframe(frame) {
164
+ return cloneValue(frame);
165
+ }
@@ -0,0 +1,9 @@
1
+ export type { ApplyPresetOptions, BasePresetOptions, Box, MotionPresetOptions, PointLike, PresetFragment, PresetTimelineMap, StylePresetOptions, TransitionPair } from "./types";
2
+ export { applyPresetFragments, mergePresetFragments, prefixPresetFragment } from "./compose";
3
+ export { curves } from "./helpers";
4
+ export * as shapes from "./shapes";
5
+ export * as characters from "./characters";
6
+ export * as motions from "./motions";
7
+ export * as effects from "./effects";
8
+ export * as transitions from "./transitions";
9
+ export * as scenes from "./scenes";
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scenes = exports.transitions = exports.effects = exports.motions = exports.characters = exports.shapes = exports.curves = exports.prefixPresetFragment = exports.mergePresetFragments = exports.applyPresetFragments = void 0;
37
+ var compose_1 = require("./compose");
38
+ Object.defineProperty(exports, "applyPresetFragments", { enumerable: true, get: function () { return compose_1.applyPresetFragments; } });
39
+ Object.defineProperty(exports, "mergePresetFragments", { enumerable: true, get: function () { return compose_1.mergePresetFragments; } });
40
+ Object.defineProperty(exports, "prefixPresetFragment", { enumerable: true, get: function () { return compose_1.prefixPresetFragment; } });
41
+ var helpers_1 = require("./helpers");
42
+ Object.defineProperty(exports, "curves", { enumerable: true, get: function () { return helpers_1.curves; } });
43
+ exports.shapes = __importStar(require("./shapes"));
44
+ exports.characters = __importStar(require("./characters"));
45
+ exports.motions = __importStar(require("./motions"));
46
+ exports.effects = __importStar(require("./effects"));
47
+ exports.transitions = __importStar(require("./transitions"));
48
+ exports.scenes = __importStar(require("./scenes"));
@@ -0,0 +1,33 @@
1
+ import type { Point2 } from "../types";
2
+ import type { MotionPresetOptions, PresetFragment } from "./types";
3
+ export interface TargetMotionOptions extends MotionPresetOptions {
4
+ id: string;
5
+ }
6
+ export interface MoveMotionOptions extends TargetMotionOptions {
7
+ from?: Point2;
8
+ to?: Point2;
9
+ distance?: number;
10
+ }
11
+ export interface PulseOptions extends TargetMotionOptions {
12
+ amount?: number;
13
+ }
14
+ export interface DrawOnOptions extends TargetMotionOptions {
15
+ from?: number;
16
+ to?: number;
17
+ }
18
+ export interface StaggerOptions extends MotionPresetOptions {
19
+ ids: string[];
20
+ each?: number;
21
+ }
22
+ export declare function fadeIn(options: TargetMotionOptions): PresetFragment;
23
+ export declare function fadeOut(options: TargetMotionOptions): PresetFragment;
24
+ export declare function slideIn(options: MoveMotionOptions): PresetFragment;
25
+ export declare function riseIn(options: MoveMotionOptions): PresetFragment;
26
+ export declare function scaleIn(options: TargetMotionOptions): PresetFragment;
27
+ export declare function pulse(options: PulseOptions): PresetFragment;
28
+ export declare function bob(options: MoveMotionOptions): PresetFragment;
29
+ export declare function shake(options: TargetMotionOptions & {
30
+ amount?: number;
31
+ }): PresetFragment;
32
+ export declare function drawOn(options: DrawOnOptions): PresetFragment;
33
+ export declare function stagger(options: StaggerOptions): PresetFragment;