@pixerate/flair 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @pixerate/flair
2
2
 
3
+ ## 0.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 55fbb80: New `@pixerate/flair/svelte` entry point, with `svelte` (>= 5) as an optional peer dependency (its types only; nothing to compile):
8
+
9
+ - `use:vectorEffect={{ id: "drip-text", values: { word: "Slop" }, loop: false }}` plays a catalog vector effect (or `{ motion }`, any `SvgMotion`) in an element: it makes an `SvgPlayer` on mount, remakes it when the params change (values by content, `speed` without remaking) and disposes it on destroy. Works as an attachment through `fromAction`.
10
+ - `vectorEffectStill(params)` returns `{ markup, style }` for server rendering: `<span use:vectorEffect={params} style={still.style}>{@html still.markup}</span>` shows the last frame, sized from the viewBox, until the player takes over. The still stays under `prefers-reduced-motion` (`reducedMotion` overrides).
11
+ - Sized like the React components: a block with the viewBox's aspect ratio, or with `inline` (or an effect's `inline` control) an `inline-block` 0.72em high.
12
+
13
+ ## 0.15.0
14
+
15
+ ### Minor Changes
16
+
17
+ - 61b2ed6: New `@pixerate/flair/react` entry point, with `react` (>= 18) as an optional peer dependency:
18
+
19
+ - `<VectorEffect id="drip-text" values={{ word: "Slop" }} loop={false} />` plays a catalog vector effect; `<SvgPlayerView motion={...} />` plays any `SvgMotion`. Each makes an `SvgPlayer` after mount and disposes it on unmount.
20
+ - Server-renders a still of the last frame, sized from the viewBox, so hydration neither shifts the layout nor flashes blank. The still stays under `prefers-reduced-motion` (`reducedMotion` overrides).
21
+ - `inline` (or an effect's `inline` control, like drip text's) sizes it as a word in a line: `inline-block`, 0.72em high, with the viewBox's aspect ratio.
22
+
23
+ `@pixerate/flair/vector` adds `svgFrameMarkup(motion, { at })`, a frame as safe `<svg>` markup with no DOM (for server rendering and reduced motion), and `svgViewBox` / `parseViewBox`.
24
+
3
25
  ## 0.14.0
4
26
 
5
27
  ### Minor Changes
