@pixerate/editor 0.70.0 → 0.71.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/dist/animation-editor/index.cjs +135 -43
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +39 -2
- package/dist/animation-editor/index.d.ts +39 -2
- package/dist/animation-editor/index.js +102 -10
- package/dist/animation-editor/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1537,11 +1537,35 @@ function motionStageSvg(scene, time, options = {}) {
|
|
|
1537
1537
|
const bg = svgOptions.background !== false && scene.artwork.background ? _nullishCoalesce(_optionalChain([/^\s*<rect[^>]*\/>/, 'access', _44 => _44.exec, 'call', _45 => _45(body), 'optionalAccess', _46 => _46[0]]), () => ( "")) : "";
|
|
1538
1538
|
return `${current.slice(0, open)}${bg}${ghosts.join("")}${body.slice(bg.length)}${paths}</svg>`;
|
|
1539
1539
|
}
|
|
1540
|
+
function motionContactSheetSvg(scene, times, options = {}) {
|
|
1541
|
+
const { columns, labels = true, ...frameOptions } = options;
|
|
1542
|
+
const n = Math.max(1, times.length);
|
|
1543
|
+
const cols = Math.max(1, Math.min(n, Math.floor(_nullishCoalesce(columns, () => ( Math.ceil(Math.sqrt(n)))))));
|
|
1544
|
+
const rows = Math.ceil(n / cols);
|
|
1545
|
+
const { width: w, height: h } = scene.artwork;
|
|
1546
|
+
const gap = Math.round(Math.max(w, h) * 0.04);
|
|
1547
|
+
const label = labels ? Math.round(Math.max(12, h * 0.08)) : 0;
|
|
1548
|
+
const timeline = compileMotionScene(scene);
|
|
1549
|
+
const W = cols * w + (cols + 1) * gap;
|
|
1550
|
+
const H = rows * (h + label) + (rows + 1) * gap;
|
|
1551
|
+
const prefix = _nullishCoalesce(frameOptions.idPrefix, () => ( "vg-"));
|
|
1552
|
+
const cells = times.map((t, i) => {
|
|
1553
|
+
const x = gap + i % cols * (w + gap);
|
|
1554
|
+
const y = gap + Math.floor(i / cols) * (h + label + gap);
|
|
1555
|
+
const frame = motionStageSvg(scene, t, { ...frameOptions, idPrefix: `${prefix}f${i}-` });
|
|
1556
|
+
const view = _nullishCoalesce(_optionalChain([/viewBox="([^"]*)"/, 'access', _47 => _47.exec, 'call', _48 => _48(frame), 'optionalAccess', _49 => _49[1]]), () => ( `0 0 ${w} ${h}`));
|
|
1557
|
+
const inner = innerSvg(frame).replace(new RegExp(` id="(?!${`${prefix}f${i}-`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})[^"]*"`, "g"), "");
|
|
1558
|
+
const shot = _nullishCoalesce(timeline.shots.find((s) => t >= s.start && t < s.end), () => ( timeline.shots[timeline.shots.length - 1]));
|
|
1559
|
+
const caption = labels ? `<text x="${x + w / 2}" y="${y + h + label * 0.8}" font-family="system-ui, sans-serif" font-size="${Math.round(label * 0.7)}" text-anchor="middle" fill="#64748b">${(t / 1e3).toFixed(2)} s${shot ? ` \xB7 ${shot.id.replace(/[<&]/g, "")}` : ""}</text>` : "";
|
|
1560
|
+
return `<svg x="${x}" y="${y}" width="${w}" height="${h}" viewBox="${view}" overflow="hidden">${inner}</svg><rect x="${x}" y="${y}" width="${w}" height="${h}" fill="none" stroke="#cbd5e1"/>${caption}`;
|
|
1561
|
+
});
|
|
1562
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}"><rect width="${W}" height="${H}" fill="#f8fafc"/>${cells.join("")}</svg>`;
|
|
1563
|
+
}
|
|
1540
1564
|
|
|
1541
1565
|
// src/animation-editor/check.ts
|
|
1542
1566
|
var MOTION_MIN_CHANGE_MS = 120;
|
|
1543
1567
|
var NUMERIC_PARAMS = (node, effectId) => {
|
|
1544
|
-
const effect = _optionalChain([node, 'access',
|
|
1568
|
+
const effect = _optionalChain([node, 'access', _50 => _50.effects, 'optionalAccess', _51 => _51.find, 'call', _52 => _52((e) => e.id === effectId)]);
|
|
1545
1569
|
if (!effect) return null;
|
|
1546
1570
|
return Object.entries(effect.params).filter(([, v]) => typeof v === "number").map(([k]) => k);
|
|
1547
1571
|
};
|
|
@@ -1622,7 +1646,7 @@ function checkMotionScene(scene) {
|
|
|
1622
1646
|
if (command2.type === "follow" && known(command2.path, "unknown-path", "path", where) && nodes.get(command2.path).node.type !== "path")
|
|
1623
1647
|
issues.push(motionIssue("not-a-path", `"${command2.path}" is a group; follow a single path node.`, { ...where, ids: [command2.path] }));
|
|
1624
1648
|
if (command2.type === "morph") known(command2.into, "unknown-shape", "shape", where);
|
|
1625
|
-
if (command2.type === "play" && !_optionalChain([scene, 'access',
|
|
1649
|
+
if (command2.type === "play" && !_optionalChain([scene, 'access', _53 => _53.clips, 'optionalAccess', _54 => _54[command2.clip]]))
|
|
1626
1650
|
issues.push(motionIssue("unknown-clip", `There is no clip ${namedWithSuggestion(command2.clip, Object.keys(_nullishCoalesce(scene.clips, () => ( {}))))}; define it with set_animation_clip.`, where));
|
|
1627
1651
|
if (command2.type === "match" && known(command2.into, "unknown-shape", "group", where)) {
|
|
1628
1652
|
const into = nodes.get(command2.into);
|
|
@@ -1715,7 +1739,7 @@ function checkMotionScene(scene) {
|
|
|
1715
1739
|
if (!shot.at) return;
|
|
1716
1740
|
const timing = timeline.shots[i];
|
|
1717
1741
|
if (timing.cue === void 0) {
|
|
1718
|
-
const what = shot.at.beat !== void 0 ? `beat ${shot.at.beat}, but the scene has no beat grid; set one with set_animation_settings ({ "beat": { "bpm": \u2026 } })` : `word ${shot.at.word}, but the narration has ${_nullishCoalesce(_optionalChain([scene, 'access',
|
|
1742
|
+
const what = shot.at.beat !== void 0 ? `beat ${shot.at.beat}, but the scene has no beat grid; set one with set_animation_settings ({ "beat": { "bpm": \u2026 } })` : `word ${shot.at.word}, but the narration has ${_nullishCoalesce(_optionalChain([scene, 'access', _55 => _55.narration, 'optionalAccess', _56 => _56.words, 'access', _57 => _57.length]), () => ( 0))} words (indexes from 0)`;
|
|
1719
1743
|
issues.push(motionIssue("unknown-cue", `Shot "${shot.id}" is cued to ${what}.`, { shot: shot.id }));
|
|
1720
1744
|
} else if (timing.missedBy !== void 0) {
|
|
1721
1745
|
const late = Math.round(timing.missedBy);
|
|
@@ -1748,7 +1772,7 @@ function checkMotionScene(scene) {
|
|
|
1748
1772
|
const cam = frame.camera;
|
|
1749
1773
|
const docIndex = indexMotionNodes(frame.document.nodes);
|
|
1750
1774
|
for (const id of command2.targets) {
|
|
1751
|
-
const b = _optionalChain([docIndex, 'access',
|
|
1775
|
+
const b = _optionalChain([docIndex, 'access', _58 => _58.get, 'call', _59 => _59(id), 'optionalAccess', _60 => _60.bounds]);
|
|
1752
1776
|
if (!b || reported.has(id) || !visibleAt(timeline, id, timing.end, nodes.get(id).node)) continue;
|
|
1753
1777
|
const outside = b.x + b.width < cam.x || b.y + b.height < cam.y || b.x > cam.x + cam.width || b.y > cam.y + cam.height;
|
|
1754
1778
|
if (outside) {
|
|
@@ -1972,9 +1996,9 @@ function applyMotionEdits(scene, edits) {
|
|
|
1972
1996
|
let next = scene;
|
|
1973
1997
|
for (let i = 0; i < list.length; i++) {
|
|
1974
1998
|
const edit = list[i];
|
|
1975
|
-
const prefix = list.length > 1 ? `op ${i + 1} (${_optionalChain([edit, 'optionalAccess',
|
|
1999
|
+
const prefix = list.length > 1 ? `op ${i + 1} (${_optionalChain([edit, 'optionalAccess', _61 => _61.op])}): ` : "";
|
|
1976
2000
|
if (!edit || !MOTION_EDIT_OPS.includes(edit.op))
|
|
1977
|
-
return { ok: false, error: `${prefix}Unknown op ${namedWithSuggestion(String(_optionalChain([edit, 'optionalAccess',
|
|
2001
|
+
return { ok: false, error: `${prefix}Unknown op ${namedWithSuggestion(String(_optionalChain([edit, 'optionalAccess', _62 => _62.op])), MOTION_EDIT_OPS)}. Nothing was changed.` };
|
|
1978
2002
|
try {
|
|
1979
2003
|
next = applyOne(next, edit);
|
|
1980
2004
|
} catch (error) {
|
|
@@ -1990,6 +2014,56 @@ function applyMotionEdits(scene, edits) {
|
|
|
1990
2014
|
if (added.length) return { ok: false, error: `Nothing was changed: ${added.map(motionIssueLine).join(" ")}` };
|
|
1991
2015
|
return { ok: true, scene: next, issues, hints: editHints(before, issues) };
|
|
1992
2016
|
}
|
|
2017
|
+
var REF = /^\$(\d+|last)((?:\.[A-Za-z_]\w*|\[\d+\])+)$/;
|
|
2018
|
+
function resolveMotionEditRefs(scene, edits) {
|
|
2019
|
+
const outcomes = [];
|
|
2020
|
+
const resolved = [];
|
|
2021
|
+
let next = scene;
|
|
2022
|
+
for (let i = 0; i < edits.length; i++) {
|
|
2023
|
+
const where = `op ${i + 1} (${_optionalChain([edits, 'access', _63 => _63[i], 'optionalAccess', _64 => _64.op])})`;
|
|
2024
|
+
let problem = null;
|
|
2025
|
+
const walk = (v) => {
|
|
2026
|
+
if (typeof v === "string") {
|
|
2027
|
+
if (v.startsWith("$$")) return v.slice(1);
|
|
2028
|
+
const m = REF.exec(v);
|
|
2029
|
+
if (!m) return v;
|
|
2030
|
+
const n = m[1] === "last" ? i - 1 : Number(m[1]);
|
|
2031
|
+
if (!(n >= 0 && n < i)) {
|
|
2032
|
+
problem = `${where}: "${v}" refers to op ${n + 1}, but only ops before this one (1 to ${i}) can be referred to.`;
|
|
2033
|
+
return v;
|
|
2034
|
+
}
|
|
2035
|
+
let value = outcomes[n];
|
|
2036
|
+
for (const part of _nullishCoalesce(m[2].match(/\.[A-Za-z_]\w*|\[\d+\]/g), () => ( []))) value = value == null ? void 0 : value[part.startsWith(".") ? part.slice(1) : part.slice(1, -1)];
|
|
2037
|
+
if (value === void 0) problem = `${where}: "${v}" has no value; op ${n + 1} made ${JSON.stringify(outcomes[n])}.`;
|
|
2038
|
+
return value;
|
|
2039
|
+
}
|
|
2040
|
+
if (Array.isArray(v)) return v.map(walk);
|
|
2041
|
+
if (v && typeof v === "object") return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk(x)]));
|
|
2042
|
+
return v;
|
|
2043
|
+
};
|
|
2044
|
+
const edit = walk(edits[i]);
|
|
2045
|
+
if (problem) return { ok: false, error: `${problem} Nothing was changed.` };
|
|
2046
|
+
const before = next;
|
|
2047
|
+
try {
|
|
2048
|
+
next = applyOne(next, edit);
|
|
2049
|
+
} catch (error) {
|
|
2050
|
+
if (error instanceof EditError) return { ok: false, error: `${where}: ${error.message} Nothing was changed.` };
|
|
2051
|
+
throw error;
|
|
2052
|
+
}
|
|
2053
|
+
resolved.push(edit);
|
|
2054
|
+
const out = { op: edit.op };
|
|
2055
|
+
if (edit.op === "insert_shots") out.shots = edit.shots.map((s) => s.id);
|
|
2056
|
+
if ("shot" in edit && typeof edit.shot === "string") out.shot = edit.op === "update_shot" && _optionalChain([edit, 'access', _65 => _65.set, 'optionalAccess', _66 => _66.id]) ? edit.set.id : edit.shot;
|
|
2057
|
+
if (edit.op === "add_commands") {
|
|
2058
|
+
const at = _nullishCoalesce(_nullishCoalesce(edit.at, () => ( _optionalChain([before, 'access', _67 => _67.shots, 'access', _68 => _68.find, 'call', _69 => _69((s) => s.id === edit.shot), 'optionalAccess', _70 => _70.run, 'access', _71 => _71.length]))), () => ( 0));
|
|
2059
|
+
out.indexes = edit.commands.map((_, k) => at + k);
|
|
2060
|
+
}
|
|
2061
|
+
if (edit.op === "move_command") out.indexes = [edit.to];
|
|
2062
|
+
if (edit.op === "set_clip") out.clip = edit.name;
|
|
2063
|
+
outcomes.push(out);
|
|
2064
|
+
}
|
|
2065
|
+
return { ok: true, edits: resolved, outcomes };
|
|
2066
|
+
}
|
|
1993
2067
|
function createMotionScene(artwork, init = {}) {
|
|
1994
2068
|
return { version: 1, name: _nullishCoalesce(init.name, () => ( "animation")), ...init, artwork, shots: _nullishCoalesce(init.shots, () => ( [])) };
|
|
1995
2069
|
}
|
|
@@ -2134,7 +2208,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2134
2208
|
const wrapper = freshId(`${id}--follow`);
|
|
2135
2209
|
const centre = freshId(`${id}--follow-centre`);
|
|
2136
2210
|
const c = entry.center;
|
|
2137
|
-
const at = _optionalChain([motionNodeOffset, 'call',
|
|
2211
|
+
const at = _optionalChain([motionNodeOffset, 'call', _72 => _72(entry, timeline, 0, nodes), 'optionalAccess', _73 => _73.follow]);
|
|
2138
2212
|
const placed = at ? `translate(${f(at.x)} ${f(at.y)})${at.angle ? ` rotate(${f(at.angle)})` : ""}` : void 0;
|
|
2139
2213
|
(wrap[id] ??= []).push({ id: wrapper, ...placed ? { transform: placed } : {} }, { id: centre, transform: `translate(${f(-c.x)} ${f(-c.y)})` });
|
|
2140
2214
|
follows.push({ id, wrapper, routes: ids, segments: followSegments.filter((seg) => seg.path && ids.has(seg.path)) });
|
|
@@ -2194,7 +2268,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2194
2268
|
exact: () => false,
|
|
2195
2269
|
value: (t) => {
|
|
2196
2270
|
const frame = motionFrameAt(scene, t, { draw: false, offsets: false });
|
|
2197
|
-
const now = _chunkYJLCBA7Vcjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call',
|
|
2271
|
+
const now = _chunkYJLCBA7Vcjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call', _74 => _74(frame.document.nodes), 'access', _75 => _75.get, 'call', _76 => _76(id), 'optionalAccess', _77 => _77.node]));
|
|
2198
2272
|
if (!now || now.type !== "path") return "";
|
|
2199
2273
|
const bezier = _chunkO2UH7LZEcjs.transformBezierPath.call(void 0, _chunkYJLCBA7Vcjs.vectorPathWorldBezier.call(void 0, now, _chunkYJLCBA7Vcjs.IDENTITY_MATRIX, { effects: false }), inverse);
|
|
2200
2274
|
return _chunkO2UH7LZEcjs.bezierPathToSvg.call(void 0, bezier, { precision: Math.min(precision, 2) });
|
|
@@ -2215,8 +2289,8 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2215
2289
|
...delay > 0 ? { delay: round2(delay) } : {},
|
|
2216
2290
|
ms: round2(ms),
|
|
2217
2291
|
ease: written,
|
|
2218
|
-
..._optionalChain([segment, 'optionalAccess',
|
|
2219
|
-
..._optionalChain([segment, 'optionalAccess',
|
|
2292
|
+
..._optionalChain([segment, 'optionalAccess', _78 => _78.behavior]) ? { behavior: segment.behavior } : {},
|
|
2293
|
+
..._optionalChain([segment, 'optionalAccess', _79 => _79.steps]) ? { strobe: segment.steps } : {}
|
|
2220
2294
|
};
|
|
2221
2295
|
if (channel.kind === "view") animate.push({ ...base, view: to });
|
|
2222
2296
|
else if (channel.kind === "draw") animate.push({ ...base, draw: [from, to] });
|
|
@@ -2305,7 +2379,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2305
2379
|
let svg = _chunkYJLCBA7Vcjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunkYJLCBA7Vcjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
|
|
2306
2380
|
if (routes.length) svg = svg.replace(/^(<svg[^>]*>)/, `$1<defs>${routes.join("")}</defs>`);
|
|
2307
2381
|
let motion = { svg, animate };
|
|
2308
|
-
if (_optionalChain([scene, 'access',
|
|
2382
|
+
if (_optionalChain([scene, 'access', _80 => _80.controls, 'optionalAccess', _81 => _81.length])) {
|
|
2309
2383
|
const declarations = scene.controls.map((c) => `{{${c.name}: color default=${c.default.toUpperCase()}${c.label ? ` label='${c.label.replace(/'/g, "\u2019")}'` : ""}}}`).join(" ");
|
|
2310
2384
|
const swap = (text) => scene.controls.reduce((s, c) => s.replace(new RegExp(`${c.default}(?![0-9a-fA-F])`, "gi"), `{{${c.name}}}`), text);
|
|
2311
2385
|
svg = svg.replace(/^(<svg[^>]*>)/, `$1<!-- ${declarations} -->`);
|
|
@@ -2327,7 +2401,7 @@ function toFlairVectorEffect(scene, options = {}) {
|
|
|
2327
2401
|
tags: _nullishCoalesce(options.tags, () => ( [])),
|
|
2328
2402
|
motion: out.motion,
|
|
2329
2403
|
hold: out.hold,
|
|
2330
|
-
..._optionalChain([scene, 'access',
|
|
2404
|
+
..._optionalChain([scene, 'access', _82 => _82.presets, 'optionalAccess', _83 => _83.length]) ? { presets: scene.presets } : {},
|
|
2331
2405
|
...out.trigger ? { trigger: out.trigger } : {}
|
|
2332
2406
|
};
|
|
2333
2407
|
}
|
|
@@ -2371,7 +2445,7 @@ function resolvePlaceholders(motion, notes) {
|
|
|
2371
2445
|
const filled = text.replace(PLACEHOLDER, (_, name) => {
|
|
2372
2446
|
const d = declared.get(name);
|
|
2373
2447
|
if (!d) unknown.add(name);
|
|
2374
|
-
return (_nullishCoalesce(_optionalChain([d, 'optionalAccess',
|
|
2448
|
+
return (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _84 => _84.value]), () => ( ""))).replace(/"/g, '\\"');
|
|
2375
2449
|
});
|
|
2376
2450
|
for (const name of unknown) notes.push(`Placeholder "{{${name}}}" has no declaration, so it was left empty.`);
|
|
2377
2451
|
return { motion: JSON.parse(filled), controls };
|
|
@@ -2425,7 +2499,7 @@ function commandsFor(anim, nodes, entered, notes) {
|
|
|
2425
2499
|
if (anim.along) {
|
|
2426
2500
|
const path = nodes.get(anim.along);
|
|
2427
2501
|
if (!path || path.node.type !== "path") notes.push(`${where} follows "${anim.along}", which is not a path in the artwork; the follow was skipped.`);
|
|
2428
|
-
else out.push({ type: "follow", targets, path: anim.along, from: _nullishCoalesce(_optionalChain([anim, 'access',
|
|
2502
|
+
else out.push({ type: "follow", targets, path: anim.along, from: _nullishCoalesce(_optionalChain([anim, 'access', _85 => _85.at, 'optionalAccess', _86 => _86[0]]), () => ( 0)), to: _nullishCoalesce(_optionalChain([anim, 'access', _87 => _87.at, 'optionalAccess', _88 => _88[1]]), () => ( 1)), ...anim.orient ? { rotate: true } : {}, ...timing, ...ease(MOTION_EASE_IN_OUT) });
|
|
2429
2503
|
}
|
|
2430
2504
|
for (const [attr, [a, b]] of Object.entries(_nullishCoalesce(anim.attrs, () => ( {})))) {
|
|
2431
2505
|
if (attr === "opacity") {
|
|
@@ -2436,7 +2510,7 @@ function commandsFor(anim, nodes, entered, notes) {
|
|
|
2436
2510
|
out.push({ type: "enter", targets, style: "fade", ...timing, ...ease(MOTION_EASE_OUT) });
|
|
2437
2511
|
} else out.push({ type: "fade", targets, to: Math.min(1, Math.max(0, to)), ...timing, ...ease(MOTION_EASE_IN_OUT) });
|
|
2438
2512
|
} else if (attr === "fill" || attr === "stroke") {
|
|
2439
|
-
if (_optionalChain([behavior, 'optionalAccess',
|
|
2513
|
+
if (_optionalChain([behavior, 'optionalAccess', _89 => _89.type]) === "pulse") out.push({ type: "color-pulse", targets, color: String(b), paint: attr, count: _nullishCoalesce(behavior.count, () => ( 1)), ...timing, ...ease("linear") });
|
|
2440
2514
|
else {
|
|
2441
2515
|
if (behavior) notes.push(`${where}: a ${attr} ${behavior.type} became a plain colour change.`);
|
|
2442
2516
|
out.push({ type: "style", targets, [attr]: String(b), ...timing, ...ease(MOTION_EASE_IN_OUT) });
|
|
@@ -2719,7 +2793,7 @@ function toLottie(scene, options = {}) {
|
|
|
2719
2793
|
const shapeSegments = [...timeline.tracks.entries()].filter(([k]) => k.startsWith(`${path.id}\0`) && (k.endsWith("\0shape") || k.includes("\0effect:"))).flatMap(([, v]) => v);
|
|
2720
2794
|
const geometryAt = (t) => {
|
|
2721
2795
|
if (!shapeSegments.length) return _chunkYJLCBA7Vcjs.vectorPathWorldBezier.call(void 0, path);
|
|
2722
|
-
const now = _optionalChain([indexMotionNodes, 'call',
|
|
2796
|
+
const now = _optionalChain([indexMotionNodes, 'call', _90 => _90(motionFrameAt(scene, t, { draw: false, offsets: false }).document.nodes), 'access', _91 => _91.get, 'call', _92 => _92(path.id), 'optionalAccess', _93 => _93.node]);
|
|
2723
2797
|
return now && now.type === "path" ? _chunkYJLCBA7Vcjs.vectorPathWorldBezier.call(void 0, _chunkYJLCBA7Vcjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunkYJLCBA7Vcjs.vectorPathWorldBezier.call(void 0, path);
|
|
2724
2798
|
};
|
|
2725
2799
|
const rest = lottieContours(_chunkO2UH7LZEcjs.toBezierPath.call(void 0, geometryAt(0)), round2);
|
|
@@ -2767,7 +2841,7 @@ function toLottie(scene, options = {}) {
|
|
|
2767
2841
|
lj: path.strokeLinejoin === "round" ? 2 : path.strokeLinejoin === "bevel" ? 3 : 1,
|
|
2768
2842
|
ml: 4
|
|
2769
2843
|
});
|
|
2770
|
-
if (_optionalChain([path, 'access',
|
|
2844
|
+
if (_optionalChain([path, 'access', _94 => _94.strokeDasharray, 'optionalAccess', _95 => _95.length])) notes.push(`"${path.id}": its dashes are not exported; the stroke is solid.`);
|
|
2771
2845
|
if (path.strokeAlign && path.strokeAlign !== "center") notes.push(`"${path.id}": its stroke is drawn centred (Lottie has no inside or outside strokes).`);
|
|
2772
2846
|
}
|
|
2773
2847
|
const fill = paintOf(path.fill, "fill", path.id);
|
|
@@ -2918,7 +2992,7 @@ var AnimationEditorController = (_class = class {
|
|
|
2918
2992
|
time: p.time,
|
|
2919
2993
|
playing: p.playing,
|
|
2920
2994
|
loop: p.loop,
|
|
2921
|
-
currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call',
|
|
2995
|
+
currentShot: _nullishCoalesce(_optionalChain([motionShotAt, 'call', _96 => _96(timeline, p.time), 'optionalAccess', _97 => _97.id]), () => ( null)),
|
|
2922
2996
|
selection: this.selection,
|
|
2923
2997
|
readOnly: this.readOnly,
|
|
2924
2998
|
error: this.error,
|
|
@@ -2957,7 +3031,7 @@ var AnimationEditorController = (_class = class {
|
|
|
2957
3031
|
this.applying = false;
|
|
2958
3032
|
}
|
|
2959
3033
|
this.notify();
|
|
2960
|
-
_optionalChain([this, 'access',
|
|
3034
|
+
_optionalChain([this, 'access', _98 => _98.onChange, 'optionalCall', _99 => _99(scene)]);
|
|
2961
3035
|
}
|
|
2962
3036
|
commit(label, next) {
|
|
2963
3037
|
const before = this.scene;
|
|
@@ -3302,9 +3376,9 @@ var EDIT_OP = {
|
|
|
3302
3376
|
object({ op: { const: "delete_shots", description: "Like delete_shots." }, shots: { type: "array", items: SHOT_ID, minItems: 1, description: "Shot ids." } }, ["op", "shots"]),
|
|
3303
3377
|
object({ op: { const: "move_shot", description: "Like move_shot." }, shot: SHOT_ID, to: { type: "integer", minimum: 0, description: "New position (0 = first)." } }, ["op", "shot", "to"]),
|
|
3304
3378
|
object({ op: { const: "add_commands", description: "Like add_commands." }, shot: SHOT_ID, commands: { type: "array", items: MOTION_COMMAND_SCHEMA, minItems: 1, description: "Commands to add." }, at: { type: "integer", minimum: 0, description: "Index in the shot's run (default: the end)." } }, ["op", "shot", "commands"]),
|
|
3305
|
-
object({ op: { const: "update_command", description: "Like update_command." }, shot: SHOT_ID, command: { type: "integer", minimum: 0, description:
|
|
3306
|
-
object({ op: { const: "move_command", description: "Like move_command." }, shot: SHOT_ID, command: { type: "integer", minimum: 0, description:
|
|
3307
|
-
object({ op: { const: "delete_commands", description: "Like delete_commands." }, shot: SHOT_ID, commands: { type: "array", items: { type: "integer", minimum: 0 }, minItems: 1, description: "Indexes in the shot's run." } }, ["op", "shot", "commands"]),
|
|
3379
|
+
object({ op: { const: "update_command", description: "Like update_command." }, shot: SHOT_ID, command: { anyOf: [{ type: "integer", minimum: 0 }, { type: "string", pattern: "^\\$(\\d+|last)[.\\[]" }], description: `Index in the shot's run, or a reference to an earlier op's outcome such as "$0.indexes[0]".` }, set: { type: "object", description: "Command fields to replace." }, remove: { type: "array", items: { type: "string" }, description: "Command fields to clear." } }, ["op", "shot", "command"]),
|
|
3380
|
+
object({ op: { const: "move_command", description: "Like move_command." }, shot: SHOT_ID, command: { anyOf: [{ type: "integer", minimum: 0 }, { type: "string", pattern: "^\\$(\\d+|last)[.\\[]" }], description: `Index in the shot's run, or a reference to an earlier op's outcome such as "$0.indexes[0]".` }, to: { type: "integer", minimum: 0, description: "New index in the run (0 = first)." } }, ["op", "shot", "command", "to"]),
|
|
3381
|
+
object({ op: { const: "delete_commands", description: "Like delete_commands." }, shot: SHOT_ID, commands: { type: "array", items: { anyOf: [{ type: "integer", minimum: 0 }, { type: "string", pattern: "^\\$(\\d+|last)[.\\[]" }], description: `An index, or a reference to an earlier op's outcome such as "$0.indexes[0]".` }, minItems: 1, description: "Indexes in the shot's run." } }, ["op", "shot", "commands"]),
|
|
3308
3382
|
object({ op: { const: "set_controls", description: "Like set_controls." }, controls: { type: "array", items: CONTROL, description: "Controls (empty clears)." }, presets: { type: "array", items: PRESET, description: "Presets (empty clears)." } }, ["op", "controls"])
|
|
3309
3383
|
]
|
|
3310
3384
|
};
|
|
@@ -3448,7 +3522,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3448
3522
|
const renderFrame = {
|
|
3449
3523
|
name: "render_animation_frame",
|
|
3450
3524
|
title: "Render a frame",
|
|
3451
|
-
description: 'Draws the animation at one moment without changing it, to check it: standalone SVG by default, or a PNG image (format "png") when the host can rasterize. Give a time in ms, or a shot and where in it.',
|
|
3525
|
+
description: 'Draws the animation at one moment (or, with times, several moments as one labelled contact sheet) without changing it, to check it: standalone SVG by default, or a PNG image (format "png") when the host can rasterize. Give a time in ms, or a shot and where in it.',
|
|
3452
3526
|
inputSchema: object({
|
|
3453
3527
|
time: MS("Time from the start"),
|
|
3454
3528
|
shot: { ...SHOT_ID, description: 'Render a moment of this shot instead of "time".' },
|
|
@@ -3463,10 +3537,12 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3463
3537
|
[],
|
|
3464
3538
|
"Draw faded frames either side of the moment, to see motion in one picture."
|
|
3465
3539
|
),
|
|
3540
|
+
times: { type: "array", items: { type: "number", minimum: 0 }, minItems: 2, maxItems: 16, description: "Several moments (ms) to draw as one contact sheet, each labelled with its time and shot, instead of one frame. Overrides time and shot." },
|
|
3541
|
+
columns: { type: "integer", minimum: 1, maximum: 8, description: "With times: frames a row (default about square)." },
|
|
3466
3542
|
motion_paths: { anyOf: [{ type: "boolean" }, { type: "array", items: { type: "string", minLength: 1 } }], description: "Draw where nodes travel (dashed, with a dot where each change starts or ends): true for every node whose place changes, or a list of ids." }
|
|
3467
3543
|
}),
|
|
3468
3544
|
annotations: { title: "Render a frame", ...READ },
|
|
3469
|
-
handler: async ({ time, shot, at = "end", format = "svg", onion_skin, motion_paths }) => {
|
|
3545
|
+
handler: async ({ time, shot, at = "end", format = "svg", onion_skin, motion_paths, times, columns }) => {
|
|
3470
3546
|
const s = scene();
|
|
3471
3547
|
let t = _nullishCoalesce(time, () => ( controller.getState().time));
|
|
3472
3548
|
if (shot !== void 0) {
|
|
@@ -3478,7 +3554,18 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3478
3554
|
const known = new Set(describeMotionElements(s).map((e) => e.id));
|
|
3479
3555
|
for (const id of motion_paths) if (!known.has(id)) throw new Error(`There is no element ${namedWithSuggestion(id, known)} to draw a motion path for.`);
|
|
3480
3556
|
}
|
|
3481
|
-
const
|
|
3557
|
+
const overlays = { ...onion_skin ? { onionSkin: onion_skin } : {}, ...motion_paths ? { motionPaths: motion_paths } : {} };
|
|
3558
|
+
if (times) {
|
|
3559
|
+
const sheet = motionContactSheetSvg(s, times, { pretty: false, ...overlays, ...columns ? { columns } : {} });
|
|
3560
|
+
if (format === "png") {
|
|
3561
|
+
if (!options.rasterize) throw new Error('This host cannot make PNG images; call render_animation_frame with format "svg".');
|
|
3562
|
+
const size = /width="(\d+)" height="(\d+)"/.exec(sheet);
|
|
3563
|
+
const image = await options.rasterize(sheet, { width: Number(size[1]), height: Number(size[2]) });
|
|
3564
|
+
return { content: [{ type: "image", data: image.data, mimeType: image.mimeType }] };
|
|
3565
|
+
}
|
|
3566
|
+
return { times, svg: sheet };
|
|
3567
|
+
}
|
|
3568
|
+
const svg = controller.toSvg(t, { pretty: false, ...overlays });
|
|
3482
3569
|
if (format === "png") {
|
|
3483
3570
|
if (!options.rasterize) throw new Error('This host cannot make PNG images; call render_animation_frame with format "svg".');
|
|
3484
3571
|
const image = await options.rasterize(svg, { width: s.artwork.width, height: s.artwork.height });
|
|
@@ -3503,9 +3590,9 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3503
3590
|
handler: ({ from = 0, to, limit = 200 }) => {
|
|
3504
3591
|
const s = scene();
|
|
3505
3592
|
const timeline = compileMotionScene(s);
|
|
3506
|
-
const words = _nullishCoalesce(_optionalChain([s, 'access',
|
|
3593
|
+
const words = _nullishCoalesce(_optionalChain([s, 'access', _100 => _100.narration, 'optionalAccess', _101 => _101.words]), () => ( []));
|
|
3507
3594
|
const end = _nullishCoalesce(to, () => ( Math.max(timeline.duration, words.length ? _nullishCoalesce(words[words.length - 1].end, () => ( words[words.length - 1].start)) : 0)));
|
|
3508
|
-
const shotAt = (ms) => _optionalChain([timeline, 'access',
|
|
3595
|
+
const shotAt = (ms) => _optionalChain([timeline, 'access', _102 => _102.shots, 'access', _103 => _103.find, 'call', _104 => _104((x) => ms >= x.start && ms < x.end), 'optionalAccess', _105 => _105.id]);
|
|
3509
3596
|
const beats = [];
|
|
3510
3597
|
if (s.beat && s.beat.bpm > 0) {
|
|
3511
3598
|
const first = Math.max(0, Math.ceil(motionBeatAt(s.beat, from).beat - 1e-9));
|
|
@@ -3755,7 +3842,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3755
3842
|
inputSchema: object({ shot: SHOT_ID, commands: { type: "array", items: MOTION_COMMAND_SCHEMA, minItems: 1, description: "Commands to add." }, at: { type: "integer", minimum: 0, description: "Index in the run (default: the end)." } }, ["shot", "commands"]),
|
|
3756
3843
|
annotations: { title: "Add commands to a shot", ...WRITE },
|
|
3757
3844
|
handler: ({ shot, commands, at }) => {
|
|
3758
|
-
const before = _nullishCoalesce(_optionalChain([scene, 'call',
|
|
3845
|
+
const before = _nullishCoalesce(_optionalChain([scene, 'call', _106 => _106(), 'access', _107 => _107.shots, 'access', _108 => _108.find, 'call', _109 => _109((s) => s.id === shot), 'optionalAccess', _110 => _110.run, 'access', _111 => _111.length]), () => ( 0));
|
|
3759
3846
|
const first = _nullishCoalesce(at, () => ( before));
|
|
3760
3847
|
return apply({ op: "add_commands", shot, commands, at }, "Add commands", (s) => {
|
|
3761
3848
|
const shots = describeMotionShots(s);
|
|
@@ -3822,12 +3909,14 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
3822
3909
|
const editAnimation = {
|
|
3823
3910
|
name: "edit_animation",
|
|
3824
3911
|
title: "Make several edits at once",
|
|
3825
|
-
description:
|
|
3912
|
+
description: `Applies several edits in order as one undo step, all or nothing: if one fails, nothing changes and the error names the op ("op 2 (add_commands): \u2026"). A later op can use what an earlier one made: "$0.indexes[0]" is the index of the first command op 1 added, "$last.shot" the shot the op before changed. Returns each op's outcome (shot, shots, indexes, clip), the timing and issues. With dry_run it only reports them.`,
|
|
3826
3913
|
inputSchema: object({ ops: { type: "array", items: EDIT_OP, minItems: 1, description: "Edits, applied in order." }, dry_run: { type: "boolean", description: "Check without applying (default false)." } }, ["ops"]),
|
|
3827
3914
|
annotations: { title: "Make several edits at once", ...WRITE },
|
|
3828
3915
|
handler: ({ ops, dry_run = false }) => {
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3916
|
+
const refs = resolveMotionEditRefs(controller.getScene(), ops);
|
|
3917
|
+
if (!refs.ok) throw new Error(refs.error);
|
|
3918
|
+
const result = controller.apply(refs.edits, "Edit animation", { dryRun: dry_run });
|
|
3919
|
+
return outcome(result, { outcomes: refs.outcomes, ...dry_run ? { dry_run: true, hint: "Nothing was applied; call again without dry_run to apply." } : {} });
|
|
3831
3920
|
}
|
|
3832
3921
|
};
|
|
3833
3922
|
const writeAnimation = {
|
|
@@ -3934,7 +4023,8 @@ Commands
|
|
|
3934
4023
|
Working method
|
|
3935
4024
|
1. get_animation to learn the element ids (set_animation_artwork_svg first if there is no artwork: give every element you will animate an id; or import_flair_effect to start from a Flair effect and edit it).
|
|
3936
4025
|
2. Plan a few shots, each one idea. Add them with insert_shots (add_commands, update_command, move_command and delete_commands refine a shot), or edit_animation to make several edits as one step (dry_run first when unsure).
|
|
3937
|
-
|
|
4026
|
+
- In edit_animation, a later op can use what an earlier one made: "$0.indexes[0]" (the first command op 1 added), "$last.shot".
|
|
4027
|
+
3. To hit a length, fit_animation (keep the shots whose pace matters). check_animation and fix every error and warning; render_animation_frame (shot + "end") to look at the result, or with "times" for a contact sheet of several moments; add onion_skin or motion_paths to see the motion in one picture, or get_motion_path for the numbers.
|
|
3938
4028
|
- For something the viewer plays (a button, a toggle, a step-by-step explainer), set "trigger" with set_animation_settings: click plays the next shot on each click and then starts over (make the last shot put things back for a toggle), hover or press plays and rewinds, scroll scrubs.
|
|
3939
4029
|
4. To make a reusable Flair effect, set_animation_controls (colour controls stand for every use of their default colour) and export_flair_effect.
|
|
3940
4030
|
|
|
@@ -3945,7 +4035,7 @@ var TIMING = /* @__PURE__ */ new Set(["duration", "delay", "stagger", "with", "e
|
|
|
3945
4035
|
var COLORS = /* @__PURE__ */ new Set(["fill", "stroke", "color"]);
|
|
3946
4036
|
var NODES = /* @__PURE__ */ new Set(["into", "path"]);
|
|
3947
4037
|
function branch(type) {
|
|
3948
|
-
return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access',
|
|
4038
|
+
return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _112 => _112.properties, 'optionalAccess', _113 => _113.type, 'optionalAccess', _114 => _114.const]) === type);
|
|
3949
4039
|
}
|
|
3950
4040
|
function unitOf(type, name) {
|
|
3951
4041
|
if (name === "duration" || name === "delay" || name === "stagger") return "ms";
|
|
@@ -3980,7 +4070,7 @@ function kindOf(name, schema) {
|
|
|
3980
4070
|
}
|
|
3981
4071
|
function motionCommandFields(type) {
|
|
3982
4072
|
const schema = branch(type);
|
|
3983
|
-
if (!_optionalChain([schema, 'optionalAccess',
|
|
4073
|
+
if (!_optionalChain([schema, 'optionalAccess', _115 => _115.properties])) return [];
|
|
3984
4074
|
const required = new Set(_nullishCoalesce(schema.required, () => ( [])));
|
|
3985
4075
|
const fields = Object.entries(schema.properties).filter(([name]) => name !== "type").map(([name, s]) => {
|
|
3986
4076
|
const kind = kindOf(name, s);
|
|
@@ -4037,7 +4127,7 @@ function defaultMotionCommand(type, targets, scene) {
|
|
|
4037
4127
|
if (type === "wait") return { type: "wait", duration: 500 };
|
|
4038
4128
|
if (!targets.length) return { error: "Pick a target first: click an element on the stage." };
|
|
4039
4129
|
const nodes = [...indexMotionNodes(scene.artwork.nodes).values()];
|
|
4040
|
-
const other = (pred) => _optionalChain([nodes, 'access',
|
|
4130
|
+
const other = (pred) => _optionalChain([nodes, 'access', _116 => _116.find, 'call', _117 => _117((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _118 => _118.node, 'access', _119 => _119.id]);
|
|
4041
4131
|
const base = { targets: [...targets] };
|
|
4042
4132
|
switch (type) {
|
|
4043
4133
|
case "scale":
|
|
@@ -4068,8 +4158,8 @@ function defaultMotionCommand(type, targets, scene) {
|
|
|
4068
4158
|
}
|
|
4069
4159
|
case "effect": {
|
|
4070
4160
|
for (const id of targets) {
|
|
4071
|
-
const node = _optionalChain([nodes, 'access',
|
|
4072
|
-
for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess',
|
|
4161
|
+
const node = _optionalChain([nodes, 'access', _120 => _120.find, 'call', _121 => _121((e) => e.node.id === id), 'optionalAccess', _122 => _122.node]);
|
|
4162
|
+
for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _123 => _123.effects]), () => ( []))) {
|
|
4073
4163
|
const param = Object.entries(effect.params).find(([, v]) => typeof v === "number");
|
|
4074
4164
|
if (param) return { type, ...base, effect: effect.id, param: param[0], to: param[1] + 1 };
|
|
4075
4165
|
}
|
|
@@ -4094,11 +4184,11 @@ function motionCommandRows(scene, shotId) {
|
|
|
4094
4184
|
return scene.shots[index].run.map((command2, i) => {
|
|
4095
4185
|
const t = timeline.commands.find((c) => c.shotIndex === index && c.command === i);
|
|
4096
4186
|
const primitive = motionFlairPrimitive(command2);
|
|
4097
|
-
return { index: i, command: command2, summary: motionCommandSummary(command2), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess',
|
|
4187
|
+
return { index: i, command: command2, summary: motionCommandSummary(command2), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _124 => _124.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _125 => _125.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
|
|
4098
4188
|
});
|
|
4099
4189
|
}
|
|
4100
4190
|
function duplicateMotionCommandEdit(scene, shot, command2) {
|
|
4101
|
-
const run = _nullishCoalesce(_optionalChain([scene, 'access',
|
|
4191
|
+
const run = _nullishCoalesce(_optionalChain([scene, 'access', _126 => _126.shots, 'access', _127 => _127.find, 'call', _128 => _128((s) => s.id === shot), 'optionalAccess', _129 => _129.run]), () => ( []));
|
|
4102
4192
|
return { op: "add_commands", shot, commands: run[command2] ? [structuredClone(run[command2])] : [], at: command2 + 1 };
|
|
4103
4193
|
}
|
|
4104
4194
|
var MOTION_EASE_CHOICES = [
|
|
@@ -4183,7 +4273,7 @@ function motionCueFromKey(key) {
|
|
|
4183
4273
|
function motionCueChoices(scene, limit = 256) {
|
|
4184
4274
|
const choices = [];
|
|
4185
4275
|
const s = (ms) => `${(ms / 1e3).toFixed(2)} s`;
|
|
4186
|
-
const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access',
|
|
4276
|
+
const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _130 => _130.narration, 'optionalAccess', _131 => _131.words, 'access', _132 => _132.map, 'call', _133 => _133((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
|
|
4187
4277
|
if (scene.beat && scene.beat.bpm > 0) {
|
|
4188
4278
|
for (let beat = 0; choices.length < limit; beat++) {
|
|
4189
4279
|
const time = motionBeatTime(scene.beat, beat);
|
|
@@ -4193,7 +4283,7 @@ function motionCueChoices(scene, limit = 256) {
|
|
|
4193
4283
|
choices.push({ value: `beat:${beat}`, label: `Beat ${beat} (bar ${at.bar}.${at.beatInBar}) \xB7 ${s(time)}`, time });
|
|
4194
4284
|
}
|
|
4195
4285
|
}
|
|
4196
|
-
_optionalChain([scene, 'access',
|
|
4286
|
+
_optionalChain([scene, 'access', _134 => _134.narration, 'optionalAccess', _135 => _135.words, 'access', _136 => _136.forEach, 'call', _137 => _137((w, i) => {
|
|
4197
4287
|
if (choices.length < limit * 2) choices.push({ value: `word:${i}`, label: `Word ${i} \u201C${w.text}\u201D \xB7 ${s(w.start)}`, time: w.start });
|
|
4198
4288
|
})]);
|
|
4199
4289
|
return choices;
|
|
@@ -4202,7 +4292,7 @@ function motionShotCueTime(scene, cue) {
|
|
|
4202
4292
|
return cue ? motionCueTime(scene, cue) : void 0;
|
|
4203
4293
|
}
|
|
4204
4294
|
function formatMotionNarration(narration) {
|
|
4205
|
-
return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess',
|
|
4295
|
+
return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _138 => _138.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
|
|
4206
4296
|
}
|
|
4207
4297
|
function parseMotionNarration(text) {
|
|
4208
4298
|
const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
@@ -4342,5 +4432,7 @@ function parseMotionNarration(text) {
|
|
|
4342
4432
|
|
|
4343
4433
|
|
|
4344
4434
|
|
|
4345
|
-
|
|
4435
|
+
|
|
4436
|
+
|
|
4437
|
+
exports.ANIMATION_EDITOR_AGENT_INSTRUCTIONS = ANIMATION_EDITOR_AGENT_INSTRUCTIONS; exports.AnimationEditorController = AnimationEditorController; exports.FLAIR_EASES = FLAIR_EASES; exports.FLAIR_EXPORT_VERSION = FLAIR_EXPORT_VERSION; exports.MOTION_ADDITIVE_PROPERTIES = MOTION_ADDITIVE_PROPERTIES; exports.MOTION_BLENDS = MOTION_BLENDS; exports.MOTION_CAMERA_MS = MOTION_CAMERA_MS; exports.MOTION_CLIP_TARGET = MOTION_CLIP_TARGET; exports.MOTION_COMMAND_SCHEMA = MOTION_COMMAND_SCHEMA; exports.MOTION_COMMAND_TYPES = MOTION_COMMAND_TYPES; exports.MOTION_DEFAULT_DURATIONS = MOTION_DEFAULT_DURATIONS; exports.MOTION_DEFAULT_HOLD = MOTION_DEFAULT_HOLD; exports.MOTION_DIRECTIONS = MOTION_DIRECTIONS; exports.MOTION_DRAW_EFFECT_ID = MOTION_DRAW_EFFECT_ID; exports.MOTION_DRAW_MS_PER_UNIT = MOTION_DRAW_MS_PER_UNIT; exports.MOTION_DRAW_RANGE = MOTION_DRAW_RANGE; exports.MOTION_EASE_CHOICES = MOTION_EASE_CHOICES; exports.MOTION_EASE_IN_OUT = MOTION_EASE_IN_OUT; exports.MOTION_EASE_OUT = MOTION_EASE_OUT; exports.MOTION_EDIT_OPS = MOTION_EDIT_OPS; exports.MOTION_ENTER_STYLES = MOTION_ENTER_STYLES; exports.MOTION_EXIT_STYLES = MOTION_EXIT_STYLES; exports.MOTION_IRIS_SHAPES = MOTION_IRIS_SHAPES; exports.MOTION_ISSUE_CODES = MOTION_ISSUE_CODES; exports.MOTION_MIN_CHANGE_MS = MOTION_MIN_CHANGE_MS; exports.MOTION_REPEAT_MODES = MOTION_REPEAT_MODES; exports.MOTION_SPEED_RANGE = MOTION_SPEED_RANGE; exports.MOTION_SPLIT_ORIENTATIONS = MOTION_SPLIT_ORIENTATIONS; exports.MOTION_TRIGGERS = MOTION_TRIGGERS; exports.MotionSceneFormatError = MotionSceneFormatError; exports.activeSegment = activeSegment; exports.applyMotionControlValues = applyMotionControlValues; exports.applyMotionEdits = applyMotionEdits; exports.checkMotionScene = checkMotionScene; exports.clipsShapeProblems = clipsShapeProblems; exports.commandShapeProblems = commandShapeProblems; exports.compileMotionScene = compileMotionScene; exports.createAnimationEditorToolProvider = createAnimationEditorToolProvider; exports.createMotionScene = createMotionScene; exports.defaultMotionCommand = defaultMotionCommand; exports.describeMotionElements = describeMotionElements; exports.describeMotionShots = describeMotionShots; exports.duplicateMotionCommandEdit = duplicateMotionCommandEdit; exports.fitMotionRect = fitMotionRect; exports.fitMotionScene = fitMotionScene; exports.fitMotionSceneEdits = fitMotionSceneEdits; exports.flairAtLeast = flairAtLeast; exports.flairCurveFor = flairCurveFor; exports.flairEaseFor = flairEaseFor; exports.formatMotionNarration = formatMotionNarration; exports.freshShotId = freshShotId; exports.fromFlairSvgMotion = fromFlairSvgMotion; exports.fromFlairVectorEffect = fromFlairVectorEffect; exports.highlightMotionSvg = highlightMotionSvg; exports.indexMotionNodes = indexMotionNodes; exports.interpolateMotionValue = interpolateMotionValue; exports.isMotionCommand = isMotionCommand; exports.isMotionShot = isMotionShot; exports.matchMotionNodes = matchMotionNodes; exports.motionAddTrackKey = motionAddTrackKey; exports.motionBeatAt = motionBeatAt; exports.motionBeatTime = motionBeatTime; exports.motionClipAttrs = motionClipAttrs; exports.motionClipLayout = motionClipLayout; exports.motionCommandDuration = motionCommandDuration; exports.motionCommandFields = motionCommandFields; exports.motionCommandRepeat = motionCommandRepeat; exports.motionCommandRows = motionCommandRows; exports.motionCommandSummary = motionCommandSummary; exports.motionContactSheetSvg = motionContactSheetSvg; exports.motionCueChoices = motionCueChoices; exports.motionCueFromKey = motionCueFromKey; exports.motionCueKey = motionCueKey; exports.motionCueTime = motionCueTime; exports.motionCycleDuration = motionCycleDuration; exports.motionEaseKey = motionEaseKey; exports.motionEasingCurve = motionEasingCurve; exports.motionEasingGuides = motionEasingGuides; exports.motionEasingPath = motionEasingPath; exports.motionFieldEdit = motionFieldEdit; exports.motionFieldLabel = motionFieldLabel; exports.motionFlairPrimitive = motionFlairPrimitive; exports.motionFollowRoute = motionFollowRoute; exports.motionFrameAt = motionFrameAt; exports.motionFrameToSvg = motionFrameToSvg; exports.motionGhosts = motionGhosts; exports.motionIssue = motionIssue; exports.motionIssueKey = motionIssueKey; exports.motionIssueLine = motionIssueLine; exports.motionMovingIds = motionMovingIds; exports.motionNodeAtElement = motionNodeAtElement; exports.motionNodeClips = motionNodeClips; exports.motionNodeOffset = motionNodeOffset; exports.motionPath = motionPath; exports.motionPathLength = motionPathLength; exports.motionPathsSvg = motionPathsSvg; exports.motionRestValue = motionRestValue; exports.motionRevealClip = motionRevealClip; exports.motionRevealPadding = motionRevealPadding; exports.motionRulerTicks = motionRulerTicks; exports.motionSceneShapeProblems = motionSceneShapeProblems; exports.motionSceneToJson = motionSceneToJson; exports.motionShotAt = motionShotAt; exports.motionShotCueTime = motionShotCueTime; exports.motionShotTimeScale = motionShotTimeScale; exports.motionStageSvg = motionStageSvg; exports.motionTrackKey = motionTrackKey; exports.namedWithSuggestion = namedWithSuggestion; exports.parseMotionFieldInput = parseMotionFieldInput; exports.parseMotionNarration = parseMotionNarration; exports.parseMotionScene = parseMotionScene; exports.resolveMotionCamera = resolveMotionCamera; exports.resolveMotionEditRefs = resolveMotionEditRefs; exports.segmentProgress = segmentProgress; exports.segmentValue = segmentValue; exports.shotShapeProblems = shotShapeProblems; exports.smoothMotionLegs = smoothMotionLegs; exports.smoothMotionTimes = smoothMotionTimes; exports.suggestName = suggestName; exports.toFlairEffectDocument = toFlairEffectDocument; exports.toFlairSvgMotion = toFlairSvgMotion; exports.toFlairVectorEffect = toFlairVectorEffect; exports.toLottie = toLottie; exports.trackValue = trackValue; exports.withMotionLayers = withMotionLayers; exports.withViewBox = withViewBox;
|
|
4346
4438
|
//# sourceMappingURL=index.cjs.map
|