@pixerate/editor 0.266.1 → 0.267.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/agent/index.cjs +8 -4
- package/dist/agent/index.js +6 -2
- package/dist/animation-editor/controller.d.cts +8 -0
- package/dist/animation-editor/controller.d.ts +8 -0
- package/dist/animation-editor/effect-tools.d.cts +1 -1
- package/dist/animation-editor/effect-tools.d.ts +1 -1
- package/dist/animation-editor/index.cjs +172 -105
- package/dist/animation-editor/index.js +91 -24
- package/dist/brushes/index.cjs +59 -59
- package/dist/brushes/index.js +5 -5
- package/dist/brushes/profiles.d.cts +6 -1
- package/dist/brushes/profiles.d.ts +6 -1
- package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-L7JYRR2R.cjs} +16 -16
- package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-NLFPEBGI.js} +4 -4
- package/dist/canvas/brushTypes.d.cts +12 -0
- package/dist/canvas/brushTypes.d.ts +12 -0
- package/dist/canvas/brushstroke.d.cts +1 -1
- package/dist/canvas/brushstroke.d.ts +1 -1
- package/dist/canvas/drawController.d.cts +19 -4
- package/dist/canvas/drawController.d.ts +19 -4
- package/dist/canvas/index.cjs +144 -105
- package/dist/canvas/index.js +46 -7
- package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
- package/dist/{chunk-T2LDTEXK.js → chunk-4IDUYB45.js} +2217 -56
- package/dist/chunk-7UKFXXWL.js +802 -0
- package/dist/chunk-ADMRNWR7.js +340 -0
- package/dist/{chunk-CIJBSUM5.js → chunk-AGNUD5BI.js} +2 -2
- package/dist/{chunk-WLUVZKVD.cjs → chunk-DT4YQUGT.cjs} +32 -32
- package/dist/{chunk-DXYHQ2VN.js → chunk-EF7LZAXQ.js} +1 -1
- package/dist/chunk-EXB2EGBE.cjs +802 -0
- package/dist/{chunk-4ODRXQRW.js → chunk-EYSHTYLG.js} +1 -1
- package/dist/{chunk-R44Y3EFS.js → chunk-FGJHJIMN.js} +8 -336
- package/dist/{chunk-AQZQWXEU.cjs → chunk-G7NHE2VD.cjs} +35 -35
- package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
- package/dist/{chunk-VRK322ZC.cjs → chunk-HIO6E7LC.cjs} +2 -2
- package/dist/{chunk-TOID45I2.cjs → chunk-J2TNIZ55.cjs} +1 -1
- package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
- package/dist/{chunk-3C33YTNN.js → chunk-JGWVZPT6.js} +2 -2
- package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
- package/dist/{chunk-3SBLVGOM.cjs → chunk-LA5Y4ETA.cjs} +23 -23
- package/dist/{chunk-MVUQSK5J.cjs → chunk-LHPEG5AU.cjs} +107 -435
- package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
- package/dist/{chunk-XRXFVRGY.cjs → chunk-OKHKA43L.cjs} +2364 -203
- package/dist/{chunk-LK4SXL3V.js → chunk-OSEXT7JL.js} +1 -1
- package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
- package/dist/{chunk-ZQI3WUPP.js → chunk-QCLY5SFS.js} +12 -0
- package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
- package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
- package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
- package/dist/{chunk-RFJZGTHA.cjs → chunk-XVOP3CGQ.cjs} +9 -9
- package/dist/{chunk-EZOJBP4D.js → chunk-YIC6MAJ2.js} +1 -1
- package/dist/chunk-YZWM6ZIP.cjs +340 -0
- package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
- package/dist/{chunk-YBC3RKT2.cjs → chunk-ZGXJ7BTR.cjs} +13 -1
- package/dist/commands/builtins.d.cts +12 -1
- package/dist/commands/builtins.d.ts +12 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/controller.d.cts +1 -1
- package/dist/image-editor/controller.d.ts +1 -1
- package/dist/image-editor/index.cjs +837 -833
- package/dist/image-editor/index.js +105 -101
- package/dist/paint/index.cjs +5 -3
- package/dist/paint/index.js +46 -44
- package/dist/paint-editor/controller.d.cts +5 -3
- package/dist/paint-editor/controller.d.ts +5 -3
- package/dist/paint-editor/index.cjs +832 -2295
- package/dist/paint-editor/index.js +285 -1748
- package/dist/paint-editor/path-samples.d.cts +2 -0
- package/dist/paint-editor/path-samples.d.ts +2 -0
- package/dist/paint-editor/presence.d.cts +20 -1
- package/dist/paint-editor/presence.d.ts +20 -1
- package/dist/stickers/helpers.d.cts +2 -0
- package/dist/stickers/helpers.d.ts +2 -0
- package/dist/stickers/index.cjs +41 -35
- package/dist/stickers/index.js +22 -16
- package/dist/stickers/types.d.cts +4 -2
- package/dist/stickers/types.d.ts +4 -2
- package/dist/tools/conformance.d.cts +8 -0
- package/dist/tools/conformance.d.ts +8 -0
- package/dist/tools/index.cjs +6 -2
- package/dist/tools/index.js +5 -1
- package/dist/vector/backdrop.d.cts +13 -0
- package/dist/vector/backdrop.d.ts +13 -0
- package/dist/vector/brushstroke.d.cts +54 -7
- package/dist/vector/brushstroke.d.ts +54 -7
- package/dist/vector/brushstrokeMedia.d.cts +96 -0
- package/dist/vector/brushstrokeMedia.d.ts +96 -0
- package/dist/vector/controller.d.cts +17 -3
- package/dist/vector/controller.d.ts +17 -3
- package/dist/vector/index.cjs +1846 -1386
- package/dist/vector/index.d.cts +2 -0
- package/dist/vector/index.d.ts +2 -0
- package/dist/vector/index.js +517 -57
- package/dist/vector/render.d.cts +6 -0
- package/dist/vector/render.d.ts +6 -0
- package/dist/vector/types.d.cts +14 -0
- package/dist/vector/types.d.ts +14 -0
- package/package.json +1 -1
- package/skills/pixerate-animation-editor/SKILL.md +1 -0
- package/skills/pixerate-brushes/SKILL.md +2 -2
- package/skills/pixerate-brushes-design/SKILL.md +7 -4
- package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
- package/skills/pixerate-canvas/SKILL.md +11 -1
- package/skills/pixerate-image-editor/SKILL.md +19 -64
- package/skills/pixerate-image-editor/references/color-management.md +2 -1
- package/skills/pixerate-image-editor/references/free-transform.md +12 -0
- package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
- package/skills/pixerate-image-editor/references/painting.md +17 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
- package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
- package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
- package/skills/pixerate-paint-editor/SKILL.md +8 -4
- package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
- package/skills/pixerate-vector/SKILL.md +16 -6
- package/skills/pixerate-vector/references/best-practices.md +1 -0
- package/skills/pixerate-vector/references/commands.md +19 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkG7NHE2VDcjs = require('../chunk-G7NHE2VD.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -39,9 +39,9 @@ var _chunk557BDWKOcjs = require('../chunk-557BDWKO.cjs');
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
var
|
|
43
|
-
require('../chunk-
|
|
44
|
-
require('../chunk-
|
|
42
|
+
var _chunkOKHKA43Lcjs = require('../chunk-OKHKA43L.cjs');
|
|
43
|
+
require('../chunk-XVOP3CGQ.cjs');
|
|
44
|
+
require('../chunk-RDFHWAHL.cjs');
|
|
45
45
|
require('../chunk-CVFAAZXE.cjs');
|
|
46
46
|
|
|
47
47
|
|
|
@@ -74,6 +74,7 @@ var _chunkPY4GWSE2cjs = require('../chunk-PY4GWSE2.cjs');
|
|
|
74
74
|
|
|
75
75
|
var _chunkL2JTLW6Bcjs = require('../chunk-L2JTLW6B.cjs');
|
|
76
76
|
require('../chunk-WOFXZ3XU.cjs');
|
|
77
|
+
require('../chunk-J5VQYK7T.cjs');
|
|
77
78
|
require('../chunk-PXDIAYB6.cjs');
|
|
78
79
|
require('../chunk-FQPUF2W2.cjs');
|
|
79
80
|
require('../chunk-3K6HWEXZ.cjs');
|
|
@@ -705,7 +706,7 @@ function smoothMotionTimes(points, start, duration, pacing = "even") {
|
|
|
705
706
|
function motionTextLayout(nodes, id) {
|
|
706
707
|
const group = _optionalChain([nodes, 'access', _5 => _5.get, 'call', _6 => _6(id), 'optionalAccess', _7 => _7.node]);
|
|
707
708
|
if (!group || group.type !== "group") return null;
|
|
708
|
-
const letters =
|
|
709
|
+
const letters = _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, group).map((p) => ({ id: p.id, b: _optionalChain([nodes, 'access', _8 => _8.get, 'call', _9 => _9(p.id), 'optionalAccess', _10 => _10.bounds]) })).filter((l) => !!l.b && l.b.width + l.b.height > 0);
|
|
709
710
|
if (!letters.length) return null;
|
|
710
711
|
const lines = [];
|
|
711
712
|
for (const l of [...letters].sort((a, c) => a.b.y + a.b.height / 2 - (c.b.y + c.b.height / 2))) {
|
|
@@ -790,21 +791,21 @@ function indexMotionNodes(nodes) {
|
|
|
790
791
|
const out = /* @__PURE__ */ new Map();
|
|
791
792
|
const walk = (list, parentWorld, ancestors) => {
|
|
792
793
|
for (const node of list) {
|
|
793
|
-
const local =
|
|
794
|
-
const bounds =
|
|
794
|
+
const local = _chunkOKHKA43Lcjs.vectorNodeBounds.call(void 0, node);
|
|
795
|
+
const bounds = _chunkOKHKA43Lcjs.vectorNodeBounds.call(void 0, node, parentWorld);
|
|
795
796
|
const center = local ? { x: local.x + local.width / 2, y: local.y + local.height / 2 } : { x: 0, y: 0 };
|
|
796
797
|
if (!out.has(node.id)) out.set(node.id, { node, ancestors, parentWorld, center, bounds, box: local });
|
|
797
|
-
if (node.type === "group") walk(node.children,
|
|
798
|
+
if (node.type === "group") walk(node.children, _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, node), parentWorld), [...ancestors, node.id]);
|
|
798
799
|
}
|
|
799
800
|
};
|
|
800
|
-
walk(nodes,
|
|
801
|
+
walk(nodes, _chunkOKHKA43Lcjs.IDENTITY_MATRIX, []);
|
|
801
802
|
indexCache.set(nodes, out);
|
|
802
803
|
return out;
|
|
803
804
|
}
|
|
804
805
|
var solid = (paint) => typeof paint === "string" && paint !== "none" ? paint : void 0;
|
|
805
806
|
function firstPaint(node, key) {
|
|
806
807
|
if (node.type === "path") return solid(node[key]);
|
|
807
|
-
for (const p of
|
|
808
|
+
for (const p of _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node)) {
|
|
808
809
|
const s = solid(p[key]);
|
|
809
810
|
if (s) return s;
|
|
810
811
|
}
|
|
@@ -812,7 +813,7 @@ function firstPaint(node, key) {
|
|
|
812
813
|
}
|
|
813
814
|
function strokeReach(node) {
|
|
814
815
|
let reach = 0;
|
|
815
|
-
for (const p of node.type === "path" ? [node] :
|
|
816
|
+
for (const p of node.type === "path" ? [node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node)) {
|
|
816
817
|
if (p.stroke == null || p.stroke === "none") continue;
|
|
817
818
|
const width = _nullishCoalesce(p.strokeWidth, () => ( 1));
|
|
818
819
|
reach = Math.max(reach, p.strokeAlign === "outside" ? width : p.strokeAlign === "inside" ? 0 : width / 2);
|
|
@@ -882,7 +883,7 @@ function motionRestValue(entry, property, artwork) {
|
|
|
882
883
|
case "stroke":
|
|
883
884
|
return _nullishCoalesce((node && firstPaint(node, property)), () => ( "transparent"));
|
|
884
885
|
case "strokeWidth": {
|
|
885
|
-
const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ?
|
|
886
|
+
const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node)[0] : void 0;
|
|
886
887
|
return _nullishCoalesce(_optionalChain([path, 'optionalAccess', _14 => _14.strokeWidth]), () => ( 1));
|
|
887
888
|
}
|
|
888
889
|
case "shape":
|
|
@@ -993,12 +994,12 @@ function resolveMotionCamera(camera, scene) {
|
|
|
993
994
|
const r = camera;
|
|
994
995
|
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
995
996
|
}
|
|
996
|
-
function motionPathLength(node, parentWorld =
|
|
997
|
+
function motionPathLength(node, parentWorld = _chunkOKHKA43Lcjs.IDENTITY_MATRIX) {
|
|
997
998
|
let longest = 0;
|
|
998
|
-
const paths = node.type === "path" ? [node] :
|
|
999
|
+
const paths = node.type === "path" ? [node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node);
|
|
999
1000
|
for (const p of paths) {
|
|
1000
1001
|
try {
|
|
1001
|
-
longest = Math.max(longest, _chunkGF2RBSDMcjs.bezierPathLength.call(void 0,
|
|
1002
|
+
longest = Math.max(longest, _chunkGF2RBSDMcjs.bezierPathLength.call(void 0, _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
|
|
1002
1003
|
} catch (e2) {
|
|
1003
1004
|
}
|
|
1004
1005
|
}
|
|
@@ -1274,12 +1275,12 @@ function compileMotionScene(scene) {
|
|
|
1274
1275
|
const order2 = _nullishCoalesce(o.order, () => ( "together"));
|
|
1275
1276
|
const pace = _nullishCoalesce(o.pace, () => ( "time"));
|
|
1276
1277
|
if (order2 === "together" && pace === "time") return null;
|
|
1277
|
-
const paths = entry.node.type === "path" ? [entry.node] :
|
|
1278
|
+
const paths = entry.node.type === "path" ? [entry.node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, entry.node);
|
|
1278
1279
|
let list = paths.map((p) => {
|
|
1279
1280
|
const at = nodes.get(p.id);
|
|
1280
1281
|
let first = { x: 0, y: 0 };
|
|
1281
1282
|
try {
|
|
1282
|
-
const m =
|
|
1283
|
+
const m = _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _42 => _42.parentWorld]), () => ( _chunkOKHKA43Lcjs.IDENTITY_MATRIX)), { effects: false })[0];
|
|
1283
1284
|
if (m && m.type === "M") first = { x: m.x, y: m.y };
|
|
1284
1285
|
} catch (e3) {
|
|
1285
1286
|
}
|
|
@@ -1391,17 +1392,17 @@ function compileMotionScene(scene) {
|
|
|
1391
1392
|
let dx = _nullishCoalesce(_optionalChain([command3, 'access', _45 => _45.by, 'optionalAccess', _46 => _46.x]), () => ( 0));
|
|
1392
1393
|
let dy = _nullishCoalesce(_optionalChain([command3, 'access', _47 => _47.by, 'optionalAccess', _48 => _48.y]), () => ( 0));
|
|
1393
1394
|
if (command3.to) {
|
|
1394
|
-
const inv =
|
|
1395
|
-
const target =
|
|
1395
|
+
const inv = _chunkOKHKA43Lcjs.invertMatrix.call(void 0, entry.parentWorld);
|
|
1396
|
+
const target = _chunkOKHKA43Lcjs.applyMatrix.call(void 0, inv, command3.to);
|
|
1396
1397
|
dx = target.x - (entry.center.x + num2("x"));
|
|
1397
1398
|
dy = target.y - (entry.center.y + num2("y"));
|
|
1398
1399
|
}
|
|
1399
1400
|
if (_optionalChain([command3, 'access', _49 => _49.via, 'optionalAccess', _50 => _50.length])) {
|
|
1400
|
-
const inv =
|
|
1401
|
+
const inv = _chunkOKHKA43Lcjs.invertMatrix.call(void 0, entry.parentWorld);
|
|
1401
1402
|
const x0 = num2("x");
|
|
1402
1403
|
const y0 = num2("y");
|
|
1403
1404
|
const add = command3.blend === "add";
|
|
1404
|
-
const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) =>
|
|
1405
|
+
const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) => _chunkOKHKA43Lcjs.applyMatrix.call(void 0, inv, p)).map((p) => ({ x: p.x - entry.center.x - x0, y: p.y - entry.center.y - y0 })), { x: dx, y: dy }];
|
|
1405
1406
|
const times = _optionalChain([command3, 'access', _51 => _51.times, 'optionalAccess', _52 => _52.length]) === command3.via.length ? [start, ...command3.times.map((f) => start + f * (end - start)), end] : smoothMotionTimes(offsets, start, end - start, _nullishCoalesce(command3.pacing, () => ( "even")));
|
|
1406
1407
|
for (const axis of ["x", "y"]) {
|
|
1407
1408
|
const base = add ? 0 : axis === "x" ? x0 : y0;
|
|
@@ -2024,13 +2025,13 @@ function morphBetween(a, b) {
|
|
|
2024
2025
|
let inner = morphCache.get(a);
|
|
2025
2026
|
if (!inner) morphCache.set(a, inner = /* @__PURE__ */ new WeakMap());
|
|
2026
2027
|
let morph = inner.get(b);
|
|
2027
|
-
if (!morph) inner.set(b, morph =
|
|
2028
|
+
if (!morph) inner.set(b, morph = _chunkG7NHE2VDcjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
|
|
2028
2029
|
return morph;
|
|
2029
2030
|
}
|
|
2030
2031
|
function shapeIn(entry, shape) {
|
|
2031
2032
|
if (shape === entry) return entry.node;
|
|
2032
|
-
const m =
|
|
2033
|
-
return { ...shape.node, ...
|
|
2033
|
+
const m = _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, shape.node), shape.parentWorld), _chunkOKHKA43Lcjs.invertMatrix.call(void 0, entry.parentWorld));
|
|
2034
|
+
return { ...shape.node, ..._chunkOKHKA43Lcjs.isIdentityMatrix.call(void 0, m) ? { transform: void 0 } : { transform: m } };
|
|
2034
2035
|
}
|
|
2035
2036
|
function shapeAt(entry, timeline, nodes, time) {
|
|
2036
2037
|
const track = timeline.tracks.get(motionTrackKey(entry.node.id, "shape"));
|
|
@@ -2050,7 +2051,7 @@ function shapeAt(entry, timeline, nodes, time) {
|
|
|
2050
2051
|
function motionFollowRoute(entry, path) {
|
|
2051
2052
|
if (!path || path.node.type !== "path") return null;
|
|
2052
2053
|
try {
|
|
2053
|
-
return _chunkGF2RBSDMcjs.transformBezierPath.call(void 0,
|
|
2054
|
+
return _chunkGF2RBSDMcjs.transformBezierPath.call(void 0, _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, path.node, path.parentWorld, { effects: false }), _chunkOKHKA43Lcjs.invertMatrix.call(void 0, entry.parentWorld));
|
|
2054
2055
|
} catch (e6) {
|
|
2055
2056
|
return null;
|
|
2056
2057
|
}
|
|
@@ -2084,9 +2085,9 @@ function motionNodeOffset(entry, timeline, time, nodes = indexMotionNodes([entry
|
|
|
2084
2085
|
const scaleX = read("scaleX", 1);
|
|
2085
2086
|
const scaleY = read("scaleY", 1);
|
|
2086
2087
|
const c = entry.center;
|
|
2087
|
-
let matrix =
|
|
2088
|
+
let matrix = _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.scaleMatrix.call(void 0, scaleX, scaleY, c), _chunkOKHKA43Lcjs.rotateMatrix.call(void 0, rotation, c)), _chunkOKHKA43Lcjs.translateMatrix.call(void 0, dx, dy));
|
|
2088
2089
|
const along = follow ? followAt(entry, timeline, nodes, time) : null;
|
|
2089
|
-
if (along) matrix =
|
|
2090
|
+
if (along) matrix = _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, matrix, _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.translateMatrix.call(void 0, -c.x, -c.y), _chunkOKHKA43Lcjs.rotateMatrix.call(void 0, along.angle)), _chunkOKHKA43Lcjs.translateMatrix.call(void 0, along.x, along.y)));
|
|
2090
2091
|
return { matrix, dx, dy, rotation, scaleX, scaleY, follow: along };
|
|
2091
2092
|
}
|
|
2092
2093
|
function motionNodeClips(id, timeline, time) {
|
|
@@ -2153,7 +2154,7 @@ function motionFrameAt(scene, time, options = {}) {
|
|
|
2153
2154
|
const start = Math.min(1, Math.max(0, typeof drawStart === "number" ? drawStart : 0));
|
|
2154
2155
|
const end = Math.min(1, Math.max(0, typeof drawEnd === "number" ? drawEnd : 1));
|
|
2155
2156
|
if (start > 0 || end < 1) {
|
|
2156
|
-
const trim =
|
|
2157
|
+
const trim = _chunkOKHKA43Lcjs.createVectorEffect.call(void 0, "trim", MOTION_DRAW_EFFECT_ID, { start: tidy(start * 100), end: tidy(end * 100) });
|
|
2157
2158
|
p = { ...p, effects: [trim, ...(_nullishCoalesce(p.effects, () => ( []))).filter((e) => e.id !== MOTION_DRAW_EFFECT_ID)] };
|
|
2158
2159
|
}
|
|
2159
2160
|
}
|
|
@@ -2167,8 +2168,8 @@ function motionFrameAt(scene, time, options = {}) {
|
|
|
2167
2168
|
if (o >= 1) delete out.opacity;
|
|
2168
2169
|
}
|
|
2169
2170
|
const offset = options.offsets === false ? null : motionNodeOffset(entry, timeline, time, nodes);
|
|
2170
|
-
if (offset && !
|
|
2171
|
-
const m =
|
|
2171
|
+
if (offset && !_chunkOKHKA43Lcjs.isIdentityMatrix.call(void 0, offset.matrix)) {
|
|
2172
|
+
const m = _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, out), offset.matrix).map(tidy);
|
|
2172
2173
|
out = { ...out, transform: m };
|
|
2173
2174
|
}
|
|
2174
2175
|
return out;
|
|
@@ -2189,8 +2190,8 @@ function motionFrameToSvg(scene, time, options = {}) {
|
|
|
2189
2190
|
const wrap = { ...options.wrap };
|
|
2190
2191
|
for (const [id, clips] of Object.entries(frame.clips))
|
|
2191
2192
|
wrap[id] = [..._nullishCoalesce(wrap[id], () => ( [])), ...clips.map((clip, i) => ({ clip: { id: `${prefix}reveal-${id}-${i}`, shape: clip.shape, attrs: motionClipAttrs(clip) } }))];
|
|
2192
|
-
if (!motionSceneHasLayers(scene)) return withCameraViewEffects(withViewBox(
|
|
2193
|
-
const art =
|
|
2193
|
+
if (!motionSceneHasLayers(scene)) return withCameraViewEffects(withViewBox(_chunkOKHKA43Lcjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap }), frame.camera), frame.view, frame.camera, prefix);
|
|
2194
|
+
const art = _chunkOKHKA43Lcjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap, background: false });
|
|
2194
2195
|
let svg = withViewBox(withMotionShotLayers(art, scene, time, frame.camera, options.layers, options.background !== false), frame.camera);
|
|
2195
2196
|
const transition = options.transitions === false ? null : motionTransitionAt(scene, time);
|
|
2196
2197
|
if (transition) {
|
|
@@ -2381,8 +2382,8 @@ function visibleAt(timeline, id, time, node) {
|
|
|
2381
2382
|
if (Array.isArray(rect) && (rect[2] <= 1e-4 || rect[3] <= 1e-4)) return false;
|
|
2382
2383
|
const circle = clip("clipCircle");
|
|
2383
2384
|
if (Array.isArray(circle) && circle[2] <= 1e-4) return false;
|
|
2384
|
-
const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" :
|
|
2385
|
-
const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" ||
|
|
2385
|
+
const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node).some((p) => p.fill && p.fill !== "none");
|
|
2386
|
+
const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" || _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node).length === 0 || _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node).some((p) => {
|
|
2386
2387
|
const v = trackValue(timeline.tracks.get(motionTrackKey(p.id, "drawEnd")), time);
|
|
2387
2388
|
return typeof v !== "number" || v > 0.01;
|
|
2388
2389
|
}));
|
|
@@ -2469,7 +2470,7 @@ function checkMotionScene(scene) {
|
|
|
2469
2470
|
}
|
|
2470
2471
|
for (const id of targets) {
|
|
2471
2472
|
const node = nodes.get(id).node;
|
|
2472
|
-
const paths = node.type === "path" ? [node] :
|
|
2473
|
+
const paths = node.type === "path" ? [node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node);
|
|
2473
2474
|
if (paths.some((p) => p[key] !== void 0 && p[key] !== null && typeof p[key] !== "string"))
|
|
2474
2475
|
issues.push(_chunkDGWOGQJ5cjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient ${key}; it switches to ${color} at the end instead of blending.`, { ...where, ids: [id] }));
|
|
2475
2476
|
}
|
|
@@ -2482,7 +2483,7 @@ function checkMotionScene(scene) {
|
|
|
2482
2483
|
else
|
|
2483
2484
|
for (const id of targets) {
|
|
2484
2485
|
const node = nodes.get(id).node;
|
|
2485
|
-
const paths = node.type === "path" ? [node] :
|
|
2486
|
+
const paths = node.type === "path" ? [node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node);
|
|
2486
2487
|
if (paths.some((p) => typeof p[key] !== "string"))
|
|
2487
2488
|
issues.push(_chunkDGWOGQJ5cjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient or no ${key}, so a colour pulse cannot tint it; give it a solid ${key} or pulse the ${key === "fill" ? "stroke" : "fill"}.`, { ...where, ids: [id] }));
|
|
2488
2489
|
}
|
|
@@ -2927,7 +2928,7 @@ function motionNodePose(scene, id, time) {
|
|
|
2927
2928
|
if (!entry) throw new Error(`There is no element ${_chunkDGWOGQJ5cjs.namedWithSuggestion.call(void 0, id, [...indexMotionNodes(scene.artwork.nodes).keys()])} in the artwork.`);
|
|
2928
2929
|
const timeline = compileMotionScene(scene);
|
|
2929
2930
|
const drawn = indexMotionNodes(motionFrameAt(scene, time).document.nodes).get(id);
|
|
2930
|
-
const centre =
|
|
2931
|
+
const centre = _chunkOKHKA43Lcjs.applyMatrix.call(void 0, entry.parentWorld, { x: entry.center.x + motionPropertyValue(timeline, id, "x", time), y: entry.center.y + motionPropertyValue(timeline, id, "y", time) });
|
|
2931
2932
|
const paint = (property) => _nullishCoalesce(trackValue(timeline.tracks.get(motionTrackKey(id, property)), time), () => ( motionRestValue(entry, property, scene.artwork)));
|
|
2932
2933
|
const fill = paint("fill");
|
|
2933
2934
|
const stroke = paint("stroke");
|
|
@@ -3274,7 +3275,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
3274
3275
|
raw: (t) => transformAt(t, true)
|
|
3275
3276
|
});
|
|
3276
3277
|
}
|
|
3277
|
-
const paths = node.type === "path" ? [node] :
|
|
3278
|
+
const paths = node.type === "path" ? [node] : _chunkOKHKA43Lcjs.collectPathNodes.call(void 0, node);
|
|
3278
3279
|
for (const path of paths) {
|
|
3279
3280
|
if (pathsSeen.has(path.id)) continue;
|
|
3280
3281
|
pathsSeen.add(path.id);
|
|
@@ -3296,7 +3297,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
3296
3297
|
if (shapeSegments.length) {
|
|
3297
3298
|
if (node.type !== "path") notes.push(`"${id}" is a group: its morph or effect animation is not exported (Flair tweens one path's "d").`);
|
|
3298
3299
|
else {
|
|
3299
|
-
const inverse =
|
|
3300
|
+
const inverse = _chunkOKHKA43Lcjs.invertMatrix.call(void 0, _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, node));
|
|
3300
3301
|
channels.push({
|
|
3301
3302
|
id,
|
|
3302
3303
|
kind: "attr",
|
|
@@ -3305,9 +3306,9 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
3305
3306
|
exact: () => false,
|
|
3306
3307
|
value: (t) => {
|
|
3307
3308
|
const frame = motionFrameAt(scene, t, { draw: false, offsets: false });
|
|
3308
|
-
const now =
|
|
3309
|
+
const now = _chunkOKHKA43Lcjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call', _151 => _151(frame.document.nodes), 'access', _152 => _152.get, 'call', _153 => _153(id), 'optionalAccess', _154 => _154.node]));
|
|
3309
3310
|
if (!now || now.type !== "path") return "";
|
|
3310
|
-
const bezier = _chunkGF2RBSDMcjs.transformBezierPath.call(void 0,
|
|
3311
|
+
const bezier = _chunkGF2RBSDMcjs.transformBezierPath.call(void 0, _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, now, _chunkOKHKA43Lcjs.IDENTITY_MATRIX, { effects: false }), inverse);
|
|
3311
3312
|
return _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, bezier, { precision: Math.min(precision, 2) });
|
|
3312
3313
|
}
|
|
3313
3314
|
});
|
|
@@ -3447,7 +3448,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
3447
3448
|
}
|
|
3448
3449
|
if (scene.motionBlur) notes.push("Motion blur is drawn on the stage only; Flair plays the scene sharp.");
|
|
3449
3450
|
if (trigger && (_nullishCoalesce(scene.loop, () => ( "none"))) !== "none") notes.push(`The scene plays on ${trigger}, so its loop does not apply in Flair.`);
|
|
3450
|
-
let svg =
|
|
3451
|
+
let svg = _chunkOKHKA43Lcjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunkOKHKA43Lcjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
|
|
3451
3452
|
if (routes.length) svg = svg.replace(/^(<svg[^>]*>)/, `$1<defs>${routes.join("")}</defs>`);
|
|
3452
3453
|
let motion = { svg, animate };
|
|
3453
3454
|
if (_optionalChain([scene, 'access', _160 => _160.controls, 'optionalAccess', _161 => _161.length])) {
|
|
@@ -3545,14 +3546,14 @@ function easingOf(ease, fallback) {
|
|
|
3545
3546
|
return fallback;
|
|
3546
3547
|
}
|
|
3547
3548
|
function poseOf(value, entry) {
|
|
3548
|
-
const t =
|
|
3549
|
-
const o =
|
|
3549
|
+
const t = _chunkOKHKA43Lcjs.parseSvgTransform.call(void 0, String(value));
|
|
3550
|
+
const o = _chunkOKHKA43Lcjs.multiplyMatrices.call(void 0, _nullishCoalesce(_chunkOKHKA43Lcjs.invertMatrix.call(void 0, _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, entry.node)), () => ( [1, 0, 0, 1, 0, 0])), t);
|
|
3550
3551
|
const sx = Math.hypot(o[0], o[1]);
|
|
3551
3552
|
if (!(sx > 1e-9)) return null;
|
|
3552
3553
|
const sy = (o[0] * o[3] - o[1] * o[2]) / sx;
|
|
3553
3554
|
if (Math.abs(o[2] + o[1] / sx * sy) > 1e-6 || Math.abs(o[3] - o[0] / sx * sy) > 1e-6) return null;
|
|
3554
3555
|
const c = entry.center;
|
|
3555
|
-
const moved =
|
|
3556
|
+
const moved = _chunkOKHKA43Lcjs.applyMatrix.call(void 0, o, c);
|
|
3556
3557
|
return { dx: moved.x - c.x, dy: moved.y - c.y, rotation: Math.atan2(o[1], o[0]) * 180 / Math.PI, sx, sy };
|
|
3557
3558
|
}
|
|
3558
3559
|
var near = (a, b, eps = 1e-6) => Math.abs(a - b) < eps;
|
|
@@ -3637,7 +3638,7 @@ function fromFlairSvgMotion(input, options = {}) {
|
|
|
3637
3638
|
const notes = [];
|
|
3638
3639
|
if (!input || typeof input.svg !== "string") throw new Error('Give a Flair SvgMotion: { svg: "<svg \u2026>", animate: [ \u2026 ] }.');
|
|
3639
3640
|
const { motion, controls } = resolvePlaceholders(input, notes);
|
|
3640
|
-
const artwork =
|
|
3641
|
+
const artwork = _chunkOKHKA43Lcjs.parseVectorSvg.call(void 0, motion.svg);
|
|
3641
3642
|
const nodes = indexMotionNodes(artwork.nodes);
|
|
3642
3643
|
const byStep = /* @__PURE__ */ new Map();
|
|
3643
3644
|
for (const anim of _nullishCoalesce(motion.animate, () => ( []))) {
|
|
@@ -3884,9 +3885,9 @@ function toLottie(scene, options = {}) {
|
|
|
3884
3885
|
const items = [];
|
|
3885
3886
|
const shapeSegments = [...timeline.tracks.entries()].filter(([k]) => k.startsWith(`${path.id}\0`) && (k.endsWith("\0shape") || k.includes("\0effect:"))).flatMap(([, v]) => v);
|
|
3886
3887
|
const geometryAt = (t) => {
|
|
3887
|
-
if (!shapeSegments.length) return
|
|
3888
|
+
if (!shapeSegments.length) return _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, path);
|
|
3888
3889
|
const now = _optionalChain([indexMotionNodes, 'call', _170 => _170(motionFrameAt(scene, t, { draw: false, offsets: false }).document.nodes), 'access', _171 => _171.get, 'call', _172 => _172(path.id), 'optionalAccess', _173 => _173.node]);
|
|
3889
|
-
return now && now.type === "path" ?
|
|
3890
|
+
return now && now.type === "path" ? _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, _chunkOKHKA43Lcjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, path);
|
|
3890
3891
|
};
|
|
3891
3892
|
const rest = lottieContours(_chunkGF2RBSDMcjs.toBezierPath.call(void 0, geometryAt(0)), round4);
|
|
3892
3893
|
rest.forEach((contour, n2) => {
|
|
@@ -3959,13 +3960,13 @@ function toLottie(scene, options = {}) {
|
|
|
3959
3960
|
const innerTr = STATIC_TR();
|
|
3960
3961
|
if (node.type === "path") inner = [...pathShapes(node)];
|
|
3961
3962
|
else if (node.type === "text" || node.type === "instance") {
|
|
3962
|
-
const drawn =
|
|
3963
|
+
const drawn = _chunkOKHKA43Lcjs.expandVectorAppearance.call(void 0, node);
|
|
3963
3964
|
inner = drawn.type === "path" ? [...pathShapes(drawn)] : drawn.children.filter((c) => c.type === "path").reverse().flatMap((c) => [...pathShapes(c)]);
|
|
3964
|
-
notes.push(`"${node.id}": text is exported as its outlines${
|
|
3965
|
+
notes.push(`"${node.id}": text is exported as its outlines${_chunkOKHKA43Lcjs.vectorTextHasOutlines.call(void 0, ) ? "" : " (glyph boxes: set an outline text shaper for real glyphs)"}.`);
|
|
3965
3966
|
} else {
|
|
3966
3967
|
inner = shown(node.children).reverse().map(nodeGroup);
|
|
3967
|
-
const m =
|
|
3968
|
-
if (m !==
|
|
3968
|
+
const m = _chunkOKHKA43Lcjs.nodeMatrix.call(void 0, node);
|
|
3969
|
+
if (m !== _chunkOKHKA43Lcjs.IDENTITY_MATRIX) {
|
|
3969
3970
|
const parts = staticParts(m);
|
|
3970
3971
|
if (!parts) notes.push(`"${node.id}": its transform skews, which is not exported; it is drawn without the skew.`);
|
|
3971
3972
|
else {
|
|
@@ -3978,7 +3979,7 @@ function toLottie(scene, options = {}) {
|
|
|
3978
3979
|
const body = { ty: "gr", nm: `${node.id} (own)`, it: [...inner, innerTr] };
|
|
3979
3980
|
return { ty: "gr", nm: _nullishCoalesce(node.name, () => ( node.id)), it: [body, poseTransform(entry)] };
|
|
3980
3981
|
};
|
|
3981
|
-
const artwork = { ...scene.artwork, nodes:
|
|
3982
|
+
const artwork = { ...scene.artwork, nodes: _chunkOKHKA43Lcjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
|
|
3982
3983
|
const content = shown(artwork.nodes).reverse().map(nodeGroup);
|
|
3983
3984
|
if (artwork.background && rgba(artwork.background))
|
|
3984
3985
|
content.push({ ty: "gr", nm: "Background", it: [{ ty: "rc", nm: "Background", p: { a: 0, k: [artwork.width / 2, artwork.height / 2] }, s: { a: 0, k: [artwork.width, artwork.height] }, r: { a: 0, k: 0 } }, { ty: "fl", c: { a: 0, k: rgba(artwork.background).map(round4) }, o: { a: 0, k: 100 }, r: 1 }, STATIC_TR()] });
|
|
@@ -4077,11 +4078,11 @@ function preset(prst, w, h) {
|
|
|
4077
4078
|
const poly = (pts) => [{ closed: true, anchors: pts.map(([x, y]) => ({ x, y })) }];
|
|
4078
4079
|
switch (prst) {
|
|
4079
4080
|
case "rect":
|
|
4080
|
-
return [
|
|
4081
|
+
return [_chunkOKHKA43Lcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
4081
4082
|
case "roundRect":
|
|
4082
|
-
return [
|
|
4083
|
+
return [_chunkOKHKA43Lcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
|
|
4083
4084
|
case "ellipse":
|
|
4084
|
-
return [
|
|
4085
|
+
return [_chunkOKHKA43Lcjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
4085
4086
|
case "triangle":
|
|
4086
4087
|
return poly([[w / 2, 0], [w, h], [0, h]]);
|
|
4087
4088
|
case "rtTriangle":
|
|
@@ -4189,7 +4190,7 @@ function shapes(ctx, tree, map) {
|
|
|
4189
4190
|
let subpaths = cust ? custom(cust, w, h) : prst ? preset(prst, w, h) : null;
|
|
4190
4191
|
if (!subpaths) {
|
|
4191
4192
|
if (prst) ctx.notes.push(`"${name}" is a ${prst}, drawn as its bounding rectangle.`);
|
|
4192
|
-
subpaths = [
|
|
4193
|
+
subpaths = [_chunkOKHKA43Lcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
4193
4194
|
}
|
|
4194
4195
|
const style = kid(el, "style");
|
|
4195
4196
|
const fill = kid(spPr, "noFill") ? null : _nullishCoalesce(colour(ctx, kid(spPr, "solidFill")), () => ( (el.localName === "cxnSp" ? null : colour(ctx, kid(style, "fillRef")))));
|
|
@@ -4578,7 +4579,7 @@ function nextMotionEffectInstance(scene) {
|
|
|
4578
4579
|
walk(scene.artwork.nodes);
|
|
4579
4580
|
for (let i = 1; ; i++) if (!used.has(`fx${i}`)) return `fx${i}`;
|
|
4580
4581
|
}
|
|
4581
|
-
var motionArtworkSvg = (artwork) =>
|
|
4582
|
+
var motionArtworkSvg = (artwork) => _chunkOKHKA43Lcjs.vectorDocumentToSvg.call(void 0, artwork);
|
|
4582
4583
|
var tag = (commands, source) => commands.map((c) => c.type === "wait" ? c : { ...c, source });
|
|
4583
4584
|
function motionCommandsFromEffect(artwork, motion, source) {
|
|
4584
4585
|
const imported = fromFlairSvgMotion({ svg: motionArtworkSvg(artwork), animate: [..._nullishCoalesce(motion.animate, () => ( []))] });
|
|
@@ -4901,6 +4902,25 @@ var AnimationEditorController = (_class2 = class {
|
|
|
4901
4902
|
return { scene: { ...this.scene, shots }, label: `Apply ${d.name}`, instance, notes };
|
|
4902
4903
|
});
|
|
4903
4904
|
}
|
|
4905
|
+
async resolveVectorPath(artwork, d, path, controlName) {
|
|
4906
|
+
const controls = _chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, d);
|
|
4907
|
+
if (!controls.length) throw new Error(`"${d.id}" does not draw along a path. Find one that does with search_effects accepts ["path"] (kind vector).`);
|
|
4908
|
+
const control = _nullishCoalesce(controlName, () => ( (controls.length === 1 ? controls[0] : void 0)));
|
|
4909
|
+
if (!control) throw new Error(`"${d.id}" has several path controls (${controls.join(", ")}); pass control.`);
|
|
4910
|
+
if (!controls.includes(control)) throw new Error(`"${control}" is not a path control of "${d.id}"; its path controls are ${controls.join(", ")}.`);
|
|
4911
|
+
if ("node" in path) {
|
|
4912
|
+
const entry = indexMotionNodes(artwork.nodes).get(path.node);
|
|
4913
|
+
if (!entry) throw new Error(`There is no node "${path.node}"; find_animation_elements lists the artwork's nodes.`);
|
|
4914
|
+
if (entry.node.type !== "path") throw new Error(`Node "${path.node}" is a ${entry.node.type}, not a path; pass a path node (find_animation_elements shows each node's type).`);
|
|
4915
|
+
const value2 = _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, _chunkOKHKA43Lcjs.vectorPathWorldBezier.call(void 0, entry.node, entry.parentWorld, { effects: false }));
|
|
4916
|
+
return { control, value: value2, place: "viewBox" };
|
|
4917
|
+
}
|
|
4918
|
+
const provider = this.effects.require();
|
|
4919
|
+
if (!provider.pathFromText) throw new Error(`The effects provider "${provider.id}" cannot write words as a path; pass a path node instead.`);
|
|
4920
|
+
if (typeof path.text !== "string" || !path.text.trim()) throw new Error("text is empty; pass the words to write.");
|
|
4921
|
+
const value = await provider.pathFromText(path.text, { ...path.font ? { font: path.font } : {}, ...path.align ? { align: path.align } : {} });
|
|
4922
|
+
return { control, value };
|
|
4923
|
+
}
|
|
4904
4924
|
/**
|
|
4905
4925
|
* Adds a provider vector effect (one with its own picture: a lower third, a loader): its SVG as
|
|
4906
4926
|
* an artwork group (id: the instance) fitted into `box` (default the whole artwork), and its
|
|
@@ -4912,25 +4932,9 @@ var AnimationEditorController = (_class2 = class {
|
|
|
4912
4932
|
let given = options.values;
|
|
4913
4933
|
let place = options.box;
|
|
4914
4934
|
if (options.path) {
|
|
4915
|
-
const
|
|
4916
|
-
if (
|
|
4917
|
-
|
|
4918
|
-
if (!control) throw new Error(`"${d.id}" has several path controls (${controls.join(", ")}); pass control.`);
|
|
4919
|
-
if (!controls.includes(control)) throw new Error(`"${control}" is not a path control of "${d.id}"; its path controls are ${controls.join(", ")}.`);
|
|
4920
|
-
let value;
|
|
4921
|
-
if ("node" in options.path) {
|
|
4922
|
-
const entry = indexMotionNodes(this.scene.artwork.nodes).get(options.path.node);
|
|
4923
|
-
if (!entry) throw new Error(`There is no node "${options.path.node}"; find_animation_elements lists the artwork's nodes.`);
|
|
4924
|
-
if (entry.node.type !== "path") throw new Error(`Node "${options.path.node}" is a ${entry.node.type}, not a path; pass a path node (find_animation_elements shows each node's type).`);
|
|
4925
|
-
value = _chunkGF2RBSDMcjs.bezierPathToSvg.call(void 0, _chunkXRXFVRGYcjs.vectorPathWorldBezier.call(void 0, entry.node, entry.parentWorld, { effects: false }));
|
|
4926
|
-
place ??= "viewBox";
|
|
4927
|
-
} else {
|
|
4928
|
-
const provider = this.effects.require();
|
|
4929
|
-
if (!provider.pathFromText) throw new Error(`The effects provider "${provider.id}" cannot write words as a path; pass a path node instead.`);
|
|
4930
|
-
if (typeof options.path.text !== "string" || !options.path.text.trim()) throw new Error("text is empty; pass the words to write.");
|
|
4931
|
-
value = await provider.pathFromText(options.path.text, { ...options.path.font ? { font: options.path.font } : {}, ...options.path.align ? { align: options.path.align } : {} });
|
|
4932
|
-
}
|
|
4933
|
-
given = { ..._nullishCoalesce(given, () => ( {})), [control]: value };
|
|
4935
|
+
const resolved = await this.resolveVectorPath(this.scene.artwork, d, options.path, options.control);
|
|
4936
|
+
if (resolved.place) place ??= resolved.place;
|
|
4937
|
+
given = { ..._nullishCoalesce(given, () => ( {})), [resolved.control]: resolved.value };
|
|
4934
4938
|
}
|
|
4935
4939
|
const values = _chunkL2JTLW6Bcjs.resolveEffectValues.call(void 0, d, given);
|
|
4936
4940
|
const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
|
|
@@ -4940,6 +4944,33 @@ var AnimationEditorController = (_class2 = class {
|
|
|
4940
4944
|
return { scene: { ...this.scene, artwork: { ...this.scene.artwork, nodes: [...this.scene.artwork.nodes, group] }, shots: [...this.scene.shots, ...shots] }, label: `Add ${d.name}`, instance, notes };
|
|
4941
4945
|
});
|
|
4942
4946
|
}
|
|
4947
|
+
/**
|
|
4948
|
+
* Sets an applied vector effect's path from a path node in the artwork (landing on the node at
|
|
4949
|
+
* scale 1) or words written by the provider (keeping where the picture was placed). One undo step.
|
|
4950
|
+
*/
|
|
4951
|
+
setVectorEffectPath(instance, path, options = {}) {
|
|
4952
|
+
return this.effectEdit(async () => {
|
|
4953
|
+
const was = motionSceneEffects(this.scene).find((e) => e.instance === instance);
|
|
4954
|
+
if (!was) throw new Error(`There is no applied effect "${instance}"; list_applied_effects lists them.`);
|
|
4955
|
+
if (was.kind !== "vector") throw new Error(`"${instance}" is a motion effect, not a vector effect.`);
|
|
4956
|
+
const d = await this.describeFor(was.effect, ["vector"]);
|
|
4957
|
+
const { scene: bare } = withoutMotionEffect(this.scene, instance);
|
|
4958
|
+
const { control, value, place } = await this.resolveVectorPath(bare.artwork, d, path, options.control);
|
|
4959
|
+
const merged = { ...was.values, [control]: value };
|
|
4960
|
+
const provider = this.effects.require();
|
|
4961
|
+
const source = { instance, effect: d.id, provider: provider.id, name: d.name, values: merged };
|
|
4962
|
+
const motion = await provider.applyVectorEffect(d.id, motionArtworkSvg(bare.artwork), merged);
|
|
4963
|
+
const { group, shots, notes } = motionPartsFromVectorEffect(bare.artwork, motion, source, place);
|
|
4964
|
+
const old = this.scene.artwork.nodes.find((n2) => n2.id === instance);
|
|
4965
|
+
const index = this.scene.artwork.nodes.findIndex((n2) => n2.id === instance);
|
|
4966
|
+
const nodes = [...bare.artwork.nodes];
|
|
4967
|
+
nodes.splice(Math.max(0, index), 0, !place && _optionalChain([old, 'optionalAccess', _230 => _230.transform]) ? { ...group, transform: old.transform } : group);
|
|
4968
|
+
const at = this.scene.shots.findIndex((s) => was.shots.includes(s.id));
|
|
4969
|
+
const kept = bare.shots;
|
|
4970
|
+
const nextShots = [...kept.slice(0, Math.max(0, at)), ...shots, ...kept.slice(Math.max(0, at))];
|
|
4971
|
+
return { scene: { ...bare, artwork: { ...bare.artwork, nodes }, shots: nextShots }, label: `Set ${d.name} path`, instance, notes };
|
|
4972
|
+
});
|
|
4973
|
+
}
|
|
4943
4974
|
/**
|
|
4944
4975
|
* Makes an applied effect again with new `values` (merged over its own; `null` resets a
|
|
4945
4976
|
* control), in the same place. One undo step.
|
|
@@ -4966,7 +4997,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
4966
4997
|
const { group, shots: shots2, notes: notes2 } = motionPartsFromVectorEffect(bare.artwork, motion2, source);
|
|
4967
4998
|
const index = this.scene.artwork.nodes.findIndex((n2) => n2.id === instance);
|
|
4968
4999
|
const nodes = [...bare.artwork.nodes];
|
|
4969
|
-
nodes.splice(Math.max(0, index), 0, _optionalChain([old, 'optionalAccess',
|
|
5000
|
+
nodes.splice(Math.max(0, index), 0, _optionalChain([old, 'optionalAccess', _231 => _231.transform]) ? { ...group, transform: old.transform } : group);
|
|
4970
5001
|
const at = this.scene.shots.findIndex((s) => was.shots.includes(s.id));
|
|
4971
5002
|
const kept = bare.shots;
|
|
4972
5003
|
const nextShots = [...kept.slice(0, Math.max(0, at)), ...shots2, ...kept.slice(Math.max(0, at))];
|
|
@@ -4977,7 +5008,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
4977
5008
|
let shots = bare.shots;
|
|
4978
5009
|
if (place && shots.some((s) => s.id === place.shot)) shots = shots.map((s) => s.id === place.shot ? { ...s, run: [...s.run.slice(0, place.index), ...commands, ...s.run.slice(place.index)] } : s);
|
|
4979
5010
|
else {
|
|
4980
|
-
const at = this.scene.shots.findIndex((s) => s.id === _optionalChain([place, 'optionalAccess',
|
|
5011
|
+
const at = this.scene.shots.findIndex((s) => s.id === _optionalChain([place, 'optionalAccess', _232 => _232.shot]));
|
|
4981
5012
|
shots = [...shots.slice(0, Math.max(0, at)), { id: instance, label: d.name, run: commands }, ...shots.slice(Math.max(0, at))];
|
|
4982
5013
|
}
|
|
4983
5014
|
return { scene: { ...bare, shots }, label: `Change ${d.name}`, instance, notes };
|
|
@@ -5031,7 +5062,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5031
5062
|
const found = this.scene.shots.find((s) => s.id === shot);
|
|
5032
5063
|
if (!found) return this.refuse(`There is no shot "${shot}"; the shots are ${this.scene.shots.map((s) => `"${s.id}"`).join(", ") || "none yet"}.`);
|
|
5033
5064
|
const field = _chunkL2JTLW6Bcjs.cameraMoveField.call(void 0, role);
|
|
5034
|
-
if (_optionalChain([found, 'access',
|
|
5065
|
+
if (_optionalChain([found, 'access', _233 => _233.camera, 'optionalAccess', _234 => _234[field]]) === void 0) return this.refuse(`Shot "${shot}" has no camera "${field}" move to clear${_optionalChain([found, 'access', _235 => _235.camera, 'optionalAccess', _236 => _236[field === "in" ? "during" : "in"]]) !== void 0 ? `; it has a "${field === "in" ? "during" : "in"}" move (role ${role === "hold" ? "transition" : "hold"})` : ""}.`);
|
|
5035
5066
|
const rest = { ...found.camera };
|
|
5036
5067
|
delete rest[field];
|
|
5037
5068
|
const keep = motionCameraFramed(rest) || rest.in !== void 0 || rest.during !== void 0;
|
|
@@ -5041,7 +5072,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5041
5072
|
}
|
|
5042
5073
|
cameraMoveResult(shot, role, move) {
|
|
5043
5074
|
const timing = compileMotionScene(this.scene).shots.find((s) => s.id === shot);
|
|
5044
|
-
const camera = _nullishCoalesce(_optionalChain([this, 'access',
|
|
5075
|
+
const camera = _nullishCoalesce(_optionalChain([this, 'access', _237 => _237.scene, 'access', _238 => _238.shots, 'access', _239 => _239.find, 'call', _240 => _240((s) => s.id === shot), 'optionalAccess', _241 => _241.camera]), () => ( null));
|
|
5045
5076
|
const window = role === "transition" ? { start: timing.start, end: timing.commandsStart } : { start: timing.commandsEnd, end: timing.end };
|
|
5046
5077
|
const notes = [];
|
|
5047
5078
|
if (move && role === "transition" && timing.index === 0) notes.push('This is the first shot, which cuts to its framing, so its "in" move does not play; it plays from the second shot on.');
|
|
@@ -5112,7 +5143,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5112
5143
|
viewScene() {
|
|
5113
5144
|
const r = this.recording;
|
|
5114
5145
|
if (!r) return this.scene;
|
|
5115
|
-
if (_optionalChain([r, 'access',
|
|
5146
|
+
if (_optionalChain([r, 'access', _242 => _242.preview, 'optionalAccess', _243 => _243.count]) === r.samples.length) return r.preview.scene;
|
|
5116
5147
|
let scene = this.scene;
|
|
5117
5148
|
if (r.samples.length) {
|
|
5118
5149
|
try {
|
|
@@ -5261,7 +5292,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5261
5292
|
const r = this.apply({ op: "update_shot", shot, set: { transition: resolved } }, `Transition ${_nullishCoalesce(resolved.name, () => ( resolved.effect))}`, { merge: options.merge });
|
|
5262
5293
|
if (!r.ok) return r;
|
|
5263
5294
|
const camera = this.scene.shots.find((s) => s.id === shot).camera;
|
|
5264
|
-
return this.layerResult(shot, void 0, _optionalChain([camera, 'optionalAccess',
|
|
5295
|
+
return this.layerResult(shot, void 0, _optionalChain([camera, 'optionalAccess', _244 => _244.in]) === void 0 ? ["With no camera move in, the camera cuts to this shot's framing and the transition does the move."] : []);
|
|
5265
5296
|
}
|
|
5266
5297
|
/** Removes a shot's transition. One undo step. Works without a provider. */
|
|
5267
5298
|
clearShotTransition(shot) {
|
|
@@ -5375,13 +5406,13 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5375
5406
|
}
|
|
5376
5407
|
/** Records the drag's pose with the pointer at `point` (document units). */
|
|
5377
5408
|
updateRecordGesture(point) {
|
|
5378
|
-
const g = _optionalChain([this, 'access',
|
|
5409
|
+
const g = _optionalChain([this, 'access', _245 => _245.recording, 'optionalAccess', _246 => _246.gesture]);
|
|
5379
5410
|
if (g) this.recordGesture(g.pose, point);
|
|
5380
5411
|
}
|
|
5381
5412
|
/** Ends the stage drag (the take keeps recording). */
|
|
5382
5413
|
endRecordGesture() {
|
|
5383
5414
|
const r = this.recording;
|
|
5384
|
-
if (!_optionalChain([r, 'optionalAccess',
|
|
5415
|
+
if (!_optionalChain([r, 'optionalAccess', _247 => _247.gesture])) return;
|
|
5385
5416
|
r.gesture = null;
|
|
5386
5417
|
this.notify();
|
|
5387
5418
|
}
|
|
@@ -5395,7 +5426,7 @@ var AnimationEditorController = (_class2 = class {
|
|
|
5395
5426
|
this.recordSample(g.node, { scaleX: Math.max(0.01, pose.scaleX * f), scaleY: Math.max(0.01, pose.scaleY * f) });
|
|
5396
5427
|
} else {
|
|
5397
5428
|
const turn = (Math.atan2(point.y - c.y, point.x - c.x) - Math.atan2(g.from.y - c.y, g.from.x - c.x)) * (180 / Math.PI);
|
|
5398
|
-
const was = _nullishCoalesce(_optionalChain([this, 'access',
|
|
5429
|
+
const was = _nullishCoalesce(_optionalChain([this, 'access', _248 => _248.recording, 'access', _249 => _249.samples, 'access', _250 => _250.filter, 'call', _251 => _251((s) => s.node === g.node && s.rotation !== void 0), 'access', _252 => _252.at, 'call', _253 => _253(-1), 'optionalAccess', _254 => _254.rotation]), () => ( pose.rotation));
|
|
5399
5430
|
let next = pose.rotation + turn;
|
|
5400
5431
|
next += 360 * Math.round((was - next) / 360);
|
|
5401
5432
|
this.recordSample(g.node, { rotation: next });
|
|
@@ -5489,7 +5520,7 @@ function elementsOf(args) {
|
|
|
5489
5520
|
if (Array.isArray(args.ops)) {
|
|
5490
5521
|
for (const op of args.ops) {
|
|
5491
5522
|
fromShot(op);
|
|
5492
|
-
if (Array.isArray(_optionalChain([op, 'optionalAccess',
|
|
5523
|
+
if (Array.isArray(_optionalChain([op, 'optionalAccess', _255 => _255.shots]))) op.shots.forEach(fromShot);
|
|
5493
5524
|
}
|
|
5494
5525
|
}
|
|
5495
5526
|
return out.slice(0, 4);
|
|
@@ -5671,7 +5702,7 @@ var MOTION_COMMAND_SCHEMA = {
|
|
|
5671
5702
|
oneOf: MOTION_COMMAND_TYPES.map((type) => MOTION_COMMAND_TYPE_SCHEMAS[type])
|
|
5672
5703
|
};
|
|
5673
5704
|
var REF2 = (name, description) => ({ $ref: `#/$defs/${name}`, ...description ? { description } : {} });
|
|
5674
|
-
var firstSentence = (text) => _nullishCoalesce(_optionalChain([/^.*?[.;](?=\s|$)/, 'access',
|
|
5705
|
+
var firstSentence = (text) => _nullishCoalesce(_optionalChain([/^.*?[.;](?=\s|$)/, 'access', _256 => _256.exec, 'call', _257 => _257(text), 'optionalAccess', _258 => _258[0]]), () => ( text));
|
|
5675
5706
|
var COMMAND_TYPE_LINES = MOTION_COMMAND_TYPES.map((type) => `${type}: ${firstSentence(_nullishCoalesce(MOTION_COMMAND_TYPE_SCHEMAS[type].description, () => ( "")))}`);
|
|
5676
5707
|
var EASE_COMPACT = {
|
|
5677
5708
|
description: `Easing: a preset, or a curve { "type": "cubic-bezier", x1, y1, x2, y2 }, { "type": "spring", stiffness, damping, mass, velocity } (spring presets are Figma's; with no "duration" it lasts until it settles) or { "type": "elastic", amplitude, period, mode }. Default: ease-out for entrances, ease-in-out for moves.`,
|
|
@@ -6080,9 +6111,9 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
6080
6111
|
handler: ({ from = 0, to, limit = 200 }) => {
|
|
6081
6112
|
const s = scene();
|
|
6082
6113
|
const timeline = compileMotionScene(s);
|
|
6083
|
-
const words = _nullishCoalesce(_optionalChain([s, 'access',
|
|
6114
|
+
const words = _nullishCoalesce(_optionalChain([s, 'access', _259 => _259.narration, 'optionalAccess', _260 => _260.words]), () => ( []));
|
|
6084
6115
|
const end = _nullishCoalesce(to, () => ( Math.max(timeline.duration, words.length ? _nullishCoalesce(words[words.length - 1].end, () => ( words[words.length - 1].start)) : 0)));
|
|
6085
|
-
const shotAt = (ms2) => _optionalChain([timeline, 'access',
|
|
6116
|
+
const shotAt = (ms2) => _optionalChain([timeline, 'access', _261 => _261.shots, 'access', _262 => _262.find, 'call', _263 => _263((x) => ms2 >= x.start && ms2 < x.end), 'optionalAccess', _264 => _264.id]);
|
|
6086
6117
|
const beats = [];
|
|
6087
6118
|
if (s.beat && s.beat.bpm > 0) {
|
|
6088
6119
|
const first = Math.max(0, Math.ceil(motionBeatAt(s.beat, from).beat - 1e-9));
|
|
@@ -6183,7 +6214,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
6183
6214
|
handler: ({ svg }) => {
|
|
6184
6215
|
let artwork;
|
|
6185
6216
|
try {
|
|
6186
|
-
artwork =
|
|
6217
|
+
artwork = _chunkOKHKA43Lcjs.parseVectorSvg.call(void 0, svg);
|
|
6187
6218
|
} catch (error) {
|
|
6188
6219
|
throw new Error(`The SVG could not be read: ${error.message}. Nothing was changed.`);
|
|
6189
6220
|
}
|
|
@@ -6458,7 +6489,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
6458
6489
|
inputSchema: object({ shot: SHOT_ID, commands: { type: "array", items: REF2("command"), minItems: 1, description: "Commands to add." }, at: { type: "integer", minimum: 0, description: "Index in the run (default: the end)." } }, ["shot", "commands"]),
|
|
6459
6490
|
annotations: { title: "Add commands to a shot", ...WRITE },
|
|
6460
6491
|
handler: ({ shot, commands, at }) => {
|
|
6461
|
-
const before = _nullishCoalesce(_optionalChain([scene, 'call',
|
|
6492
|
+
const before = _nullishCoalesce(_optionalChain([scene, 'call', _265 => _265(), 'access', _266 => _266.shots, 'access', _267 => _267.find, 'call', _268 => _268((s) => s.id === shot), 'optionalAccess', _269 => _269.run, 'access', _270 => _270.length]), () => ( 0));
|
|
6462
6493
|
const first = _nullishCoalesce(at, () => ( before));
|
|
6463
6494
|
return apply({ op: "add_commands", shot, commands, at }, "Add commands", (s) => {
|
|
6464
6495
|
const shots = describeMotionShots(s);
|
|
@@ -6659,7 +6690,7 @@ var TIMING = /* @__PURE__ */ new Set(["duration", "delay", "stagger", "with", "e
|
|
|
6659
6690
|
var COLORS = /* @__PURE__ */ new Set(["fill", "stroke", "color"]);
|
|
6660
6691
|
var NODES = /* @__PURE__ */ new Set(["into", "path"]);
|
|
6661
6692
|
function branch(type) {
|
|
6662
|
-
return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access',
|
|
6693
|
+
return (_nullishCoalesce(MOTION_COMMAND_SCHEMA.oneOf, () => ( []))).find((b) => _optionalChain([b, 'access', _271 => _271.properties, 'optionalAccess', _272 => _272.type, 'optionalAccess', _273 => _273.const]) === type);
|
|
6663
6694
|
}
|
|
6664
6695
|
function unitOf(type, name) {
|
|
6665
6696
|
if (name === "duration" || name === "delay" || name === "stagger") return "ms";
|
|
@@ -6694,7 +6725,7 @@ function kindOf(name, schema) {
|
|
|
6694
6725
|
}
|
|
6695
6726
|
function motionCommandFields(type) {
|
|
6696
6727
|
const schema = branch(type);
|
|
6697
|
-
if (!_optionalChain([schema, 'optionalAccess',
|
|
6728
|
+
if (!_optionalChain([schema, 'optionalAccess', _274 => _274.properties])) return [];
|
|
6698
6729
|
const required = new Set(_nullishCoalesce(schema.required, () => ( [])));
|
|
6699
6730
|
const fields2 = Object.entries(schema.properties).filter(([name]) => name !== "type").map(([name, s]) => {
|
|
6700
6731
|
const kind = kindOf(name, s);
|
|
@@ -6751,7 +6782,7 @@ function defaultMotionCommand(type, targets, scene) {
|
|
|
6751
6782
|
if (type === "wait") return { type: "wait", duration: 500 };
|
|
6752
6783
|
if (!targets.length) return { error: "Pick a target first: click an element on the stage." };
|
|
6753
6784
|
const nodes = [...indexMotionNodes(scene.artwork.nodes).values()];
|
|
6754
|
-
const other = (pred) => _optionalChain([nodes, 'access',
|
|
6785
|
+
const other = (pred) => _optionalChain([nodes, 'access', _275 => _275.find, 'call', _276 => _276((e) => !targets.includes(e.node.id) && pred(e)), 'optionalAccess', _277 => _277.node, 'access', _278 => _278.id]);
|
|
6755
6786
|
const base = { targets: [...targets] };
|
|
6756
6787
|
switch (type) {
|
|
6757
6788
|
case "scale":
|
|
@@ -6782,8 +6813,8 @@ function defaultMotionCommand(type, targets, scene) {
|
|
|
6782
6813
|
}
|
|
6783
6814
|
case "effect": {
|
|
6784
6815
|
for (const id of targets) {
|
|
6785
|
-
const node = _optionalChain([nodes, 'access',
|
|
6786
|
-
for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess',
|
|
6816
|
+
const node = _optionalChain([nodes, 'access', _279 => _279.find, 'call', _280 => _280((e) => e.node.id === id), 'optionalAccess', _281 => _281.node]);
|
|
6817
|
+
for (const effect of _nullishCoalesce(_optionalChain([node, 'optionalAccess', _282 => _282.effects]), () => ( []))) {
|
|
6787
6818
|
const param = Object.entries(effect.params).find(([, v]) => typeof v === "number");
|
|
6788
6819
|
if (param) return { type, ...base, effect: effect.id, param: param[0], to: param[1] + 1 };
|
|
6789
6820
|
}
|
|
@@ -6808,11 +6839,11 @@ function motionCommandRows(scene, shotId) {
|
|
|
6808
6839
|
return scene.shots[index].run.map((command3, i) => {
|
|
6809
6840
|
const t = timeline.commands.find((c) => c.shotIndex === index && c.command === i);
|
|
6810
6841
|
const primitive = motionFlairPrimitive(command3);
|
|
6811
|
-
return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess',
|
|
6842
|
+
return { index: i, command: command3, summary: motionCommandSummary(command3), start: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _283 => _283.start]), () => ( 0)), end: _nullishCoalesce(_optionalChain([t, 'optionalAccess', _284 => _284.end]), () => ( 0)), ...primitive ? { flairPrimitive: primitive } : {} };
|
|
6812
6843
|
});
|
|
6813
6844
|
}
|
|
6814
6845
|
function duplicateMotionCommandEdit(scene, shot, command3) {
|
|
6815
|
-
const run = _nullishCoalesce(_optionalChain([scene, 'access',
|
|
6846
|
+
const run = _nullishCoalesce(_optionalChain([scene, 'access', _285 => _285.shots, 'access', _286 => _286.find, 'call', _287 => _287((s) => s.id === shot), 'optionalAccess', _288 => _288.run]), () => ( []));
|
|
6816
6847
|
return { op: "add_commands", shot, commands: run[command3] ? [structuredClone(run[command3])] : [], at: command3 + 1 };
|
|
6817
6848
|
}
|
|
6818
6849
|
var MOTION_EASE_CHOICES = [
|
|
@@ -6897,7 +6928,7 @@ function motionCueFromKey(key) {
|
|
|
6897
6928
|
function motionCueChoices(scene, limit = 256) {
|
|
6898
6929
|
const choices = [];
|
|
6899
6930
|
const s = (ms2) => `${(ms2 / 1e3).toFixed(2)} s`;
|
|
6900
|
-
const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access',
|
|
6931
|
+
const end = Math.max(compileMotionScene(scene).duration, ..._nullishCoalesce(_optionalChain([scene, 'access', _289 => _289.narration, 'optionalAccess', _290 => _290.words, 'access', _291 => _291.map, 'call', _292 => _292((w) => _nullishCoalesce(w.end, () => ( w.start)))]), () => ( [0]))) + 2e3;
|
|
6901
6932
|
if (scene.beat && scene.beat.bpm > 0) {
|
|
6902
6933
|
for (let beat = 0; choices.length < limit; beat++) {
|
|
6903
6934
|
const time = motionBeatTime(scene.beat, beat);
|
|
@@ -6907,7 +6938,7 @@ function motionCueChoices(scene, limit = 256) {
|
|
|
6907
6938
|
choices.push({ value: `beat:${beat}`, label: `Beat ${beat} (bar ${at.bar}.${at.beatInBar}) \xB7 ${s(time)}`, time });
|
|
6908
6939
|
}
|
|
6909
6940
|
}
|
|
6910
|
-
_optionalChain([scene, 'access',
|
|
6941
|
+
_optionalChain([scene, 'access', _293 => _293.narration, 'optionalAccess', _294 => _294.words, 'access', _295 => _295.forEach, 'call', _296 => _296((w, i) => {
|
|
6911
6942
|
if (choices.length < limit * 2) choices.push({ value: `word:${i}`, label: `Word ${i} \u201C${w.text}\u201D \xB7 ${s(w.start)}`, time: w.start });
|
|
6912
6943
|
})]);
|
|
6913
6944
|
return choices;
|
|
@@ -6916,7 +6947,7 @@ function motionShotCueTime(scene, cue) {
|
|
|
6916
6947
|
return cue ? motionCueTime(scene, cue) : void 0;
|
|
6917
6948
|
}
|
|
6918
6949
|
function formatMotionNarration(narration) {
|
|
6919
|
-
return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess',
|
|
6950
|
+
return (_nullishCoalesce(_optionalChain([narration, 'optionalAccess', _297 => _297.words]), () => ( []))).map((w) => `${w.start} ${w.text}`).join("\n");
|
|
6920
6951
|
}
|
|
6921
6952
|
function parseMotionNarration(text) {
|
|
6922
6953
|
const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
@@ -6959,7 +6990,7 @@ var ROLE = {
|
|
|
6959
6990
|
enum: ["transition", "hold"],
|
|
6960
6991
|
description: `transition: the move the camera gets into the shot with (its camera "in": a glide, whip pan, punch zoom, cut). hold: the move it makes while the shot holds (its camera "during": a Ken Burns drift, a crash zoom), played across the shot's hold.`
|
|
6961
6992
|
};
|
|
6962
|
-
var summary = (e) => ({ id: e.id, name: e.name, role: e.camera.role, durationMs: e.camera.durationMs, ...e.camera.cut !== void 0 ? { cut: e.camera.cut } : {}, ...e.description ? { description: e.description } : {}, ..._optionalChain([e, 'access',
|
|
6993
|
+
var summary = (e) => ({ id: e.id, name: e.name, role: e.camera.role, durationMs: e.camera.durationMs, ...e.camera.cut !== void 0 ? { cut: e.camera.cut } : {}, ...e.description ? { description: e.description } : {}, ..._optionalChain([e, 'access', _298 => _298.tags, 'optionalAccess', _299 => _299.length]) ? { tags: e.tags } : {} });
|
|
6963
6994
|
var done = (r) => {
|
|
6964
6995
|
if (!r.ok) throw new Error(r.error);
|
|
6965
6996
|
return { shot: r.shot, camera: r.camera, ...r.window ? { window: r.window } : {}, ...r.notes.length ? { notes: r.notes } : {} };
|
|
@@ -7239,7 +7270,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
|
|
|
7239
7270
|
{
|
|
7240
7271
|
name: "add_vector_effect",
|
|
7241
7272
|
title: "Add a vector effect",
|
|
7242
|
-
description: 'Adds a provider vector effect that brings its own picture (search_effects with kind vector: lower thirds, loaders, stickers): its SVG becomes an artwork group, fitted into box (default the whole artwork), and its motion becomes shots after the last one. For an effect that draws along a path (search_effects accepts ["path"]: a signature, a route), pass path: { node } to run it along a path node (its outline with every transform applied; the picture then lands on the node at scale 1 unless box is given) or { text } for words the provider writes. Use it instead of follow or draw-on when the effect itself should trace the path. The path is copied when added;
|
|
7273
|
+
description: 'Adds a provider vector effect that brings its own picture (search_effects with kind vector: lower thirds, loaders, stickers): its SVG becomes an artwork group, fitted into box (default the whole artwork), and its motion becomes shots after the last one. For an effect that draws along a path (search_effects accepts ["path"]: a signature, a route), pass path: { node } to run it along a path node (its outline with every transform applied; the picture then lands on the node at scale 1 unless box is given) or { text } for words the provider writes. Use it instead of follow or draw-on when the effect itself should trace the path. The path is copied when added; after reshaping the node, give it the path again with set_vector_effect_path. Change it with update_effect (target and effect: the returned instance) or remove it with remove_effect. One undo step. Returns the instance, the group id and any notes on what could not be carried over.',
|
|
7243
7274
|
inputSchema: {
|
|
7244
7275
|
type: "object",
|
|
7245
7276
|
properties: {
|
|
@@ -7283,6 +7314,42 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
|
|
|
7283
7314
|
if (!r.ok) throw new Error(r.error);
|
|
7284
7315
|
return { instance: r.effect.instance, group: r.effect.group, effect: info(r.effect), ...r.notes.length ? { notes: r.notes } : {} };
|
|
7285
7316
|
}
|
|
7317
|
+
},
|
|
7318
|
+
{
|
|
7319
|
+
name: "set_vector_effect_path",
|
|
7320
|
+
title: "Run a vector effect along a path",
|
|
7321
|
+
description: 'Gives a vector effect already added with add_vector_effect (instance: its id from add_vector_effect or list_applied_effects) a new path to draw along, in place: path: { node } runs it along a path node (its outline with every transform applied) and lands the picture on the node at scale 1; { text } writes words with the provider and keeps the picture where it was. Use it after reshaping the node the effect was run along, or to switch between a node and words. To clear the path, call update_effect with the path control set to "". Refuses a motion effect, an effect without a path control, an unknown or non-path node, and a provider that cannot write words, saying what to pass. One undo step. Returns the instance, the control set, its new path data and any notes.',
|
|
7322
|
+
inputSchema: {
|
|
7323
|
+
type: "object",
|
|
7324
|
+
properties: {
|
|
7325
|
+
instance: { type: "string", minLength: 1, description: "The applied vector effect id (add_vector_effect instance, or list_applied_effects)." },
|
|
7326
|
+
path: {
|
|
7327
|
+
type: "object",
|
|
7328
|
+
description: "The path the effect draws along: { node } or { text }.",
|
|
7329
|
+
properties: {
|
|
7330
|
+
node: { type: "string", minLength: 1, description: "A path node id (find_animation_elements)." },
|
|
7331
|
+
text: { type: "string", minLength: 1, description: "Words the provider writes as a single-stroke path." },
|
|
7332
|
+
font: { type: "string", minLength: 1, description: "With text: a single-stroke font the provider offers (default its first)." },
|
|
7333
|
+
align: { type: "string", enum: ["start", "middle", "end"], description: "With text: where the line sits (default start)." }
|
|
7334
|
+
},
|
|
7335
|
+
oneOf: [{ required: ["node"] }, { required: ["text"] }],
|
|
7336
|
+
additionalProperties: false
|
|
7337
|
+
},
|
|
7338
|
+
control: { type: "string", minLength: 1, description: "Which path control takes the path (default the effect's only one; describe_effect pathControls lists them)." }
|
|
7339
|
+
},
|
|
7340
|
+
required: ["instance", "path"],
|
|
7341
|
+
additionalProperties: false
|
|
7342
|
+
},
|
|
7343
|
+
annotations: { title: "Run a vector effect along a path", ...ctx.annotations.write, idempotentHint: true },
|
|
7344
|
+
handler: async (args) => {
|
|
7345
|
+
ctx.requireProvider();
|
|
7346
|
+
if (args.path.node !== void 0 && args.path.text !== void 0) throw new Error("Pass path as { node } or { text }, not both.");
|
|
7347
|
+
const path = args.path.node !== void 0 ? { node: args.path.node } : { text: args.path.text, font: args.path.font, align: args.path.align };
|
|
7348
|
+
const r = await controller.setVectorEffectPath(args.instance, path, { control: args.control });
|
|
7349
|
+
if (!r.ok) throw new Error(r.error);
|
|
7350
|
+
const control = await _asyncNullishCoalesce(args.control, async () => ( _chunkL2JTLW6Bcjs.pathControlsOf.call(void 0, await controller.effectsProvider.describe(r.effect.effect))[0]));
|
|
7351
|
+
return { instance: r.effect.instance, group: r.effect.group, control, value: r.effect.values[control], effect: info(r.effect), ...r.notes.length ? { notes: r.notes } : {} };
|
|
7352
|
+
}
|
|
7286
7353
|
}
|
|
7287
7354
|
]
|
|
7288
7355
|
}), options.playbackSurface);
|