package/README.md CHANGED
@@ -43,7 +43,9 @@ Flair gives products a library of good-looking, configurable visual effects (her
43
43
  | :--- | :--- | :--- |
44
44
  | `@pixerate/flair` | Shader engine, vector motion, time and easing, colour, blending, transitions, scenes, interchange exporters | None (browser-safe) |
45
45
  | `@pixerate/flair/catalog` | `EFFECTS`, `getEffect`, `findEffects`, `effectDefaults`, `renderVectorEffect`, `vectorControls`, GLSL helpers, sample images, `textImage` | None |
46
- | `@pixerate/flair/vector` | `SvgMotion`, `svgFrame`, `svgView`, `SvgPlayer`, `animateCount`, `formatCount`, `morphPaths`, `morphSequence`, `svgMotionIssues` | None |
46
+ | `@pixerate/flair/vector` | `SvgMotion`, `svgFrame`, `svgView`, `SvgPlayer`, `svgFrameMarkup`, `svgViewBox`, `animateCount`, `formatCount`, `morphPaths`, `morphSequence`, `svgMotionIssues` | None |
47
+ | `@pixerate/flair/react` | `<VectorEffect>`, `<SvgPlayerView>`: vector effects as React components, server-rendered as a still | `react` ≥ 18 (optional peer) |
48
+ | `@pixerate/flair/svelte` | `vectorEffect` action, `vectorEffectStill`: vector effects in Svelte, server-rendered as a still | `svelte` ≥ 5 (optional peer; types only) |
47
49
  | `@pixerate/flair/editor` | `EffectEditor`, effect documents, keyframe tracks, renderer bindings, parameter-panel binding, agent tools and instructions | `@pixerate/editor` ≥ 0.29 (optional peer; only its dependency-free `/history`, `/commands`, `/tools`, `/animation` and `/parameters` subpaths) |
48
50
  | `@pixerate/flair/node` | `exportMotionGraphic`: renders a shader to GIF/MP4 through headless Chrome and ffmpeg | Node.js |
49
51
 
@@ -149,6 +151,45 @@ Overlay shaders (`category: "overlay"`) have `transparent: true`: they write cov
149
151
 
150
152
  To morph between any two SVG shapes, `morphPaths(from, to)` (from `@pixerate/flair/vector`) returns two paths with one structure, so `attrs: { d: [a, b] }` blends them point by point: curves and arcs are read, pieces are paired by position and size, and a piece with no partner grows from or shrinks to a point (draw them with `fill-rule="evenodd"`). `morphSequence` does the same for three or more shapes. `feature-morph` morphs two photos from five matching points, and `silhouette-morph` morphs any two silhouettes or logos (or words, through `textImage`).
151
153
 
154
+ ### React
155
+
156
+ `@pixerate/flair/react` wraps the player, so a page needs no ref, effect or dispose of its own. `<VectorEffect>` plays a catalog vector effect by id, `<SvgPlayerView>` any `SvgMotion`:
157
+
158
+ ```tsx
159
+ import { VectorEffect } from "@pixerate/flair/react";
160
+
161
+ <h1>
162
+ Stop the <VectorEffect id="drip-text" values={{ word: "Slop", inline: true, font: "inherit" }} loop={false} />
163
+ </h1>;
164
+ ```
165
+
166
+ - **Server rendering**: both render a still of the last frame as markup (`"first"` for hover and press triggers; set `poster` for another), sized from the viewBox, so the page hydrates with the picture in place. The `SvgPlayer` takes over after mount and is disposed on unmount.
167
+ - **Reduced motion**: under `prefers-reduced-motion: reduce` the still stays. `reducedMotion="always"` or `"never"` overrides it.
168
+ - **Size**: a block as wide as its container, with the viewBox's aspect ratio. With `inline` (or an effect whose `inline` control is on, like drip text's) it is an `inline-block` 0.72em high, sitting on the baseline like a capital letter; pass a CSS length to `inline` for another height.
169
+ - **Props**: player options (`loop`, `autoplay`, `speed`, `hold`, `trigger`, `steps`, `pauseWhenHidden`, `playOnEnter`, `clock` …), `values` and `preset` for an effect, `onPlayer` for the player itself, and any `<span>` attribute (`elementId` sets the host's `id` on `<VectorEffect>`). Values are compared by content, so an inline object does not restart it; pass `<SvgPlayerView>` a memoised `motion`.
170
+
171
+ Without React or Svelte, `svgFrameMarkup(motion, { at: "last" })` (from `@pixerate/flair/vector`) gives the same still as safe `<svg>` markup with no DOM, for any server or framework.
172
+
173
+ ### Svelte
174
+
175
+ `@pixerate/flair/svelte` does the same for Svelte 5, as plain TypeScript (no `.svelte` files, so nothing to compile). The `vectorEffect` action plays an effect by `id` (or any `motion`) in its element, and `vectorEffectStill` gives the server-rendered still:
176
+
177
+ ```svelte
178
+ <script>
179
+ import { vectorEffect, vectorEffectStill } from "@pixerate/flair/svelte";
180
+
181
+ let { word = "Slop" } = $props();
182
+ const params = $derived({ id: "drip-text", values: { word, inline: true, font: "inherit" }, loop: false });
183
+ const still = $derived(vectorEffectStill(params));
184
+ </script>
185
+
186
+ <h1>Stop the <span use:vectorEffect={params} style={still.style}>{@html still.markup}</span></h1>
187
+ ```
188
+
189
+ - **Params**: the React props, as one object: `id` with `values` and `preset`, or `motion`; player options; `poster`, `reducedMotion`, `inline`, `onPlayer`. A change remakes the player (values by content; `speed` without remaking), and it is disposed when the element goes.
190
+ - **Still**: `markup` is the still's layer and `style` the host's size from the viewBox, with the same rules as React. The action hides the still while the player runs and keeps it under `prefers-reduced-motion`. Without `vectorEffectStill` it makes its own still and sizes the element on the client.
191
+ - **Attachments**: `{@attach fromAction(vectorEffect, () => params)}`, with `fromAction` from `svelte/attachments`.
192
+
152
193
  `shader-text` fills letters from a text image: set its `uText` control to `textImage("Your title", { weight: 900 })`, a transparent SVG `data:` URL of any Unicode text.
153
194
 
154
195
  A vector effect declares its controls in its picture, the way a shader declares its uniforms: the first `{{name: type …}}` declares a control (`float`, `int`, `bool`, `color` or `text`, with `@control`'s attributes; quote values with spaces in single quotes), and every `{{name}}` is filled with its value. Declarations can sit in an XML comment, which is dropped when the picture is filled in, and text is escaped, so any words are safe:
@@ -1,7 +1,7 @@
1
1
  import { a as ControlDef, C as ControlValue } from '../controls-Syr6drzO.js';
2
- import { E as EffectDefinition, a as EffectCategory, S as ShaderEffect } from '../types-CGsNkP5U.js';
3
- export { b as EFFECT_CATEGORIES, c as EffectPreset, V as VECTOR_CONTROL_TYPES, d as VectorControl, e as VectorEffect, f as colorControl, n as numberControl, r as renderVectorEffect, v as vectorControlDef, g as vectorControlIssues, h as vectorControls, i as vectorEffectControls } from '../types-CGsNkP5U.js';
4
- import '../svg-C_TWBtEN.js';
2
+ import { E as EffectDefinition, a as EffectCategory, S as ShaderEffect } from '../types-9J6NWaN3.js';
3
+ export { b as EFFECT_CATEGORIES, c as EffectPreset, d as VECTOR_CONTROL_TYPES, e as VectorControl, V as VectorEffect, f as colorControl, n as numberControl, r as renderVectorEffect, v as vectorControlDef, g as vectorControlIssues, h as vectorControls, i as vectorEffectControls } from '../types-9J6NWaN3.js';
4
+ import '../svg-XugR-6Ec.js';
5
5
 
6
6
  /**
7
7
  * Sample pictures for the catalog's image effects: small SVGs as `data:` URLs,
@@ -0,0 +1,137 @@
1
+ import {
2
+ SVG_PICTURE,
3
+ svgDuration,
4
+ svgFrame
5
+ } from "./chunk-4RGHZWQC.js";
6
+
7
+ // src/vector/static.ts
8
+ var DROPPED = /* @__PURE__ */ new Set(["script", "foreignobject", "iframe", "object", "embed"]);
9
+ var ATTR = /([^\s=/>"']+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>"']+)))?/g;
10
+ var TOKEN = /<!--[\s\S]*?(?:-->|$)|<!\[CDATA\[([\s\S]*?)(?:\]\]>|$)|<[!?][^>]*>|<\/\s*([\w:.-]+)\s*>|<([\w:.-]+)((?:\s+[^\s=/>"']+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>"']+))?)*)\s*(\/?)>/g;
11
+ var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: "\xA0" };
12
+ var decode = (s) => s.replace(/&(#x[0-9a-f]+|#\d+|\w+);/gi, (match, e) => {
13
+ if (e[0] !== "#") return ENTITIES[e.toLowerCase()] ?? match;
14
+ const code = e[1] === "x" || e[1] === "X" ? parseInt(e.slice(2), 16) : parseInt(e.slice(1), 10);
15
+ return code > 0 && code <= 1114111 ? String.fromCodePoint(code) : "";
16
+ });
17
+ var escapeText = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
18
+ var escapeAttr = (s) => escapeText(s).replace(/"/g, "&quot;");
19
+ function safeAttr(name, value) {
20
+ const n = name.toLowerCase();
21
+ if (n.startsWith("on") || !/^[a-z_][\w:.-]*$/i.test(n)) return false;
22
+ if (n === "href" || n === "xlink:href" || n === "src") return /^(#|data:image\/)/i.test(value.trim());
23
+ return true;
24
+ }
25
+ function parse(markup) {
26
+ const root = { tag: "", attrs: [], children: [] };
27
+ const stack = [root];
28
+ let dropping = 0;
29
+ let at = 0;
30
+ const text = (s) => {
31
+ if (!dropping && s) stack[stack.length - 1].children.push(decode(s));
32
+ };
33
+ for (const m of markup.matchAll(TOKEN)) {
34
+ text(markup.slice(at, m.index));
35
+ at = m.index + m[0].length;
36
+ const [, cdata, close, open, attrs = "", selfClosing] = m;
37
+ if (cdata !== void 0) {
38
+ if (!dropping) stack[stack.length - 1].children.push(cdata);
39
+ } else if (close) {
40
+ const tag = close.toLowerCase();
41
+ if (dropping) {
42
+ if (DROPPED.has(tag)) dropping--;
43
+ continue;
44
+ }
45
+ let i = stack.length - 1;
46
+ while (i > 0 && stack[i].tag.toLowerCase() !== tag) i--;
47
+ if (i > 0) stack.length = i;
48
+ } else if (open) {
49
+ if (DROPPED.has(open.toLowerCase())) {
50
+ if (!selfClosing) dropping++;
51
+ continue;
52
+ }
53
+ if (dropping) continue;
54
+ const node = { tag: open, attrs: [], children: [] };
55
+ for (const a of attrs.matchAll(ATTR)) {
56
+ const value = decode(a[2] ?? a[3] ?? a[4] ?? "");
57
+ if (safeAttr(a[1], value)) node.attrs.push([a[1], value]);
58
+ }
59
+ stack[stack.length - 1].children.push(node);
60
+ if (!selfClosing) stack.push(node);
61
+ }
62
+ }
63
+ text(markup.slice(at));
64
+ const svg = root.children.find((c) => typeof c !== "string");
65
+ return svg && svg.tag.toLowerCase() === "svg" ? svg : void 0;
66
+ }
67
+ function serialize(node) {
68
+ if (typeof node === "string") return escapeText(node);
69
+ const attrs = node.attrs.map(([k, v]) => ` ${k}="${escapeAttr(v)}"`).join("");
70
+ return `<${node.tag}${attrs}>${node.children.map(serialize).join("")}</${node.tag}>`;
71
+ }
72
+ function setAttr(node, name, value) {
73
+ const i = node.attrs.findIndex(([k]) => k === name);
74
+ if (value === void 0) {
75
+ if (i >= 0) node.attrs.splice(i, 1);
76
+ } else if (!safeAttr(name, value)) return;
77
+ else if (i >= 0) node.attrs[i][1] = value;
78
+ else node.attrs.push([name, value]);
79
+ }
80
+ var getAttr = (node, name) => node.attrs.find(([k]) => k === name)?.[1];
81
+ function parseViewBox(value) {
82
+ const box = (value ?? "").trim().split(/[\s,]+/).map(Number);
83
+ return box.length === 4 && box.every(Number.isFinite) && box[2] > 0 && box[3] > 0 ? box : void 0;
84
+ }
85
+ function svgViewBox(markup) {
86
+ const open = /<svg\b[^>]*>/i.exec(markup)?.[0] ?? "";
87
+ return parseViewBox(/\sviewBox\s*=\s*(?:"([^"]*)"|'([^']*)')/i.exec(open)?.slice(1).find((v) => v !== void 0));
88
+ }
89
+ function svgFrameMarkup(motion, options = {}) {
90
+ const svg = parse(motion.svg.trim());
91
+ if (!svg) return void 0;
92
+ const steps = options.steps ?? [];
93
+ const at = options.at ?? "last";
94
+ const time = at === "first" ? 0 : at === "last" ? svgDuration(motion, steps) : at;
95
+ const byId = /* @__PURE__ */ new Map();
96
+ const index = (node) => {
97
+ const id = getAttr(node, "id");
98
+ if (id && !byId.has(id)) byId.set(id, node);
99
+ for (const c of node.children) if (typeof c !== "string") index(c);
100
+ };
101
+ index(svg);
102
+ const whole = parseViewBox(getAttr(svg, "viewBox"));
103
+ for (const [id, frame] of svgFrame(motion.animate ?? [], steps, time)) {
104
+ if (id === SVG_PICTURE && frame.view) {
105
+ const { from, to, u } = frame.view;
106
+ const a = from === null ? whole : typeof from === "string" ? void 0 : from;
107
+ const b = typeof to === "string" ? void 0 : to;
108
+ if (a && b) setAttr(svg, "viewBox", a.map((n, i) => +(n + (b[i] - n) * u).toFixed(2)).join(" "));
109
+ continue;
110
+ }
111
+ const el = byId.get(id);
112
+ if (!el) continue;
113
+ for (const [name, value] of Object.entries(frame.attrs)) setAttr(el, name, value);
114
+ if (frame.draw !== void 0) {
115
+ setAttr(el, "pathLength", "1");
116
+ setAttr(el, "stroke-dasharray", "1 1");
117
+ setAttr(el, "stroke-dashoffset", String(1 - frame.draw));
118
+ }
119
+ if (frame.text !== void 0) el.children = [frame.text];
120
+ if (frame.solo !== void 0) {
121
+ let i = 0;
122
+ for (const child of el.children)
123
+ if (typeof child !== "string") setAttr(child, "display", i++ === frame.solo ? void 0 : "none");
124
+ }
125
+ }
126
+ setAttr(svg, "width", "100%");
127
+ setAttr(svg, "height", "100%");
128
+ if (!getAttr(svg, "xmlns")) setAttr(svg, "xmlns", "http://www.w3.org/2000/svg");
129
+ return serialize(svg);
130
+ }
131
+
132
+ export {
133
+ parseViewBox,
134
+ svgViewBox,
135
+ svgFrameMarkup
136
+ };
137
+ //# sourceMappingURL=chunk-DVVQRZJ5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vector/static.ts"],"sourcesContent":["/**\n * An {@link SvgMotion}'s frame as markup, with no DOM: for server rendering\n * (a still that hydrates without a blank flash), reduced motion and other\n * places a live player is not wanted.\n */\n\nimport { SVG_PICTURE, svgFrame, type SvgBox, type SvgMotion } from \"./motion.js\";\nimport { svgDuration } from \"./svg.js\";\n\ninterface Node {\n tag: string;\n attrs: [string, string][];\n children: (Node | string)[];\n}\n\n/** Elements dropped with all they hold: they run code or show outside markup. */\nconst DROPPED = new Set([\"script\", \"foreignobject\", \"iframe\", \"object\", \"embed\"]);\nconst ATTR = /([^\\s=/>\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>\"']+)))?/g;\nconst TOKEN = /<!--[\\s\\S]*?(?:-->|$)|<!\\[CDATA\\[([\\s\\S]*?)(?:\\]\\]>|$)|<[!?][^>]*>|<\\/\\s*([\\w:.-]+)\\s*>|<([\\w:.-]+)((?:\\s+[^\\s=/>\"']+(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s>\"']+))?)*)\\s*(\\/?)>/g;\n\nconst ENTITIES: Record<string, string> = { amp: \"&\", lt: \"<\", gt: \">\", quot: '\"', apos: \"'\", nbsp: \" \" };\nconst decode = (s: string) =>\n s.replace(/&(#x[0-9a-f]+|#\\d+|\\w+);/gi, (match, e: string) => {\n if (e[0] !== \"#\") return ENTITIES[e.toLowerCase()] ?? match;\n const code = e[1] === \"x\" || e[1] === \"X\" ? parseInt(e.slice(2), 16) : parseInt(e.slice(1), 10);\n return code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : \"\";\n });\nconst escapeText = (s: string) => s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\nconst escapeAttr = (s: string) => escapeText(s).replace(/\"/g, \"&quot;\");\n\n/** Safe as `parseSvg` keeps it: no handlers, and links only within the picture or to data images. */\nfunction safeAttr(name: string, value: string): boolean {\n const n = name.toLowerCase();\n if (n.startsWith(\"on\") || !/^[a-z_][\\w:.-]*$/i.test(n)) return false;\n if (n === \"href\" || n === \"xlink:href\" || n === \"src\") return /^(#|data:image\\/)/i.test(value.trim());\n return true;\n}\n\n/** The `<svg>` in `markup` as a tree, without anything `parseSvg` would remove. */\nfunction parse(markup: string): Node | undefined {\n const root: Node = { tag: \"\", attrs: [], children: [] };\n const stack = [root];\n let dropping = 0;\n let at = 0;\n const text = (s: string) => {\n if (!dropping && s) stack[stack.length - 1]!.children.push(decode(s));\n };\n for (const m of markup.matchAll(TOKEN)) {\n text(markup.slice(at, m.index));\n at = m.index + m[0].length;\n const [, cdata, close, open, attrs = \"\", selfClosing] = m;\n if (cdata !== undefined) {\n if (!dropping) stack[stack.length - 1]!.children.push(cdata);\n } else if (close) {\n const tag = close.toLowerCase();\n if (dropping) {\n if (DROPPED.has(tag)) dropping--;\n continue;\n }\n // Close up to the matching element; a stray closing tag is ignored.\n let i = stack.length - 1;\n while (i > 0 && stack[i]!.tag.toLowerCase() !== tag) i--;\n if (i > 0) stack.length = i;\n } else if (open) {\n if (DROPPED.has(open.toLowerCase())) {\n if (!selfClosing) dropping++;\n continue;\n }\n if (dropping) continue;\n const node: Node = { tag: open, attrs: [], children: [] };\n for (const a of attrs.matchAll(ATTR)) {\n const value = decode(a[2] ?? a[3] ?? a[4] ?? \"\");\n if (safeAttr(a[1]!, value)) node.attrs.push([a[1]!, value]);\n }\n stack[stack.length - 1]!.children.push(node);\n if (!selfClosing) stack.push(node);\n }\n }\n text(markup.slice(at));\n const svg = root.children.find((c): c is Node => typeof c !== \"string\");\n return svg && svg.tag.toLowerCase() === \"svg\" ? svg : undefined;\n}\n\nfunction serialize(node: Node | string): string {\n if (typeof node === \"string\") return escapeText(node);\n const attrs = node.attrs.map(([k, v]) => ` ${k}=\"${escapeAttr(v)}\"`).join(\"\");\n return `<${node.tag}${attrs}>${node.children.map(serialize).join(\"\")}</${node.tag}>`;\n}\n\nfunction setAttr(node: Node, name: string, value: string | undefined) {\n const i = node.attrs.findIndex(([k]) => k === name);\n if (value === undefined) {\n if (i >= 0) node.attrs.splice(i, 1);\n } else if (!safeAttr(name, value)) return;\n else if (i >= 0) node.attrs[i]![1] = value;\n else node.attrs.push([name, value]);\n}\n\nconst getAttr = (node: Node, name: string) => node.attrs.find(([k]) => k === name)?.[1];\n\n/** A `viewBox` attribute's box, or undefined when it has none or it is malformed. */\nexport function parseViewBox(value: string | null | undefined): SvgBox | undefined {\n const box = (value ?? \"\").trim().split(/[\\s,]+/).map(Number);\n return box.length === 4 && box.every(Number.isFinite) && box[2]! > 0 && box[3]! > 0\n ? (box as unknown as SvgBox)\n : undefined;\n}\n\n/** The `viewBox` on an SVG's opening tag (see {@link parseViewBox}). */\nexport function svgViewBox(markup: string): SvgBox | undefined {\n const open = /<svg\\b[^>]*>/i.exec(markup)?.[0] ?? \"\";\n return parseViewBox(/\\sviewBox\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/i.exec(open)?.slice(1).find((v) => v !== undefined));\n}\n\nexport interface SvgFrameMarkupOptions {\n /**\n * The time shown, in ms: a number, `\"first\"` (0) or `\"last\"` (the end of\n * its last change, see `svgDuration`; the default).\n */\n at?: number | \"first\" | \"last\";\n /** Step start times in ms, as a player's `steps` (default none). */\n steps?: readonly number[];\n}\n\n/**\n * The picture of an {@link SvgMotion} at a moment, as `<svg>` markup made safe\n * the way `parseSvg` makes it (no scripts, handlers, `<foreignObject>` or\n * outside links), with no DOM needed: render it on a server, show it under\n * `prefers-reduced-motion`, or anywhere a still will do. It is sized to fill\n * its container, as `SvgPlayer` draws it.\n *\n * It matches the player's frame except where that needs layout: a change\n * `along` a path, and a `view` that frames an element by id, stay where the\n * markup puts them. Undefined when `motion.svg` is not an `<svg>`.\n */\nexport function svgFrameMarkup(motion: SvgMotion, options: SvgFrameMarkupOptions = {}): string | undefined {\n const svg = parse(motion.svg.trim());\n if (!svg) return undefined;\n const steps = options.steps ?? [];\n const at = options.at ?? \"last\";\n const time = at === \"first\" ? 0 : at === \"last\" ? svgDuration(motion, steps) : at;\n const byId = new Map<string, Node>();\n const index = (node: Node) => {\n const id = getAttr(node, \"id\");\n if (id && !byId.has(id)) byId.set(id, node);\n for (const c of node.children) if (typeof c !== \"string\") index(c);\n };\n index(svg);\n const whole = parseViewBox(getAttr(svg, \"viewBox\"));\n for (const [id, frame] of svgFrame(motion.animate ?? [], steps, time)) {\n if (id === SVG_PICTURE && frame.view) {\n const { from, to, u } = frame.view;\n const a = from === null ? whole : typeof from === \"string\" ? undefined : from;\n const b = typeof to === \"string\" ? undefined : to;\n if (a && b) setAttr(svg, \"viewBox\", a.map((n, i) => +(n + (b[i]! - n) * u).toFixed(2)).join(\" \"));\n continue;\n }\n const el = byId.get(id);\n if (!el) continue;\n for (const [name, value] of Object.entries(frame.attrs)) setAttr(el, name, value);\n if (frame.draw !== undefined) {\n setAttr(el, \"pathLength\", \"1\");\n setAttr(el, \"stroke-dasharray\", \"1 1\");\n setAttr(el, \"stroke-dashoffset\", String(1 - frame.draw));\n }\n if (frame.text !== undefined) el.children = [frame.text];\n if (frame.solo !== undefined) {\n let i = 0;\n for (const child of el.children)\n if (typeof child !== \"string\") setAttr(child, \"display\", i++ === frame.solo ? undefined : \"none\");\n }\n }\n setAttr(svg, \"width\", \"100%\");\n setAttr(svg, \"height\", \"100%\");\n if (!getAttr(svg, \"xmlns\")) setAttr(svg, \"xmlns\", \"http://www.w3.org/2000/svg\");\n return serialize(svg);\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,12 @@
1
+ import {
2
+ CAMERA_MS,
3
+ CAMERA_STEP_MS,
4
+ EFFECT_TYPES,
5
+ MAX_TILT,
6
+ cameraAt,
7
+ cameraTrack,
8
+ sceneStage
9
+ } from "./chunk-WAMA45G3.js";
1
10
  import {
2
11
  HOVER_SECONDS,
3
12
  MAX_CLICKS,
@@ -13,15 +22,6 @@ import {
13
22
  resetGlCaches,
14
23
  wrapSource
15
24
  } from "./chunk-YLJWC4N2.js";
16
- import {
17
- CAMERA_MS,
18
- CAMERA_STEP_MS,
19
- EFFECT_TYPES,
20
- MAX_TILT,
21
- cameraAt,
22
- cameraTrack,
23
- sceneStage
24
- } from "./chunk-WAMA45G3.js";
25
25
  import {
26
26
  controlValue,
27
27
  imageUrls,
@@ -1617,4 +1617,4 @@ export {
1617
1617
  validateScene,
1618
1618
  standaloneSceneHtml
1619
1619
  };
1620
- //# sourceMappingURL=chunk-KVKJCD6A.js.map
1620
+ //# sourceMappingURL=chunk-UNLCGDCB.js.map
@@ -128,4 +128,4 @@ export {
128
128
  stepVariant,
129
129
  formatUnit
130
130
  };
131
- //# sourceMappingURL=chunk-H355R6U4.js.map
131
+ //# sourceMappingURL=chunk-VP6IEWIK.js.map
package/dist/cli.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  standaloneHtml,
4
4
  standaloneSceneHtml,
5
5
  validateScene
6
- } from "./chunk-KVKJCD6A.js";
7
- import "./chunk-YLJWC4N2.js";
8
- import "./chunk-EHDJ3CPJ.js";
6
+ } from "./chunk-UNLCGDCB.js";
9
7
  import {
10
8
  simulateScene
11
9
  } from "./chunk-WAMA45G3.js";
10
+ import "./chunk-YLJWC4N2.js";
11
+ import "./chunk-EHDJ3CPJ.js";
12
12
  import "./chunk-WMZQCUFJ.js";
13
13
  import {
14
14
  parseControls
@@ -1,6 +1,6 @@
1
- import { d as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-CGsNkP5U.js';
1
+ import { e as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-9J6NWaN3.js';
2
2
  import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-Syr6drzO.js';
3
- import { S as SvgMotion, C as Clock } from '../svg-C_TWBtEN.js';
3
+ import { S as SvgMotion, C as Clock } from '../svg-XugR-6Ec.js';
4
4
  import { AnimationEasingPreset, AnimationEasing, AnimationTrack, AnimationKeyframe, cubicBezierAt as cubicBezierAt$1, evaluateEasing as evaluateEasing$1 } from '@pixerate/editor/animation';
5
5
  export { CubicBezierEasing, SpringEasing } from '@pixerate/editor/animation';
6
6
  import { CommandRegistry, CommandSpec } from '@pixerate/editor/commands';
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { C as ControlValue, a as ControlDef } from './controls-Syr6drzO.js';
2
2
  export { c as ControlCheck, b as ControlType, T as TextureSettings, d as checkControlValue, e as coerceControlValue, f as componentCount, g as controlValue, h as describeValue, i as hexToRgb, j as humanise, k as imageUrls, l as isImageUrl, p as parseControls, r as rgbToHex } from './controls-Syr6drzO.js';
3
3
  export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, f as ShaderRendererOptions, T as TextureCache, g as TextureSource, V as VERTEX_SOURCE, h as applyTextureSettings, i as compileShader, j as createContext, k as drawFrame, l as formatCompileError, m as isSvgUrl, n as loadImage, p as parseCompileLog, o as preloadImages, r as releaseImages, q as resetGlCaches, s as sizeSvg, w as wrapSource } from './renderer-SNYZu__R.js';
4
- import { C as Clock } from './svg-C_TWBtEN.js';
5
- export { A as AnimateCountOptions, D as DataKey, E as EASES, b as EaseName, M as ManualClock, c as SCRAMBLE_MS, d as STEP_MS, e as SVG_PICTURE, f as SvgAnimation, g as SvgBox, h as SvgElementFrame, S as SvgMotion, i as SvgPlayer, j as SvgPlayerOptions, a as SvgTrigger, k as SvgView, l as SvgViewOptions, m as animateCount, n as defaultDataKey, o as formatCount, p as jitter, q as lerpAttr, r as lerpData, s as pageHidden, t as parseSvg, u as realClock, v as stepData, w as stepProgress, x as stepStart, y as svgDuration, z as svgFrame, B as svgMotionIssues, F as svgOpeningTag, G as svgView, H as writtenText } from './svg-C_TWBtEN.js';
6
- export { BoxAlignment, BoxFit, FittedBoxResult, FormatUnitOptions, MorphOptions, StackLayoutOptions, UnitFormat, computeBoxFit, formatUnit, layoutStack, morphPaths, morphSequence, remap, stepVariant } from './vector/index.js';
4
+ import { C as Clock } from './svg-XugR-6Ec.js';
5
+ export { A as AnimateCountOptions, D as DataKey, E as EASES, c as EaseName, M as ManualClock, d as SCRAMBLE_MS, e as STEP_MS, f as SVG_PICTURE, g as SvgAnimation, h as SvgBox, i as SvgElementFrame, S as SvgMotion, b as SvgPlayer, j as SvgPlayerOptions, a as SvgTrigger, k as SvgView, l as SvgViewOptions, m as animateCount, n as defaultDataKey, o as formatCount, p as jitter, q as lerpAttr, r as lerpData, s as pageHidden, t as parseSvg, u as realClock, v as stepData, w as stepProgress, x as stepStart, y as svgDuration, z as svgFrame, B as svgMotionIssues, F as svgOpeningTag, G as svgView, H as writtenText } from './svg-XugR-6Ec.js';
6
+ export { BoxAlignment, BoxFit, FittedBoxResult, FormatUnitOptions, MorphOptions, StackLayoutOptions, SvgFrameMarkupOptions, UnitFormat, computeBoxFit, formatUnit, layoutStack, morphPaths, morphSequence, parseViewBox, remap, stepVariant, svgFrameMarkup, svgViewBox } from './vector/index.js';
7
7
 
8
8
  /** Controls a registered thumbnail. */
9
9
  interface ThumbnailHandle {
package/dist/index.js CHANGED
@@ -1,10 +1,25 @@
1
+ import {
2
+ calculateShotTimings,
3
+ createLottieEase,
4
+ exportCmx3600Edl,
5
+ exportFcp7Xml,
6
+ exportLottie,
7
+ exportMotn,
8
+ framesToTimecode,
9
+ timecodeToFrames
10
+ } from "./chunk-GTIAOYOK.js";
1
11
  import {
2
12
  computeBoxFit,
3
13
  formatUnit,
4
14
  layoutStack,
5
15
  remap,
6
16
  stepVariant
7
- } from "./chunk-H355R6U4.js";
17
+ } from "./chunk-VP6IEWIK.js";
18
+ import {
19
+ parseViewBox,
20
+ svgFrameMarkup,
21
+ svgViewBox
22
+ } from "./chunk-DVVQRZJ5.js";
8
23
  import {
9
24
  EASES,
10
25
  SCRAMBLE_MS,
@@ -44,67 +59,7 @@ import {
44
59
  standaloneHtml,
45
60
  standaloneSceneHtml,
46
61
  validateScene
47
- } from "./chunk-KVKJCD6A.js";
48
- import {
49
- BUILTIN_UNIFORMS,
50
- HOVER_SECONDS,
51
- ImageLoadError,
52
- MAX_CLICKS,
53
- PointerTracker,
54
- SVG_EDGE,
55
- ShaderCompileError,
56
- TextureCache,
57
- VERTEX_SOURCE,
58
- applyAscCdl,
59
- applyLiftGammaGain,
60
- applyTextureSettings,
61
- applyVibrance,
62
- clicksUniform,
63
- compileShader,
64
- convertColorSpace,
65
- createContext,
66
- drawFrame,
67
- formatCompileError,
68
- getColorGradingGLSL,
69
- getOklabGLSL,
70
- getWhiteBalanceGains,
71
- interpolateOklab,
72
- interpolateOklch,
73
- isSvgUrl,
74
- linearRgbToSrgb,
75
- linearSrgbToOklab,
76
- linearToSrgb,
77
- loadImage,
78
- oklabToLinearSrgb,
79
- oklabToOklch,
80
- oklabToSrgb,
81
- oklchToOklab,
82
- parseCompileLog,
83
- preloadImages,
84
- releaseImages,
85
- resetGlCaches,
86
- sizeSvg,
87
- srgbToLinear,
88
- srgbToLinearRgb,
89
- srgbToOklab,
90
- wrapSource
91
- } from "./chunk-YLJWC4N2.js";
92
- import {
93
- ALL_TRANSITION_TYPES,
94
- blendTransitionPixel,
95
- getTransitionGLSL,
96
- sampleTransition
97
- } from "./chunk-EHDJ3CPJ.js";
98
- import {
99
- calculateShotTimings,
100
- createLottieEase,
101
- exportCmx3600Edl,
102
- exportFcp7Xml,
103
- exportLottie,
104
- exportMotn,
105
- framesToTimecode,
106
- timecodeToFrames
107
- } from "./chunk-GTIAOYOK.js";
62
+ } from "./chunk-UNLCGDCB.js";
108
63
  import {
109
64
  CAMERA_MS,
110
65
  CAMERA_STEP_MS,
@@ -162,6 +117,56 @@ import {
162
117
  viewAt,
163
118
  visibleRect
164
119
  } from "./chunk-WAMA45G3.js";
120
+ import {
121
+ BUILTIN_UNIFORMS,
122
+ HOVER_SECONDS,
123
+ ImageLoadError,
124
+ MAX_CLICKS,
125
+ PointerTracker,
126
+ SVG_EDGE,
127
+ ShaderCompileError,
128
+ TextureCache,
129
+ VERTEX_SOURCE,
130
+ applyAscCdl,
131
+ applyLiftGammaGain,
132
+ applyTextureSettings,
133
+ applyVibrance,
134
+ clicksUniform,
135
+ compileShader,
136
+ convertColorSpace,
137
+ createContext,
138
+ drawFrame,
139
+ formatCompileError,
140
+ getColorGradingGLSL,
141
+ getOklabGLSL,
142
+ getWhiteBalanceGains,
143
+ interpolateOklab,
144
+ interpolateOklch,
145
+ isSvgUrl,
146
+ linearRgbToSrgb,
147
+ linearSrgbToOklab,
148
+ linearToSrgb,
149
+ loadImage,
150
+ oklabToLinearSrgb,
151
+ oklabToOklch,
152
+ oklabToSrgb,
153
+ oklchToOklab,
154
+ parseCompileLog,
155
+ preloadImages,
156
+ releaseImages,
157
+ resetGlCaches,
158
+ sizeSvg,
159
+ srgbToLinear,
160
+ srgbToLinearRgb,
161
+ srgbToOklab,
162
+ wrapSource
163
+ } from "./chunk-YLJWC4N2.js";
164
+ import {
165
+ ALL_TRANSITION_TYPES,
166
+ blendTransitionPixel,
167
+ getTransitionGLSL,
168
+ sampleTransition
169
+ } from "./chunk-EHDJ3CPJ.js";
165
170
  import {
166
171
  ManualClock,
167
172
  jitter,
@@ -1303,6 +1308,7 @@ export {
1303
1308
  parseControls,
1304
1309
  parseSvg,
1305
1310
  parseTimecode,
1311
+ parseViewBox,
1306
1312
  pingPongTime,
1307
1313
  playScene,
1308
1314
  preloadImages,
@@ -1343,9 +1349,11 @@ export {
1343
1349
  supportsDropFrame,
1344
1350
  svgDuration,
1345
1351
  svgFrame,
1352
+ svgFrameMarkup,
1346
1353
  svgMotionIssues,
1347
1354
  svgOpeningTag,
1348
1355
  svgView,
1356
+ svgViewBox,
1349
1357
  timecodeToFrames,
1350
1358
  titleBox,
1351
1359
  touchedIds,