pixi-effects 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -1
- package/README.md +11 -6
- package/ai/SKILL.md +7 -4
- package/ai/reference/cheatsheet.md +18 -5
- package/ai/reference/pitfalls.md +16 -11
- package/ai/reference/recipes.md +153 -1
- package/ai/template.html +6 -3
- package/ai/tools/check.mjs +385 -0
- package/dist/{Base-DhY9oMxr.d.ts → Base-4vNLl4tH.d.cts} +6 -1
- package/dist/{Base-5R7C5pHR.d.cts → Base-CD4AoT5-.d.ts} +6 -1
- package/dist/Composition-7SO5WYHU.js +4 -0
- package/dist/{Composition-RGTRZ2JX.js.map → Composition-7SO5WYHU.js.map} +1 -1
- package/dist/Composition-Y5VZSDDP.cjs +13 -0
- package/dist/{Composition-D7RCAGEA.cjs.map → Composition-Y5VZSDDP.cjs.map} +1 -1
- package/dist/Controller.cjs +47 -15
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +5 -2
- package/dist/Controller.d.ts +5 -2
- package/dist/Controller.js +47 -15
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-DRZtIGU7.d.ts → Movie-CADDBfpl.d.cts} +58 -2
- package/dist/{Movie-CghFXprP.d.cts → Movie-Ch2SUI1h.d.ts} +58 -2
- package/dist/{chunk-QGBOC5YL.cjs → chunk-4AGJF5RK.cjs} +33 -21
- package/dist/chunk-4AGJF5RK.cjs.map +1 -0
- package/dist/{chunk-ZQX7WIYL.js → chunk-7IJHJXDI.js} +380 -64
- package/dist/chunk-7IJHJXDI.js.map +1 -0
- package/dist/{chunk-A574IA4F.js → chunk-B2FTJLNB.js} +18 -6
- package/dist/chunk-B2FTJLNB.js.map +1 -0
- package/dist/chunk-DKGG7WD4.js +61 -0
- package/dist/chunk-DKGG7WD4.js.map +1 -0
- package/dist/{chunk-6BQ6IEW2.cjs → chunk-KQM2ZZMK.cjs} +380 -63
- package/dist/chunk-KQM2ZZMK.cjs.map +1 -0
- package/dist/chunk-UQBGW5DO.cjs +64 -0
- package/dist/chunk-UQBGW5DO.cjs.map +1 -0
- package/dist/index.cjs +333 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -5
- package/dist/index.d.ts +54 -5
- package/dist/index.js +317 -75
- package/dist/index.js.map +1 -1
- package/dist/sfx-MZJZXYY3.cjs +446 -0
- package/dist/sfx-MZJZXYY3.cjs.map +1 -0
- package/dist/sfx-S37DDC66.js +434 -0
- package/dist/sfx-S37DDC66.js.map +1 -0
- package/dist/three.cjs +5 -5
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +1 -1
- package/dist/{types-CRE9WKd4.d.ts → types-DrW9QeKU.d.cts} +118 -12
- package/dist/{types-CRE9WKd4.d.cts → types-DrW9QeKU.d.ts} +118 -12
- package/docs/api.md +37 -0
- package/docs/dsl.md +70 -10
- package/llms-full.txt +300 -30
- package/llms.txt +1 -1
- package/package.json +2 -1
- package/dist/Composition-D7RCAGEA.cjs +0 -13
- package/dist/Composition-RGTRZ2JX.js +0 -4
- package/dist/chunk-6BQ6IEW2.cjs.map +0 -1
- package/dist/chunk-A574IA4F.js.map +0 -1
- package/dist/chunk-QGBOC5YL.cjs.map +0 -1
- package/dist/chunk-ZQX7WIYL.js.map +0 -1
|
@@ -741,6 +741,11 @@ var Sequence = class {
|
|
|
741
741
|
* (not a normal child) by PIXI when `target.mask = maskSequence.target`.
|
|
742
742
|
*/
|
|
743
743
|
maskSequence = null;
|
|
744
|
+
/**
|
|
745
|
+
* Set by the parent composition on a sprite-based (image / video) mask. PIXI hides such a mask with
|
|
746
|
+
* `renderable = false`; the lifespan toggles must not switch it back on, or the mask is drawn as a picture.
|
|
747
|
+
*/
|
|
748
|
+
keepHidden = false;
|
|
744
749
|
/**
|
|
745
750
|
* Absolute start time on the global timeline (offset + at), recorded by
|
|
746
751
|
* bindTimeline. Movie._awaitVideoFrames uses it to determine the correct
|
|
@@ -785,6 +790,7 @@ var Sequence = class {
|
|
|
785
790
|
applyKeyframes(timeline, this.target, this.spec.keyframes, this.duration, scope, [], startTime, routers);
|
|
786
791
|
const endTime = startTime + this.duration;
|
|
787
792
|
this.absoluteStart = startTime;
|
|
793
|
+
if (this.keepHidden) return;
|
|
788
794
|
this.target.renderable = startTime <= 0;
|
|
789
795
|
timeline.set(this.target, { renderable: true }, startTime);
|
|
790
796
|
timeline.set(this.target, { renderable: false }, endTime);
|
|
@@ -837,6 +843,7 @@ function lintTiming(spec, parentDuration, warn = defaultWarn) {
|
|
|
837
843
|
if (at >= parentDuration) {
|
|
838
844
|
warn(`pixi-effects: ${who} starts at ${at}s, after its composition ends (${parentDuration}s), so it is never visible`);
|
|
839
845
|
}
|
|
846
|
+
if (spec.type === "audio" && spec.sfx !== void 0 && spec.duration === void 0) return;
|
|
840
847
|
const duration = spec.duration ?? parentDuration;
|
|
841
848
|
(spec.keyframes ?? []).forEach((kf, i) => {
|
|
842
849
|
const kat = kf.at ?? 0;
|
|
@@ -854,7 +861,12 @@ function summarizeWarnings(messages, shown = 3) {
|
|
|
854
861
|
}
|
|
855
862
|
function lintText(spec, warn = defaultWarn) {
|
|
856
863
|
if (spec.type !== "text") return;
|
|
857
|
-
|
|
864
|
+
const strings = [spec.text ?? "", ...(spec.keyframes ?? []).map((kf) => String(kf.set?.text ?? ""))];
|
|
865
|
+
const hasPlaceholder = strings.some((t) => t.includes("{value}"));
|
|
866
|
+
if (hasPlaceholder && !collectPropKeys(spec).has("value")) {
|
|
867
|
+
warn(`pixi-effects: ${describeLayer(spec)}: the text has a {value} placeholder but nothing sets or animates \`value\`, so it prints 0. Set initial: { value: \u2026 } or animate it; {value} is reserved for counters (there is no way to print a literal "{value}").`);
|
|
868
|
+
}
|
|
869
|
+
if (collectPropKeys(spec).has("value") && !hasPlaceholder) {
|
|
858
870
|
warn(`pixi-effects: ${describeLayer(spec)}: \`value\` is set or animated but the text has no {value} placeholder, so nothing shows it. Use text: '{value}' (or e.g. '{value} users').`);
|
|
859
871
|
}
|
|
860
872
|
}
|
|
@@ -1048,6 +1060,8 @@ function revertibleSet(timeline, at, read, write, value) {
|
|
|
1048
1060
|
}
|
|
1049
1061
|
|
|
1050
1062
|
// src/expr/colorInterp.ts
|
|
1063
|
+
var CHROMA_FLOOR = 0.03;
|
|
1064
|
+
var CHROMA_FULL = 0.08;
|
|
1051
1065
|
function buildColorInterp(from, to, space) {
|
|
1052
1066
|
const fromRGBA = parseToRGBA(from);
|
|
1053
1067
|
const toRGBA = parseToRGBA(to);
|
|
@@ -1064,8 +1078,9 @@ function buildColorInterp(from, to, space) {
|
|
|
1064
1078
|
}
|
|
1065
1079
|
const fromLCH = oklabToOklch(fromOk);
|
|
1066
1080
|
const toLCH = oklabToOklch(toOk);
|
|
1067
|
-
|
|
1068
|
-
|
|
1081
|
+
const fromHue = fromLCH.h, toHue = toLCH.h;
|
|
1082
|
+
fromLCH.h = borrowHue(fromHue, fromLCH.C, toHue);
|
|
1083
|
+
toLCH.h = borrowHue(toHue, toLCH.C, fromHue);
|
|
1069
1084
|
const hueDelta = shortestHueDelta(fromLCH.h, toLCH.h);
|
|
1070
1085
|
return (t) => {
|
|
1071
1086
|
const L = lerp(fromLCH.L, toLCH.L, t);
|
|
@@ -1076,6 +1091,11 @@ function buildColorInterp(from, to, space) {
|
|
|
1076
1091
|
return rgbaString(oklabToRgb(ab), alpha);
|
|
1077
1092
|
};
|
|
1078
1093
|
}
|
|
1094
|
+
function borrowHue(own, chroma, other) {
|
|
1095
|
+
const u = Math.min(1, Math.max(0, (chroma - CHROMA_FLOOR) / (CHROMA_FULL - CHROMA_FLOOR)));
|
|
1096
|
+
const keep = u * u * (3 - 2 * u);
|
|
1097
|
+
return own + shortestHueDelta(own, other) * (1 - keep);
|
|
1098
|
+
}
|
|
1079
1099
|
function parseToRGBA(input) {
|
|
1080
1100
|
if (typeof input === "number") {
|
|
1081
1101
|
return { r: (input >> 16 & 255) / 255, g: (input >> 8 & 255) / 255, b: (input & 255) / 255, a: 1 };
|
|
@@ -1260,6 +1280,7 @@ var ImageSequence = class extends Sequence {
|
|
|
1260
1280
|
}
|
|
1261
1281
|
this.absoluteStart = startTime;
|
|
1262
1282
|
const endTime = startTime + this.duration;
|
|
1283
|
+
if (this.keepHidden) return;
|
|
1263
1284
|
this.target.renderable = startTime <= 0;
|
|
1264
1285
|
timeline.set(this.target, { renderable: true }, startTime);
|
|
1265
1286
|
timeline.set(this.target, { renderable: false }, endTime);
|
|
@@ -1304,19 +1325,31 @@ var STYLE_OPAQUE_KEYS = [
|
|
|
1304
1325
|
];
|
|
1305
1326
|
function formatValue(v, f) {
|
|
1306
1327
|
const fixed = v.toFixed(Math.max(0, Math.floor(f?.decimals ?? 0)));
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1328
|
+
const pad = Math.max(0, Math.floor(f?.pad ?? 0));
|
|
1329
|
+
if (!f?.grouping && !pad) return fixed;
|
|
1330
|
+
const [signed, frac] = fixed.split(".");
|
|
1331
|
+
const sign = signed.startsWith("-") ? "-" : "";
|
|
1332
|
+
let int = sign ? signed.slice(1) : signed;
|
|
1333
|
+
if (pad) int = int.padStart(pad, "0");
|
|
1334
|
+
if (f?.grouping) int = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
1335
|
+
return sign + int + (frac !== void 0 ? "." + frac : "");
|
|
1310
1336
|
}
|
|
1311
1337
|
var TextSequence = class extends Sequence {
|
|
1312
|
-
/**
|
|
1313
|
-
|
|
1338
|
+
/** `value`: the number for the `{value}` placeholder; `visibleChars`: how many characters show (typewriter). Both tweened by keyframes. */
|
|
1339
|
+
_counters = { value: 0, visibleChars: 0 };
|
|
1340
|
+
/** The string now on the layer (before `{value}` / `visibleChars`): `text`, or the last `set: { text }`. */
|
|
1341
|
+
_template = "";
|
|
1342
|
+
/** `visibleChars` is in play (initial or animated): otherwise the whole text shows. */
|
|
1343
|
+
_typed = false;
|
|
1314
1344
|
_lastText = "";
|
|
1315
|
-
/**
|
|
1345
|
+
/** A typewriter that has typed nothing yet: the layer is empty on purpose (inspect must not call that "no size"). */
|
|
1346
|
+
get showsNothingYet() {
|
|
1347
|
+
return this._typed && this._lastText === "" && this._template !== "";
|
|
1348
|
+
}
|
|
1349
|
+
/** Rewrite the displayed string from the template, the current `value` and `visibleChars`. */
|
|
1316
1350
|
_refreshText() {
|
|
1317
|
-
|
|
1318
|
-
if (
|
|
1319
|
-
const next = template.split("{value}").join(formatValue(this._value.value, this.spec.format));
|
|
1351
|
+
let next = this._template.includes("{value}") ? this._template.split("{value}").join(formatValue(this._counters.value, this.spec.format)) : this._template;
|
|
1352
|
+
if (this._typed) next = Array.from(next).slice(0, Math.max(0, Math.floor(this._counters.visibleChars))).join("");
|
|
1320
1353
|
if (next === this._lastText) return;
|
|
1321
1354
|
this._lastText = next;
|
|
1322
1355
|
this.target.text = next;
|
|
@@ -1328,8 +1361,10 @@ var TextSequence = class extends Sequence {
|
|
|
1328
1361
|
fill: "#ffffff",
|
|
1329
1362
|
align: "center"
|
|
1330
1363
|
};
|
|
1364
|
+
const initialProps = this.spec.initial ?? {};
|
|
1365
|
+
this._template = String(initialProps.text ?? this.spec.text ?? "");
|
|
1331
1366
|
const text = new pixi_js.Text({
|
|
1332
|
-
text: this.
|
|
1367
|
+
text: this._template,
|
|
1333
1368
|
style: baseStyle,
|
|
1334
1369
|
label: this.spec.name
|
|
1335
1370
|
});
|
|
@@ -1341,10 +1376,10 @@ var TextSequence = class extends Sequence {
|
|
|
1341
1376
|
this.duration = this.parent?.duration ?? this.root.duration;
|
|
1342
1377
|
}
|
|
1343
1378
|
if (this.spec.style) {
|
|
1344
|
-
const
|
|
1379
|
+
const scope2 = this.scope();
|
|
1345
1380
|
const resolved = normalizeProps(
|
|
1346
1381
|
this.spec.style,
|
|
1347
|
-
|
|
1382
|
+
scope2,
|
|
1348
1383
|
{ skipKeys: STYLE_OPAQUE_KEYS }
|
|
1349
1384
|
);
|
|
1350
1385
|
for (const k of Object.keys(resolved)) {
|
|
@@ -1353,22 +1388,36 @@ var TextSequence = class extends Sequence {
|
|
|
1353
1388
|
this.intrinsicWidth = text.width;
|
|
1354
1389
|
this.intrinsicHeight = text.height;
|
|
1355
1390
|
}
|
|
1356
|
-
const
|
|
1357
|
-
if (
|
|
1391
|
+
const scope = this.scope();
|
|
1392
|
+
if (initialProps.value !== void 0) this._counters.value = resolveNumber(initialProps.value, scope);
|
|
1393
|
+
this._typed = initialProps.visibleChars !== void 0 || animates(this.spec.keyframes, "visibleChars");
|
|
1394
|
+
if (initialProps.visibleChars !== void 0) this._counters.visibleChars = resolveNumber(initialProps.visibleChars, scope);
|
|
1395
|
+
const typed = this._typed;
|
|
1396
|
+
this._typed = false;
|
|
1358
1397
|
this._refreshText();
|
|
1359
1398
|
if (this._lastText !== "") {
|
|
1360
1399
|
this.intrinsicWidth = text.width;
|
|
1361
1400
|
this.intrinsicHeight = text.height;
|
|
1362
1401
|
}
|
|
1402
|
+
this._typed = typed;
|
|
1403
|
+
this._refreshText();
|
|
1363
1404
|
this.buildFilters();
|
|
1364
1405
|
}
|
|
1365
1406
|
bindTimeline(timeline, offset = 0) {
|
|
1366
1407
|
if (!this.target) return;
|
|
1367
1408
|
const colorSpace = this.spec.colorSpace ?? "rgb";
|
|
1368
|
-
const stripped = stripKeys2(this.spec, ["fill", "value"]);
|
|
1409
|
+
const stripped = stripKeys2(this.spec, ["fill", "value", "text", "visibleChars"]);
|
|
1369
1410
|
runSuperWithStrippedSpec(this, stripped, timeline, offset);
|
|
1370
|
-
|
|
1371
|
-
|
|
1411
|
+
const keyframes = this.spec.keyframes ?? [];
|
|
1412
|
+
const origin = offset + this.at;
|
|
1413
|
+
bindFillKeyframes(timeline, this.target, keyframes, this.duration, origin, colorSpace);
|
|
1414
|
+
const refresh = () => this._refreshText();
|
|
1415
|
+
bindCounterKeyframes(timeline, this._counters, "value", refresh, keyframes, this.duration, origin, this.scope());
|
|
1416
|
+
bindCounterKeyframes(timeline, this._counters, "visibleChars", refresh, keyframes, this.duration, origin, this.scope());
|
|
1417
|
+
bindTextKeyframes(timeline, keyframes, this.duration, origin, () => this._template, (t) => {
|
|
1418
|
+
this._template = t;
|
|
1419
|
+
refresh();
|
|
1420
|
+
}, describeLayer(this.spec));
|
|
1372
1421
|
}
|
|
1373
1422
|
};
|
|
1374
1423
|
function runSuperWithStrippedSpec(inst, strippedSpec, timeline, offset) {
|
|
@@ -1404,11 +1453,11 @@ function resolveNumber(v, scope) {
|
|
|
1404
1453
|
const out = normalizeProps({ v }, scope).v;
|
|
1405
1454
|
return typeof out === "number" ? out : Number(out) || 0;
|
|
1406
1455
|
}
|
|
1407
|
-
function
|
|
1456
|
+
function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDuration, origin, scope) {
|
|
1408
1457
|
for (const kf of keyframes) {
|
|
1409
|
-
const setV = kf.set?.
|
|
1410
|
-
const fromV = kf.from?.
|
|
1411
|
-
const toV = kf.to?.
|
|
1458
|
+
const setV = kf.set?.[key];
|
|
1459
|
+
const fromV = kf.from?.[key];
|
|
1460
|
+
const toV = kf.to?.[key];
|
|
1412
1461
|
if (setV === void 0 && fromV === void 0 && toV === void 0) continue;
|
|
1413
1462
|
const at = origin + resolveAt(kf.at, parentDuration);
|
|
1414
1463
|
const duration = kf.duration ?? 0;
|
|
@@ -1416,25 +1465,40 @@ function bindValueKeyframes(timeline, state, refresh, keyframes, parentDuration,
|
|
|
1416
1465
|
const loop = loopVars(kf);
|
|
1417
1466
|
if (setV !== void 0) {
|
|
1418
1467
|
const v = resolveNumber(setV, scope);
|
|
1419
|
-
revertibleSet(timeline, at, () => state
|
|
1420
|
-
state
|
|
1468
|
+
revertibleSet(timeline, at, () => state[key], (n) => {
|
|
1469
|
+
state[key] = n;
|
|
1421
1470
|
refresh();
|
|
1422
1471
|
}, v);
|
|
1423
1472
|
}
|
|
1424
1473
|
if (toV !== void 0 && fromV !== void 0) {
|
|
1425
1474
|
timeline.fromTo(
|
|
1426
1475
|
state,
|
|
1427
|
-
{
|
|
1428
|
-
{
|
|
1476
|
+
{ [key]: resolveNumber(fromV, scope) },
|
|
1477
|
+
{ [key]: resolveNumber(toV, scope), duration, ease, ...loop, onUpdate: refresh },
|
|
1429
1478
|
at
|
|
1430
1479
|
);
|
|
1431
1480
|
} else if (toV !== void 0) {
|
|
1432
|
-
timeline.to(state, {
|
|
1481
|
+
timeline.to(state, { [key]: resolveNumber(toV, scope), duration, ease, ...loop, onUpdate: refresh }, at);
|
|
1433
1482
|
} else if (fromV !== void 0) {
|
|
1434
|
-
timeline.from(state, {
|
|
1483
|
+
timeline.from(state, { [key]: resolveNumber(fromV, scope), duration, ease, ...loop, onUpdate: refresh }, at);
|
|
1435
1484
|
}
|
|
1436
1485
|
}
|
|
1437
1486
|
}
|
|
1487
|
+
function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read, write, who) {
|
|
1488
|
+
for (const kf of keyframes) {
|
|
1489
|
+
for (const [what, props] of [["to", kf.to], ["from", kf.from]]) {
|
|
1490
|
+
if (props && props.text !== void 0) {
|
|
1491
|
+
console.warn(`pixi-effects: ${who}: a keyframe's ${what}: { text } cannot tween a string: use set: { text: '\u2026' } at the time it should change`);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
const t = kf.set?.text;
|
|
1495
|
+
if (t === void 0) continue;
|
|
1496
|
+
revertibleSet(timeline, origin + resolveAt(kf.at, parentDuration), read, write, String(t));
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
function animates(keyframes, key) {
|
|
1500
|
+
return (keyframes ?? []).some((kf) => [kf.set, kf.to, kf.from].some((p) => p && p[key] !== void 0));
|
|
1501
|
+
}
|
|
1438
1502
|
function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, colorSpace) {
|
|
1439
1503
|
const state = { fill: text.style.fill };
|
|
1440
1504
|
const writeFill = () => {
|
|
@@ -1478,28 +1542,64 @@ function pickFill(props) {
|
|
|
1478
1542
|
}
|
|
1479
1543
|
var AudioSequence = class extends Sequence {
|
|
1480
1544
|
_audioBuffer = null;
|
|
1545
|
+
_synth = null;
|
|
1546
|
+
_source = "";
|
|
1481
1547
|
async build() {
|
|
1482
|
-
|
|
1548
|
+
this.target = null;
|
|
1549
|
+
if (this.spec.sfx !== void 0) return this._buildSfx(this.spec);
|
|
1550
|
+
const spec = this.spec;
|
|
1551
|
+
this._source = `asset "${spec.asset}"`;
|
|
1552
|
+
const data = await pixi_js.Assets.get(spec.asset);
|
|
1483
1553
|
this._audioBuffer = data.audioBuffer;
|
|
1484
1554
|
if (this.duration === void 0) {
|
|
1485
1555
|
const rest = Math.max(0, (this.parent?.duration ?? this.root.duration) - this.at);
|
|
1486
|
-
this.duration =
|
|
1556
|
+
this.duration = spec.duration ?? (spec.loop ? rest : data.duration) ?? this.root.duration;
|
|
1487
1557
|
}
|
|
1488
|
-
if (!
|
|
1558
|
+
if (!spec.loop && data.duration !== void 0 && this.duration > data.duration + 0.05) {
|
|
1489
1559
|
console.warn(
|
|
1490
|
-
`pixi-effects: ${describeLayer(
|
|
1560
|
+
`pixi-effects: ${describeLayer(spec)}: audio asset "${spec.asset}" is ${data.duration.toFixed(1)}s but the layer lasts ${this.duration.toFixed(1)}s, so it goes silent after ${data.duration.toFixed(1)}s. Add loop: true, or shorten the layer's duration.`
|
|
1491
1561
|
);
|
|
1492
1562
|
}
|
|
1493
|
-
|
|
1563
|
+
}
|
|
1564
|
+
async _buildSfx(spec) {
|
|
1565
|
+
const who = describeLayer(spec);
|
|
1566
|
+
const raw = spec;
|
|
1567
|
+
if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and sfx \u2014 the sfx plays; remove one`);
|
|
1568
|
+
if (raw.loop) console.warn(`pixi-effects: ${who}: loop has no effect on an sfx \u2014 to repeat it, add one audio layer per hit (a JS loop)`);
|
|
1569
|
+
const { resolveSfx, renderSfx, sfxKey } = await import('./sfx-MZJZXYY3.cjs');
|
|
1570
|
+
const sfx = resolveSfx(spec.sfx, spec.duration, who);
|
|
1571
|
+
if (!sfx) return;
|
|
1572
|
+
this.duration = sfx.length;
|
|
1573
|
+
this._source = `sfx "${sfx.preset ?? "custom"}"`;
|
|
1574
|
+
this._synth = { key: sfxKey(sfx), render: (sr) => renderSfx(sfx, sr) };
|
|
1575
|
+
(spec.keyframes ?? []).forEach((kf, i) => {
|
|
1576
|
+
if ((kf.at ?? 0) >= sfx.length) {
|
|
1577
|
+
console.warn(`pixi-effects: ${who}: keyframes[${i}] starts at ${kf.at}s, after the sound ends (${sfx.length}s), so it never plays`);
|
|
1578
|
+
} else if ((kf.at ?? 0) < 0 && sfx.length + (kf.at ?? 0) < 0) {
|
|
1579
|
+
console.warn(`pixi-effects: ${who}: keyframes[${i}] starts ${-kf.at}s before the END of a ${sfx.length}s sound, which is before the sound begins (a negative \`at\` counts back from the end of the layer). Use a shorter \`at\`, or stretch the sound with \`duration\`.`);
|
|
1580
|
+
}
|
|
1581
|
+
});
|
|
1494
1582
|
}
|
|
1495
1583
|
bindTimeline(_timeline) {
|
|
1496
1584
|
}
|
|
1497
1585
|
collectAudio(out, baseTime) {
|
|
1498
|
-
if (!this._audioBuffer) return;
|
|
1499
|
-
const initialVolume = this.spec.volume ?? 1;
|
|
1500
|
-
const volumeKeyframes = [];
|
|
1501
|
-
const dur = this.duration;
|
|
1586
|
+
if (!this._audioBuffer && !this._synth) return;
|
|
1587
|
+
const initialVolume = this.spec.volume ?? this.spec.initial?.volume ?? 1;
|
|
1502
1588
|
const t0 = baseTime + this.at;
|
|
1589
|
+
const dur = this.duration;
|
|
1590
|
+
out.push({
|
|
1591
|
+
...this._audioBuffer ? { buffer: this._audioBuffer } : { synth: this._synth },
|
|
1592
|
+
layer: describeLayer(this.spec),
|
|
1593
|
+
source: this._source,
|
|
1594
|
+
loop: !this._synth && !!this.spec.loop,
|
|
1595
|
+
start: t0,
|
|
1596
|
+
end: t0 + dur,
|
|
1597
|
+
initialVolume,
|
|
1598
|
+
volumeKeyframes: this._volumePoints(t0, dur, initialVolume)
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
_volumePoints(t0, dur, initialVolume) {
|
|
1602
|
+
const volumeKeyframes = [];
|
|
1503
1603
|
const keyframes = (this.spec.keyframes ?? []).map((raw) => normalizeKeyframe(raw, dur)).filter((kf) => [kf.set, kf.to, kf.from].some((p) => p && "volume" in p)).sort((x, y) => x.at - y.at);
|
|
1504
1604
|
let current = initialVolume;
|
|
1505
1605
|
const point = (time, value) => {
|
|
@@ -1527,17 +1627,11 @@ var AudioSequence = class extends Sequence {
|
|
|
1527
1627
|
point(end, current);
|
|
1528
1628
|
}
|
|
1529
1629
|
}
|
|
1530
|
-
|
|
1531
|
-
buffer: this._audioBuffer,
|
|
1532
|
-
loop: !!this.spec.loop,
|
|
1533
|
-
start: baseTime + this.at,
|
|
1534
|
-
end: baseTime + this.at + dur,
|
|
1535
|
-
initialVolume,
|
|
1536
|
-
volumeKeyframes
|
|
1537
|
-
});
|
|
1630
|
+
return volumeKeyframes;
|
|
1538
1631
|
}
|
|
1539
1632
|
destroy() {
|
|
1540
1633
|
this._audioBuffer = null;
|
|
1634
|
+
this._synth = null;
|
|
1541
1635
|
}
|
|
1542
1636
|
};
|
|
1543
1637
|
|
|
@@ -1686,6 +1780,8 @@ var VideoSequence = class extends Sequence {
|
|
|
1686
1780
|
const initialVolume = this.spec.volume ?? 1;
|
|
1687
1781
|
out.push({
|
|
1688
1782
|
buffer: this._audioBuffer,
|
|
1783
|
+
layer: describeLayer(this.spec),
|
|
1784
|
+
source: `video "${this.spec.asset}"`,
|
|
1689
1785
|
loop: !!this.spec.loop,
|
|
1690
1786
|
start: baseTime + this.at,
|
|
1691
1787
|
end: baseTime + this.at + this.duration,
|
|
@@ -1766,19 +1862,107 @@ function makeGradientFill(g) {
|
|
|
1766
1862
|
}
|
|
1767
1863
|
return new pixi_js.FillGradient(gradientOptions(g));
|
|
1768
1864
|
}
|
|
1865
|
+
var CURVE_STEPS = 24;
|
|
1866
|
+
var ELLIPSE_STEPS = 128;
|
|
1867
|
+
function flattenSvgPath(d) {
|
|
1868
|
+
const prims = new pixi_js.GraphicsPath(d).shapePath.shapePrimitives;
|
|
1869
|
+
const out = [];
|
|
1870
|
+
for (const { shape } of prims) {
|
|
1871
|
+
const poly = shape;
|
|
1872
|
+
if (poly.points && poly.points.length >= 4) out.push({ pts: poly.points.slice(), closed: poly.closePath === true });
|
|
1873
|
+
}
|
|
1874
|
+
return out;
|
|
1875
|
+
}
|
|
1876
|
+
function rectOutline(x, y, w, h, radius) {
|
|
1877
|
+
const r = Math.max(0, Math.min(radius, Math.abs(w) / 2, Math.abs(h) / 2));
|
|
1878
|
+
if (r === 0) return { pts: [x, y, x + w, y, x + w, y + h, x, y + h], closed: true };
|
|
1879
|
+
const pts = [];
|
|
1880
|
+
const corner = (cx, cy, from) => {
|
|
1881
|
+
for (let i = 0; i <= CURVE_STEPS; i++) {
|
|
1882
|
+
const a = from + i / CURVE_STEPS * (Math.PI / 2);
|
|
1883
|
+
pts.push(cx + r * Math.cos(a), cy + r * Math.sin(a));
|
|
1884
|
+
}
|
|
1885
|
+
};
|
|
1886
|
+
corner(x + w - r, y + r, -Math.PI / 2);
|
|
1887
|
+
corner(x + w - r, y + h - r, 0);
|
|
1888
|
+
corner(x + r, y + h - r, Math.PI / 2);
|
|
1889
|
+
corner(x + r, y + r, Math.PI);
|
|
1890
|
+
const startAt = pts.length - 2;
|
|
1891
|
+
const rotated = pts.slice(startAt).concat(pts.slice(0, startAt));
|
|
1892
|
+
return { pts: rotated, closed: true };
|
|
1893
|
+
}
|
|
1894
|
+
function ellipseOutline(cx, cy, rx, ry) {
|
|
1895
|
+
const pts = [];
|
|
1896
|
+
for (let i = 0; i < ELLIPSE_STEPS; i++) {
|
|
1897
|
+
const a = -Math.PI / 2 + i / ELLIPSE_STEPS * Math.PI * 2;
|
|
1898
|
+
pts.push(cx + rx * Math.cos(a), cy + ry * Math.sin(a));
|
|
1899
|
+
}
|
|
1900
|
+
return { pts, closed: true };
|
|
1901
|
+
}
|
|
1902
|
+
function trimPolylines(lines, start, end) {
|
|
1903
|
+
const s = Math.max(0, Math.min(1, start)), e = Math.max(0, Math.min(1, end));
|
|
1904
|
+
if (!(e > s)) return [];
|
|
1905
|
+
const lengths = lines.map(polylineLength);
|
|
1906
|
+
const total = lengths.reduce((a, b) => a + b, 0);
|
|
1907
|
+
if (!(total > 0)) return [];
|
|
1908
|
+
const from = s * total, to = e * total;
|
|
1909
|
+
const out = [];
|
|
1910
|
+
let offset = 0;
|
|
1911
|
+
lines.forEach((line, i) => {
|
|
1912
|
+
const len = lengths[i];
|
|
1913
|
+
const a = Math.max(from - offset, 0), b = Math.min(to - offset, len);
|
|
1914
|
+
offset += len;
|
|
1915
|
+
if (!(b > a) || len === 0) return;
|
|
1916
|
+
if (line.closed && a <= 0 && b >= len) {
|
|
1917
|
+
out.push({ pts: line.pts.slice(), closed: true });
|
|
1918
|
+
return;
|
|
1919
|
+
}
|
|
1920
|
+
out.push({ pts: slice(line, a, b), closed: false });
|
|
1921
|
+
});
|
|
1922
|
+
return out;
|
|
1923
|
+
}
|
|
1924
|
+
function points(line) {
|
|
1925
|
+
return line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
1926
|
+
}
|
|
1927
|
+
function polylineLength(line) {
|
|
1928
|
+
const p = points(line);
|
|
1929
|
+
let len = 0;
|
|
1930
|
+
for (let i = 2; i < p.length; i += 2) len += Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
1931
|
+
return len;
|
|
1932
|
+
}
|
|
1933
|
+
function slice(line, a, b) {
|
|
1934
|
+
const p = points(line);
|
|
1935
|
+
const out = [];
|
|
1936
|
+
let at = 0;
|
|
1937
|
+
for (let i = 2; i < p.length; i += 2) {
|
|
1938
|
+
const x0 = p[i - 2], y0 = p[i - 1], x1 = p[i], y1 = p[i + 1];
|
|
1939
|
+
const seg = Math.hypot(x1 - x0, y1 - y0);
|
|
1940
|
+
const segEnd = at + seg;
|
|
1941
|
+
if (segEnd > a && at < b && seg > 0) {
|
|
1942
|
+
const t0 = Math.max(a - at, 0) / seg, t1 = Math.min(b - at, seg) / seg;
|
|
1943
|
+
if (out.length === 0) out.push(x0 + (x1 - x0) * t0, y0 + (y1 - y0) * t0);
|
|
1944
|
+
out.push(x0 + (x1 - x0) * t1, y0 + (y1 - y0) * t1);
|
|
1945
|
+
}
|
|
1946
|
+
at = segEnd;
|
|
1947
|
+
if (at >= b) break;
|
|
1948
|
+
}
|
|
1949
|
+
return out;
|
|
1950
|
+
}
|
|
1769
1951
|
|
|
1770
1952
|
// src/sequences/Shape.ts
|
|
1771
1953
|
var STYLE_KEYS = ["fillColor", "fillAlpha", "strokeColor", "strokeAlpha", "strokeWidth"];
|
|
1772
1954
|
var COLOR_KEYS = /* @__PURE__ */ new Set(["fillColor", "strokeColor"]);
|
|
1955
|
+
var TRIM_KEYS = ["trimStart", "trimEnd"];
|
|
1773
1956
|
var GEOMETRY_KEYS_BY_SHAPE = {
|
|
1774
|
-
rect: ["width", "height", "cornerRadius", "anchorX", "anchorY"],
|
|
1775
|
-
circle: ["radius", "anchorX", "anchorY"],
|
|
1776
|
-
ellipse: ["radiusX", "radiusY", "anchorX", "anchorY"],
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1957
|
+
rect: ["width", "height", "cornerRadius", "anchorX", "anchorY", ...TRIM_KEYS],
|
|
1958
|
+
circle: ["radius", "anchorX", "anchorY", ...TRIM_KEYS],
|
|
1959
|
+
ellipse: ["radiusX", "radiusY", "anchorX", "anchorY", ...TRIM_KEYS],
|
|
1960
|
+
arc: ["radius", "innerRadius", "startAngle", "endAngle"],
|
|
1961
|
+
line: [...TRIM_KEYS],
|
|
1962
|
+
polygon: [...TRIM_KEYS],
|
|
1963
|
+
path: [...TRIM_KEYS]
|
|
1780
1964
|
};
|
|
1781
|
-
var ANCHORED_SHAPES = /* @__PURE__ */ new Set(["rect", "circle", "ellipse"]);
|
|
1965
|
+
var ANCHORED_SHAPES = /* @__PURE__ */ new Set(["rect", "circle", "ellipse", "arc"]);
|
|
1782
1966
|
var ShapeSequence = class extends Sequence {
|
|
1783
1967
|
_state = {
|
|
1784
1968
|
fillColor: void 0,
|
|
@@ -1805,12 +1989,30 @@ var ShapeSequence = class extends Sequence {
|
|
|
1805
1989
|
for (const k of geomKeys) this._liveKeys.add(k);
|
|
1806
1990
|
seedGeometry(this._state, this.spec, scope);
|
|
1807
1991
|
seedStyle(this._state, this.spec.initial ?? {}, scope);
|
|
1992
|
+
seedStrokeStyle(this._state, this.spec, this.spec.initial ?? {}, describeLayer(this.spec));
|
|
1993
|
+
if (this.spec.shape === "arc") {
|
|
1994
|
+
this._state.startAngle ??= 0;
|
|
1995
|
+
this._state.endAngle ??= 360;
|
|
1996
|
+
const top = this.spec, ini = this.spec.initial ?? {};
|
|
1997
|
+
if ("trimStart" in top || "trimEnd" in top || "trimStart" in ini || "trimEnd" in ini) {
|
|
1998
|
+
console.warn(`pixi-effects: ${describeLayer(this.spec)}: trimStart / trimEnd do not apply to an arc: animate its endAngle (and startAngle) instead`);
|
|
1999
|
+
}
|
|
2000
|
+
} else {
|
|
2001
|
+
this._state.trimStart ??= 0;
|
|
2002
|
+
this._state.trimEnd ??= 1;
|
|
2003
|
+
}
|
|
1808
2004
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
1809
2005
|
if (gradientSpec) this._state.fillStyle = makeGradientFill(gradientSpec);
|
|
1810
2006
|
this._drawGeometry = makeDrawGeometry(this.spec, scope, this._state);
|
|
2007
|
+
this._outline = makeOutline(this.spec, scope, this._state);
|
|
2008
|
+
const { trimStart, trimEnd } = this._state;
|
|
2009
|
+
this._state.trimStart = 0;
|
|
2010
|
+
this._state.trimEnd = 1;
|
|
1811
2011
|
this._drawGeometry(graphics);
|
|
1812
2012
|
applyState(graphics, this._state);
|
|
1813
2013
|
const bounds = graphics.getLocalBounds();
|
|
2014
|
+
this._state.trimStart = trimStart;
|
|
2015
|
+
this._state.trimEnd = trimEnd;
|
|
1814
2016
|
this.intrinsicWidth = bounds.width;
|
|
1815
2017
|
this.intrinsicHeight = bounds.height;
|
|
1816
2018
|
if (!ANCHORED_SHAPES.has(this.spec.shape)) {
|
|
@@ -1828,14 +2030,37 @@ var ShapeSequence = class extends Sequence {
|
|
|
1828
2030
|
}
|
|
1829
2031
|
this._redraw();
|
|
1830
2032
|
};
|
|
2033
|
+
this._redraw();
|
|
1831
2034
|
this.buildFilters();
|
|
1832
2035
|
}
|
|
1833
2036
|
_fresh = false;
|
|
2037
|
+
_outline = null;
|
|
1834
2038
|
_redraw() {
|
|
1835
2039
|
const graphics = this.target;
|
|
2040
|
+
const s = this._state;
|
|
1836
2041
|
graphics.clear();
|
|
1837
|
-
|
|
1838
|
-
|
|
2042
|
+
const trimmed = (s.trimStart ?? 0) > 0 || (s.trimEnd ?? 1) < 1;
|
|
2043
|
+
if (!trimmed || !this._outline || !(s.strokeColor !== void 0 && s.strokeWidth > 0)) {
|
|
2044
|
+
this._drawGeometry(graphics);
|
|
2045
|
+
applyState(graphics, s);
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
if (s.fillStyle || s.fillColor !== void 0) {
|
|
2049
|
+
this._drawGeometry(graphics);
|
|
2050
|
+
applyFill(graphics, s);
|
|
2051
|
+
graphics.beginPath();
|
|
2052
|
+
}
|
|
2053
|
+
const parts = trimPolylines(this._outline(), s.trimStart ?? 0, s.trimEnd ?? 1);
|
|
2054
|
+
if (parts.length === 0) return;
|
|
2055
|
+
for (const part of parts) {
|
|
2056
|
+
if (part.closed) {
|
|
2057
|
+
graphics.poly(part.pts, true);
|
|
2058
|
+
continue;
|
|
2059
|
+
}
|
|
2060
|
+
graphics.moveTo(part.pts[0], part.pts[1]);
|
|
2061
|
+
for (let i = 2; i < part.pts.length; i += 2) graphics.lineTo(part.pts[i], part.pts[i + 1]);
|
|
2062
|
+
}
|
|
2063
|
+
applyStroke(graphics, s);
|
|
1839
2064
|
}
|
|
1840
2065
|
/**
|
|
1841
2066
|
* Draw from the tweened `_state` before the culler runs. The culler measures the geometry as last
|
|
@@ -1873,6 +2098,21 @@ function seedGeometry(state, spec, scope) {
|
|
|
1873
2098
|
if (v !== void 0) state[k] = num(v, scope);
|
|
1874
2099
|
}
|
|
1875
2100
|
}
|
|
2101
|
+
var STROKE_CAPS = ["butt", "round", "square"];
|
|
2102
|
+
var STROKE_JOINS = ["miter", "round", "bevel"];
|
|
2103
|
+
function seedStrokeStyle(state, spec, initial, who) {
|
|
2104
|
+
const top = spec;
|
|
2105
|
+
const ini = initial;
|
|
2106
|
+
const pick = (key, valid) => {
|
|
2107
|
+
const v = top[key] ?? ini[key];
|
|
2108
|
+
if (v === void 0) return void 0;
|
|
2109
|
+
if (valid.includes(String(v))) return String(v);
|
|
2110
|
+
console.warn(`pixi-effects: ${who}: ${key} "${v}" is not one of ${valid.join(", ")}; ignored`);
|
|
2111
|
+
return void 0;
|
|
2112
|
+
};
|
|
2113
|
+
state.strokeCap = pick("strokeCap", STROKE_CAPS);
|
|
2114
|
+
state.strokeJoin = pick("strokeJoin", STROKE_JOINS);
|
|
2115
|
+
}
|
|
1876
2116
|
function seedStyle(state, initial, scope) {
|
|
1877
2117
|
for (const k of STYLE_KEYS) {
|
|
1878
2118
|
const v = initial[k];
|
|
@@ -1881,8 +2121,8 @@ function seedStyle(state, initial, scope) {
|
|
|
1881
2121
|
}
|
|
1882
2122
|
}
|
|
1883
2123
|
function stripGradient(props) {
|
|
1884
|
-
if (!props || !("fillGradient" in props)) return props;
|
|
1885
|
-
const { fillGradient: _drop, ...rest } = props;
|
|
2124
|
+
if (!props || !("fillGradient" in props || "strokeCap" in props || "strokeJoin" in props)) return props;
|
|
2125
|
+
const { fillGradient: _drop, strokeCap: _cap, strokeJoin: _join, ...rest } = props;
|
|
1886
2126
|
return rest;
|
|
1887
2127
|
}
|
|
1888
2128
|
function stripLive(props, liveKeys) {
|
|
@@ -1923,13 +2163,25 @@ function resolveLiveValue(key, value, scope) {
|
|
|
1923
2163
|
return numOrZero(value, scope);
|
|
1924
2164
|
}
|
|
1925
2165
|
function applyState(g, s) {
|
|
2166
|
+
applyFill(g, s);
|
|
2167
|
+
applyStroke(g, s);
|
|
2168
|
+
}
|
|
2169
|
+
function applyFill(g, s) {
|
|
1926
2170
|
if (s.fillStyle) {
|
|
1927
2171
|
g.fill(s.fillStyle);
|
|
1928
2172
|
} else if (s.fillColor !== void 0) {
|
|
1929
2173
|
g.fill({ color: s.fillColor, alpha: s.fillAlpha });
|
|
1930
2174
|
}
|
|
2175
|
+
}
|
|
2176
|
+
function applyStroke(g, s) {
|
|
1931
2177
|
if (s.strokeColor !== void 0 && s.strokeWidth > 0) {
|
|
1932
|
-
g.stroke({
|
|
2178
|
+
g.stroke({
|
|
2179
|
+
color: s.strokeColor,
|
|
2180
|
+
alpha: s.strokeAlpha,
|
|
2181
|
+
width: s.strokeWidth,
|
|
2182
|
+
...s.strokeCap ? { cap: s.strokeCap } : {},
|
|
2183
|
+
...s.strokeJoin ? { join: s.strokeJoin } : {}
|
|
2184
|
+
});
|
|
1933
2185
|
}
|
|
1934
2186
|
}
|
|
1935
2187
|
function drawRectFromState(g, s) {
|
|
@@ -1956,6 +2208,34 @@ function drawEllipseFromState(g, s) {
|
|
|
1956
2208
|
const ay = s.anchorY ?? 0.5;
|
|
1957
2209
|
g.ellipse((0.5 - ax) * 2 * rx, (0.5 - ay) * 2 * ry, rx, ry);
|
|
1958
2210
|
}
|
|
2211
|
+
var DEG2 = Math.PI / 180;
|
|
2212
|
+
function drawArcFromState(g, s) {
|
|
2213
|
+
const r = s.radius ?? 0;
|
|
2214
|
+
const ri = Math.max(0, Math.min(s.innerRadius ?? 0, r));
|
|
2215
|
+
const startDeg = s.startAngle ?? 0;
|
|
2216
|
+
let endDeg = s.endAngle ?? 360;
|
|
2217
|
+
if (!(r > 0) || endDeg === startDeg) return;
|
|
2218
|
+
const filled = !!s.fillStyle || s.fillColor !== void 0;
|
|
2219
|
+
if (Math.abs(endDeg - startDeg) >= 360) {
|
|
2220
|
+
if (!filled) {
|
|
2221
|
+
g.circle(0, 0, r);
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
endDeg = startDeg + Math.sign(endDeg - startDeg) * 359.999;
|
|
2225
|
+
}
|
|
2226
|
+
const a0 = startDeg * DEG2, a1 = endDeg * DEG2;
|
|
2227
|
+
const ccw = a1 < a0;
|
|
2228
|
+
if (filled) g.moveTo(r * Math.cos(a0), r * Math.sin(a0));
|
|
2229
|
+
g.arc(0, 0, r, a0, a1, ccw);
|
|
2230
|
+
if (!filled) return;
|
|
2231
|
+
if (ri > 0) {
|
|
2232
|
+
g.lineTo(ri * Math.cos(a1), ri * Math.sin(a1));
|
|
2233
|
+
g.arc(0, 0, ri, a1, a0, !ccw);
|
|
2234
|
+
} else {
|
|
2235
|
+
g.lineTo(0, 0);
|
|
2236
|
+
}
|
|
2237
|
+
g.closePath();
|
|
2238
|
+
}
|
|
1959
2239
|
function makeLineDraw(spec, scope) {
|
|
1960
2240
|
const fx = num(spec.from[0], scope);
|
|
1961
2241
|
const fy = num(spec.from[1], scope);
|
|
@@ -1984,7 +2264,8 @@ function makePathDraw(spec) {
|
|
|
1984
2264
|
var STATE_DRAWERS = {
|
|
1985
2265
|
rect: drawRectFromState,
|
|
1986
2266
|
circle: drawCircleFromState,
|
|
1987
|
-
ellipse: drawEllipseFromState
|
|
2267
|
+
ellipse: drawEllipseFromState,
|
|
2268
|
+
arc: drawArcFromState
|
|
1988
2269
|
};
|
|
1989
2270
|
function makeDrawGeometry(spec, scope, state) {
|
|
1990
2271
|
const stateDrawer = STATE_DRAWERS[spec.shape];
|
|
@@ -2000,6 +2281,41 @@ function makeDrawGeometry(spec, scope, state) {
|
|
|
2000
2281
|
return () => {
|
|
2001
2282
|
};
|
|
2002
2283
|
}
|
|
2284
|
+
function makeOutline(spec, scope, s) {
|
|
2285
|
+
switch (spec.shape) {
|
|
2286
|
+
case "rect":
|
|
2287
|
+
return () => {
|
|
2288
|
+
const w = s.width ?? 0, h = s.height ?? 0;
|
|
2289
|
+
return [rectOutline(0 - (s.anchorX ?? 0.5) * w, 0 - (s.anchorY ?? 0.5) * h, w, h, s.cornerRadius ?? 0)];
|
|
2290
|
+
};
|
|
2291
|
+
case "circle":
|
|
2292
|
+
return () => {
|
|
2293
|
+
const r = s.radius ?? 0;
|
|
2294
|
+
return [ellipseOutline((0.5 - (s.anchorX ?? 0.5)) * 2 * r, (0.5 - (s.anchorY ?? 0.5)) * 2 * r, r, r)];
|
|
2295
|
+
};
|
|
2296
|
+
case "ellipse":
|
|
2297
|
+
return () => {
|
|
2298
|
+
const rx = s.radiusX ?? 0, ry = s.radiusY ?? 0;
|
|
2299
|
+
return [ellipseOutline((0.5 - (s.anchorX ?? 0.5)) * 2 * rx, (0.5 - (s.anchorY ?? 0.5)) * 2 * ry, rx, ry)];
|
|
2300
|
+
};
|
|
2301
|
+
case "line": {
|
|
2302
|
+
const lines = [{ pts: [num(spec.from[0], scope), num(spec.from[1], scope), num(spec.to[0], scope), num(spec.to[1], scope)], closed: false }];
|
|
2303
|
+
return () => lines;
|
|
2304
|
+
}
|
|
2305
|
+
case "polygon": {
|
|
2306
|
+
const pts = [];
|
|
2307
|
+
for (const [x, y] of spec.points) pts.push(num(x, scope), num(y, scope));
|
|
2308
|
+
const lines = pts.length >= 4 ? [{ pts, closed: !spec.open }] : [];
|
|
2309
|
+
return () => lines;
|
|
2310
|
+
}
|
|
2311
|
+
case "path": {
|
|
2312
|
+
let lines = null;
|
|
2313
|
+
return () => lines ??= flattenSvgPath(spec.d);
|
|
2314
|
+
}
|
|
2315
|
+
default:
|
|
2316
|
+
return null;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2003
2319
|
function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration, scope, offset, colorSpace) {
|
|
2004
2320
|
for (const kf of keyframes) {
|
|
2005
2321
|
const at = offset + resolveAt(kf.at, parentDuration);
|
|
@@ -2073,7 +2389,7 @@ function numOrZero(v, scope) {
|
|
|
2073
2389
|
var _CompositionSequence = null;
|
|
2074
2390
|
async function getCompositionSequence() {
|
|
2075
2391
|
if (!_CompositionSequence) {
|
|
2076
|
-
_CompositionSequence = (await import('./Composition-
|
|
2392
|
+
_CompositionSequence = (await import('./Composition-Y5VZSDDP.cjs')).CompositionSequence;
|
|
2077
2393
|
}
|
|
2078
2394
|
return _CompositionSequence;
|
|
2079
2395
|
}
|
|
@@ -2113,6 +2429,7 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
2113
2429
|
exports.CameraSequence = CameraSequence;
|
|
2114
2430
|
exports.DEFAULT_FOV = DEFAULT_FOV;
|
|
2115
2431
|
exports.DEG = DEG;
|
|
2432
|
+
exports.NEAR = NEAR;
|
|
2116
2433
|
exports.Sequence = Sequence;
|
|
2117
2434
|
exports.buildScope = buildScope;
|
|
2118
2435
|
exports.buildSequenceTree = buildSequenceTree;
|
|
@@ -2128,5 +2445,5 @@ exports.projectLayer = projectLayer;
|
|
|
2128
2445
|
exports.registerSequenceType = registerSequenceType;
|
|
2129
2446
|
exports.resolveAt = resolveAt;
|
|
2130
2447
|
exports.summarizeWarnings = summarizeWarnings;
|
|
2131
|
-
//# sourceMappingURL=chunk-
|
|
2132
|
-
//# sourceMappingURL=chunk-
|
|
2448
|
+
//# sourceMappingURL=chunk-KQM2ZZMK.cjs.map
|
|
2449
|
+
//# sourceMappingURL=chunk-KQM2ZZMK.cjs.map
|