pixi-effects 0.2.0 → 0.4.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 +55 -0
- package/README.md +16 -6
- package/ai/SKILL.md +46 -0
- package/ai/reference/cheatsheet.md +121 -0
- package/ai/reference/pitfalls.md +75 -0
- package/ai/reference/recipes.md +375 -0
- package/ai/template.html +82 -0
- package/ai/tools/save-image.py +24 -0
- package/dist/{Base-Bh_VSusi.d.ts → Base-5R7C5pHR.d.cts} +7 -1
- package/dist/{Base-B1Tdn0Cv.d.cts → Base-DhY9oMxr.d.ts} +7 -1
- package/dist/Composition-D7RCAGEA.cjs +13 -0
- package/dist/{Composition-BI5HZJFL.cjs.map → Composition-D7RCAGEA.cjs.map} +1 -1
- package/dist/Composition-RGTRZ2JX.js +4 -0
- package/dist/{Composition-IO7ZN32J.js.map → Composition-RGTRZ2JX.js.map} +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Movie-CghFXprP.d.cts +179 -0
- package/dist/Movie-DRZtIGU7.d.ts +179 -0
- package/dist/{chunk-7OIWYXGV.cjs → chunk-6BQ6IEW2.cjs} +363 -91
- package/dist/chunk-6BQ6IEW2.cjs.map +1 -0
- package/dist/{chunk-H55V3U56.js → chunk-A574IA4F.js} +68 -13
- package/dist/chunk-A574IA4F.js.map +1 -0
- package/dist/{chunk-64IHCYYN.cjs → chunk-QGBOC5YL.cjs} +76 -21
- package/dist/chunk-QGBOC5YL.cjs.map +1 -0
- package/dist/{chunk-VJCDG6YG.js → chunk-ZQX7WIYL.js} +359 -93
- package/dist/chunk-ZQX7WIYL.js.map +1 -0
- package/dist/index.cjs +366 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -31
- package/dist/index.d.ts +61 -31
- package/dist/index.js +363 -22
- package/dist/index.js.map +1 -1
- 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-CNBilhpz.d.cts → types-CRE9WKd4.d.cts} +59 -6
- package/dist/{types-CNBilhpz.d.ts → types-CRE9WKd4.d.ts} +59 -6
- package/docs/api.md +333 -0
- package/docs/dsl.md +1028 -0
- package/llms-full.txt +2001 -0
- package/llms.txt +30 -0
- package/package.json +5 -3
- package/dist/Composition-BI5HZJFL.cjs +0 -13
- package/dist/Composition-IO7ZN32J.js +0 -4
- package/dist/Movie-CcR6h2jO.d.cts +0 -82
- package/dist/Movie-D-n8glA6.d.ts +0 -82
- package/dist/chunk-64IHCYYN.cjs.map +0 -1
- package/dist/chunk-7OIWYXGV.cjs.map +0 -1
- package/dist/chunk-H55V3U56.js.map +0 -1
- package/dist/chunk-VJCDG6YG.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Rectangle, Container, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, Color, GraphicsPath } from 'pixi.js';
|
|
1
|
+
import { Rectangle, Container, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, FillGradient, Color, GraphicsPath } from 'pixi.js';
|
|
2
2
|
import { gsap } from 'gsap';
|
|
3
3
|
|
|
4
4
|
// src/sequences/Base.ts
|
|
@@ -244,6 +244,23 @@ function looksLikeColorString(s) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
// src/core/Timeline.ts
|
|
247
|
+
function loopVars(kf) {
|
|
248
|
+
const out = {};
|
|
249
|
+
let repeat = 0;
|
|
250
|
+
if (kf.repeat !== void 0) {
|
|
251
|
+
if (Number.isFinite(kf.repeat) && kf.repeat >= 0) {
|
|
252
|
+
repeat = Math.floor(kf.repeat);
|
|
253
|
+
out.repeat = repeat;
|
|
254
|
+
} else {
|
|
255
|
+
console.warn(`pixi-effects: keyframe repeat ${String(kf.repeat)} ignored \u2014 repeat must be a finite count >= 0 (the timeline needs a fixed length; for endless motion repeat many times).`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (repeat > 0) {
|
|
259
|
+
if (kf.yoyo !== void 0) out.yoyo = kf.yoyo;
|
|
260
|
+
if (kf.repeatDelay !== void 0 && kf.repeatDelay > 0) out.repeatDelay = kf.repeatDelay;
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
247
264
|
function resolveAt(at, duration) {
|
|
248
265
|
if (at === void 0 || at === null) return 0;
|
|
249
266
|
return at < 0 ? duration + at : at;
|
|
@@ -261,7 +278,7 @@ function normalizeKeyframe(kf, parentDuration) {
|
|
|
261
278
|
else if (hasFrom) kind = "from";
|
|
262
279
|
else if (hasTo) kind = "to";
|
|
263
280
|
else kind = "to";
|
|
264
|
-
return { at, duration, ease, kind, set: kf.set, from: kf.from, to: kf.to };
|
|
281
|
+
return { at, duration, ease, loop: loopVars(kf), kind, set: kf.set, from: kf.from, to: kf.to };
|
|
265
282
|
}
|
|
266
283
|
function partitionProps(props) {
|
|
267
284
|
const ownProps = {};
|
|
@@ -371,27 +388,27 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
371
388
|
const resolved = normalizeProps(kf.to, scope, { skipKeys });
|
|
372
389
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
373
390
|
for (const r of routed)
|
|
374
|
-
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease }, at);
|
|
391
|
+
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
375
392
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
376
393
|
if (Object.keys(ownProps).length > 0)
|
|
377
|
-
timeline.to(target, { ...pixiwrap(ownProps), duration: kf.duration, ease: kf.ease }, at);
|
|
394
|
+
timeline.to(target, { ...pixiwrap(ownProps), duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
378
395
|
for (const [name, props] of Object.entries(filterProps)) {
|
|
379
396
|
const f = findFilter(target, name);
|
|
380
397
|
if (!f) continue;
|
|
381
|
-
timeline.to(f, { ...props, duration: kf.duration, ease: kf.ease }, at);
|
|
398
|
+
timeline.to(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
382
399
|
}
|
|
383
400
|
} else if (kf.kind === "from") {
|
|
384
401
|
const resolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
385
402
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
386
403
|
for (const r of routed)
|
|
387
|
-
timeline.from(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease }, at);
|
|
404
|
+
timeline.from(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
388
405
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
389
406
|
if (Object.keys(ownProps).length > 0)
|
|
390
|
-
timeline.from(target, { ...pixiwrap(ownProps), duration: kf.duration, ease: kf.ease }, at);
|
|
407
|
+
timeline.from(target, { ...pixiwrap(ownProps), duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
391
408
|
for (const [name, props] of Object.entries(filterProps)) {
|
|
392
409
|
const f = findFilter(target, name);
|
|
393
410
|
if (!f) continue;
|
|
394
|
-
timeline.from(f, { ...props, duration: kf.duration, ease: kf.ease }, at);
|
|
411
|
+
timeline.from(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
395
412
|
}
|
|
396
413
|
} else {
|
|
397
414
|
const fromResolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
@@ -406,15 +423,15 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
406
423
|
timeline.fromTo(
|
|
407
424
|
r.target,
|
|
408
425
|
{ [r.prop]: f.value },
|
|
409
|
-
{ [r.prop]: r.value, duration: kf.duration, ease: kf.ease },
|
|
426
|
+
{ [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop },
|
|
410
427
|
at
|
|
411
428
|
);
|
|
412
429
|
} else {
|
|
413
|
-
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease }, at);
|
|
430
|
+
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
414
431
|
}
|
|
415
432
|
}
|
|
416
433
|
for (const f of fromByKey.values())
|
|
417
|
-
timeline.from(f.target, { [f.prop]: f.value, duration: kf.duration, ease: kf.ease }, at);
|
|
434
|
+
timeline.from(f.target, { [f.prop]: f.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
418
435
|
const fromSplit = partitionProps(fromRouted.rest);
|
|
419
436
|
const toSplit = partitionProps(toRouted.rest);
|
|
420
437
|
const ownKeys = /* @__PURE__ */ new Set([...Object.keys(fromSplit.ownProps), ...Object.keys(toSplit.ownProps)]);
|
|
@@ -422,7 +439,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
422
439
|
timeline.fromTo(
|
|
423
440
|
target,
|
|
424
441
|
{ ...pixiwrap(fromSplit.ownProps) },
|
|
425
|
-
{ ...pixiwrap(toSplit.ownProps), duration: kf.duration, ease: kf.ease },
|
|
442
|
+
{ ...pixiwrap(toSplit.ownProps), duration: kf.duration, ease: kf.ease, ...kf.loop },
|
|
426
443
|
at
|
|
427
444
|
);
|
|
428
445
|
}
|
|
@@ -436,7 +453,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
436
453
|
timeline.fromTo(
|
|
437
454
|
f,
|
|
438
455
|
{ ...fromSplit.filterProps[name] ?? {} },
|
|
439
|
-
{ ...toSplit.filterProps[name] ?? {}, duration: kf.duration, ease: kf.ease },
|
|
456
|
+
{ ...toSplit.filterProps[name] ?? {}, duration: kf.duration, ease: kf.ease, ...kf.loop },
|
|
440
457
|
at
|
|
441
458
|
);
|
|
442
459
|
}
|
|
@@ -761,9 +778,9 @@ var Sequence = class {
|
|
|
761
778
|
if (!this.target) return;
|
|
762
779
|
const scope = this.scope();
|
|
763
780
|
const routers = this.pathRouters();
|
|
764
|
-
applyInitial(this.target, this.spec.initial, scope, [], routers);
|
|
765
|
-
applyKeyframes(timeline, this.target, this.spec.keyframes, this.duration, scope, [], offset, routers);
|
|
766
781
|
const startTime = offset + this.at;
|
|
782
|
+
applyInitial(this.target, this.spec.initial, scope, [], routers);
|
|
783
|
+
applyKeyframes(timeline, this.target, this.spec.keyframes, this.duration, scope, [], startTime, routers);
|
|
767
784
|
const endTime = startTime + this.duration;
|
|
768
785
|
this.absoluteStart = startTime;
|
|
769
786
|
this.target.renderable = startTime <= 0;
|
|
@@ -779,6 +796,14 @@ var Sequence = class {
|
|
|
779
796
|
*/
|
|
780
797
|
updateSpace(_t, _host) {
|
|
781
798
|
}
|
|
799
|
+
/**
|
|
800
|
+
* Runs once per rendered frame, after the timeline seek and before the cull. Layers whose drawn
|
|
801
|
+
* geometry follows tweened state (shapes) redraw here, so the culler measures where the layer is NOW
|
|
802
|
+
* and not where it was drawn at the previous render.
|
|
803
|
+
*/
|
|
804
|
+
syncFrame() {
|
|
805
|
+
this.maskSequence?.syncFrame();
|
|
806
|
+
}
|
|
782
807
|
destroy() {
|
|
783
808
|
this.maskSequence?.destroy();
|
|
784
809
|
this.maskSequence = null;
|
|
@@ -787,6 +812,51 @@ var Sequence = class {
|
|
|
787
812
|
}
|
|
788
813
|
};
|
|
789
814
|
|
|
815
|
+
// src/space/specKeys.ts
|
|
816
|
+
function collectPropKeys(spec) {
|
|
817
|
+
const out = /* @__PURE__ */ new Set();
|
|
818
|
+
for (const k of Object.keys(spec.initial ?? {})) out.add(k);
|
|
819
|
+
for (const kf of spec.keyframes ?? []) {
|
|
820
|
+
for (const bag of [kf.set, kf.to, kf.from]) {
|
|
821
|
+
for (const k of Object.keys(bag ?? {})) out.add(k);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
return out;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/core/lint.ts
|
|
828
|
+
var defaultWarn = (m) => console.warn(m);
|
|
829
|
+
function describeLayer(spec) {
|
|
830
|
+
return spec.name ? `layer "${spec.name}"` : `unnamed ${spec.type} layer`;
|
|
831
|
+
}
|
|
832
|
+
function lintTiming(spec, parentDuration, warn = defaultWarn) {
|
|
833
|
+
const who = describeLayer(spec);
|
|
834
|
+
const at = spec.at ?? 0;
|
|
835
|
+
if (at >= parentDuration) {
|
|
836
|
+
warn(`pixi-effects: ${who} starts at ${at}s, after its composition ends (${parentDuration}s), so it is never visible`);
|
|
837
|
+
}
|
|
838
|
+
const duration = spec.duration ?? parentDuration;
|
|
839
|
+
(spec.keyframes ?? []).forEach((kf, i) => {
|
|
840
|
+
const kat = kf.at ?? 0;
|
|
841
|
+
if (kat >= duration) {
|
|
842
|
+
warn(
|
|
843
|
+
`pixi-effects: ${who}: keyframes[${i}] starts at ${kat}s, after the layer ends (duration ${duration}s), so it never plays. Keyframe \`at\` is measured from the start of this layer, not from the start of the composition.`,
|
|
844
|
+
"late-keyframe"
|
|
845
|
+
);
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function summarizeWarnings(messages, shown = 3) {
|
|
850
|
+
if (messages.length <= shown) return messages;
|
|
851
|
+
return [...messages.slice(0, shown), `pixi-effects: ${messages.length - shown} more layers with the same problem (the same loop or helper is probably building them): fix the ones above and these go away.`];
|
|
852
|
+
}
|
|
853
|
+
function lintText(spec, warn = defaultWarn) {
|
|
854
|
+
if (spec.type !== "text") return;
|
|
855
|
+
if (collectPropKeys(spec).has("value") && !(spec.text ?? "").includes("{value}")) {
|
|
856
|
+
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').`);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
790
860
|
// src/space/math.ts
|
|
791
861
|
var DEG = Math.PI / 180;
|
|
792
862
|
var DEFAULT_FOV = 40;
|
|
@@ -898,20 +968,6 @@ function projectLayer(t, frame, b) {
|
|
|
898
968
|
const origin = projectPoint(b, { x: t.x, y: t.y, z: t.z });
|
|
899
969
|
return { corners, depth: origin.depth, visible };
|
|
900
970
|
}
|
|
901
|
-
|
|
902
|
-
// src/space/specKeys.ts
|
|
903
|
-
function collectPropKeys(spec) {
|
|
904
|
-
const out = /* @__PURE__ */ new Set();
|
|
905
|
-
for (const k of Object.keys(spec.initial ?? {})) out.add(k);
|
|
906
|
-
for (const kf of spec.keyframes ?? []) {
|
|
907
|
-
for (const bag of [kf.set, kf.to, kf.from]) {
|
|
908
|
-
for (const k of Object.keys(bag ?? {})) out.add(k);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
return out;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
// src/space/CameraSequence.ts
|
|
915
971
|
var CameraSequence = class extends Sequence {
|
|
916
972
|
/** True when `z` is never specified anywhere: z then follows `fov`. */
|
|
917
973
|
autoZ = true;
|
|
@@ -968,6 +1024,27 @@ var CameraSequence = class extends Sequence {
|
|
|
968
1024
|
}
|
|
969
1025
|
};
|
|
970
1026
|
|
|
1027
|
+
// src/core/revertibleSet.ts
|
|
1028
|
+
function revertibleSet(timeline, at, read, write, value) {
|
|
1029
|
+
let p = 0;
|
|
1030
|
+
let before;
|
|
1031
|
+
const proxy = {
|
|
1032
|
+
get p() {
|
|
1033
|
+
return p;
|
|
1034
|
+
},
|
|
1035
|
+
set p(next) {
|
|
1036
|
+
if (next >= 1 && p < 1) {
|
|
1037
|
+
before = read();
|
|
1038
|
+
write(value);
|
|
1039
|
+
} else if (next < 1 && p >= 1) {
|
|
1040
|
+
write(before);
|
|
1041
|
+
}
|
|
1042
|
+
p = next;
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
timeline.set(proxy, { p: 1 }, at);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
971
1048
|
// src/expr/colorInterp.ts
|
|
972
1049
|
function buildColorInterp(from, to, space) {
|
|
973
1050
|
const fromRGBA = parseToRGBA(from);
|
|
@@ -1094,7 +1171,7 @@ function shortestHueDelta(from, to) {
|
|
|
1094
1171
|
}
|
|
1095
1172
|
|
|
1096
1173
|
// src/expr/colorTween.ts
|
|
1097
|
-
function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, at, colorSpace, onUpdate) {
|
|
1174
|
+
function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, at, colorSpace, onUpdate, loop = {}) {
|
|
1098
1175
|
let interp = null;
|
|
1099
1176
|
const proxy = { p: 0 };
|
|
1100
1177
|
timeline.fromTo(
|
|
@@ -1104,6 +1181,7 @@ function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, a
|
|
|
1104
1181
|
p: 1,
|
|
1105
1182
|
duration,
|
|
1106
1183
|
ease,
|
|
1184
|
+
...loop,
|
|
1107
1185
|
onStart: () => {
|
|
1108
1186
|
const start = fromValue !== void 0 ? fromValue : target[key];
|
|
1109
1187
|
if (start === void 0) return;
|
|
@@ -1142,23 +1220,25 @@ var ImageSequence = class extends Sequence {
|
|
|
1142
1220
|
return;
|
|
1143
1221
|
}
|
|
1144
1222
|
const scope = this.scope();
|
|
1223
|
+
const startTime = offset + this.at;
|
|
1145
1224
|
const initial = stripKeys(this.spec.initial, ["tint"]);
|
|
1146
1225
|
const keyframes = this.spec.keyframes ? this.spec.keyframes.map((kf) => stripKeysInKeyframe(kf, ["tint"])) : void 0;
|
|
1147
1226
|
applyInitial(this.target, initial, scope);
|
|
1148
|
-
applyKeyframes(timeline, this.target, keyframes, this.duration, scope, [],
|
|
1227
|
+
applyKeyframes(timeline, this.target, keyframes, this.duration, scope, [], startTime);
|
|
1149
1228
|
const initTint = this.spec.initial?.tint;
|
|
1150
1229
|
if (initTint !== void 0) this.target.tint = initTint;
|
|
1151
1230
|
for (const kf of this.spec.keyframes ?? []) {
|
|
1152
|
-
const at =
|
|
1231
|
+
const at = startTime + resolveAt(kf.at, this.duration);
|
|
1153
1232
|
const duration = kf.duration ?? 0;
|
|
1154
1233
|
const ease = kf.ease ?? "none";
|
|
1155
1234
|
const fromTint = kf.from?.tint;
|
|
1156
1235
|
const toTint = kf.to?.tint;
|
|
1157
1236
|
const setTint = kf.set?.tint;
|
|
1158
1237
|
if (setTint !== void 0) {
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1238
|
+
const sprite = this.target;
|
|
1239
|
+
revertibleSet(timeline, at, () => sprite.tint, (c) => {
|
|
1240
|
+
sprite.tint = c;
|
|
1241
|
+
}, setTint);
|
|
1162
1242
|
}
|
|
1163
1243
|
if (toTint !== void 0) {
|
|
1164
1244
|
tweenColor(
|
|
@@ -1170,11 +1250,12 @@ var ImageSequence = class extends Sequence {
|
|
|
1170
1250
|
duration,
|
|
1171
1251
|
ease,
|
|
1172
1252
|
at,
|
|
1173
|
-
colorSpace
|
|
1253
|
+
colorSpace,
|
|
1254
|
+
void 0,
|
|
1255
|
+
loopVars(kf)
|
|
1174
1256
|
);
|
|
1175
1257
|
}
|
|
1176
1258
|
}
|
|
1177
|
-
const startTime = offset + this.at;
|
|
1178
1259
|
this.absoluteStart = startTime;
|
|
1179
1260
|
const endTime = startTime + this.duration;
|
|
1180
1261
|
this.target.renderable = startTime <= 0;
|
|
@@ -1204,8 +1285,40 @@ function stripKeysInKeyframe(kf, keys) {
|
|
|
1204
1285
|
from: stripKeys(kf.from, keys)
|
|
1205
1286
|
};
|
|
1206
1287
|
}
|
|
1207
|
-
var STYLE_OPAQUE_KEYS = [
|
|
1288
|
+
var STYLE_OPAQUE_KEYS = [
|
|
1289
|
+
"fontFamily",
|
|
1290
|
+
"fill",
|
|
1291
|
+
"align",
|
|
1292
|
+
"fontStyle",
|
|
1293
|
+
"fontWeight",
|
|
1294
|
+
"fontVariant",
|
|
1295
|
+
"textBaseline",
|
|
1296
|
+
"whiteSpace",
|
|
1297
|
+
"lineJoin",
|
|
1298
|
+
"join",
|
|
1299
|
+
"cap",
|
|
1300
|
+
"color",
|
|
1301
|
+
"stroke"
|
|
1302
|
+
];
|
|
1303
|
+
function formatValue(v, f) {
|
|
1304
|
+
const fixed = v.toFixed(Math.max(0, Math.floor(f?.decimals ?? 0)));
|
|
1305
|
+
if (!f?.grouping) return fixed;
|
|
1306
|
+
const [int, frac] = fixed.split(".");
|
|
1307
|
+
return int.replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (frac !== void 0 ? "." + frac : "");
|
|
1308
|
+
}
|
|
1208
1309
|
var TextSequence = class extends Sequence {
|
|
1310
|
+
/** Current number for the `{value}` placeholder (tweened by `value` keyframes). */
|
|
1311
|
+
_value = { value: 0 };
|
|
1312
|
+
_lastText = "";
|
|
1313
|
+
/** Rewrite the displayed string from the template and the current `value`. */
|
|
1314
|
+
_refreshText() {
|
|
1315
|
+
const template = this.spec.text ?? "";
|
|
1316
|
+
if (!template.includes("{value}")) return;
|
|
1317
|
+
const next = template.split("{value}").join(formatValue(this._value.value, this.spec.format));
|
|
1318
|
+
if (next === this._lastText) return;
|
|
1319
|
+
this._lastText = next;
|
|
1320
|
+
this.target.text = next;
|
|
1321
|
+
}
|
|
1209
1322
|
async build() {
|
|
1210
1323
|
const baseStyle = {
|
|
1211
1324
|
fontFamily: "Arial",
|
|
@@ -1235,15 +1348,25 @@ var TextSequence = class extends Sequence {
|
|
|
1235
1348
|
for (const k of Object.keys(resolved)) {
|
|
1236
1349
|
text.style[k] = resolved[k];
|
|
1237
1350
|
}
|
|
1351
|
+
this.intrinsicWidth = text.width;
|
|
1352
|
+
this.intrinsicHeight = text.height;
|
|
1353
|
+
}
|
|
1354
|
+
const initialValue = this.spec.initial?.value;
|
|
1355
|
+
if (initialValue !== void 0) this._value.value = resolveNumber(initialValue, this.scope());
|
|
1356
|
+
this._refreshText();
|
|
1357
|
+
if (this._lastText !== "") {
|
|
1358
|
+
this.intrinsicWidth = text.width;
|
|
1359
|
+
this.intrinsicHeight = text.height;
|
|
1238
1360
|
}
|
|
1239
1361
|
this.buildFilters();
|
|
1240
1362
|
}
|
|
1241
1363
|
bindTimeline(timeline, offset = 0) {
|
|
1242
1364
|
if (!this.target) return;
|
|
1243
1365
|
const colorSpace = this.spec.colorSpace ?? "rgb";
|
|
1244
|
-
const stripped =
|
|
1366
|
+
const stripped = stripKeys2(this.spec, ["fill", "value"]);
|
|
1245
1367
|
runSuperWithStrippedSpec(this, stripped, timeline, offset);
|
|
1246
|
-
bindFillKeyframes(timeline, this.target, this.spec.keyframes ?? [], this.duration, offset, colorSpace);
|
|
1368
|
+
bindFillKeyframes(timeline, this.target, this.spec.keyframes ?? [], this.duration, offset + this.at, colorSpace);
|
|
1369
|
+
bindValueKeyframes(timeline, this._value, () => this._refreshText(), this.spec.keyframes ?? [], this.duration, offset + this.at, this.scope());
|
|
1247
1370
|
}
|
|
1248
1371
|
};
|
|
1249
1372
|
function runSuperWithStrippedSpec(inst, strippedSpec, timeline, offset) {
|
|
@@ -1255,25 +1378,61 @@ function runSuperWithStrippedSpec(inst, strippedSpec, timeline, offset) {
|
|
|
1255
1378
|
inst.spec = originalSpec;
|
|
1256
1379
|
}
|
|
1257
1380
|
}
|
|
1258
|
-
function
|
|
1381
|
+
function stripKeys2(spec, keys) {
|
|
1259
1382
|
return {
|
|
1260
1383
|
...spec,
|
|
1261
|
-
initial:
|
|
1384
|
+
initial: stripProps(spec.initial, keys),
|
|
1262
1385
|
keyframes: spec.keyframes ? spec.keyframes.map((kf) => ({
|
|
1263
1386
|
...kf,
|
|
1264
|
-
set:
|
|
1265
|
-
to:
|
|
1266
|
-
from:
|
|
1387
|
+
set: stripProps(kf.set, keys),
|
|
1388
|
+
to: stripProps(kf.to, keys),
|
|
1389
|
+
from: stripProps(kf.from, keys)
|
|
1267
1390
|
})) : void 0
|
|
1268
1391
|
};
|
|
1269
1392
|
}
|
|
1270
|
-
function
|
|
1393
|
+
function stripProps(props, keys) {
|
|
1271
1394
|
if (!props) return props;
|
|
1272
|
-
if (!(
|
|
1395
|
+
if (!keys.some((k) => k in props)) return props;
|
|
1273
1396
|
const out = {};
|
|
1274
|
-
for (const k of Object.keys(props)) if (k
|
|
1397
|
+
for (const k of Object.keys(props)) if (!keys.includes(k)) out[k] = props[k];
|
|
1275
1398
|
return out;
|
|
1276
1399
|
}
|
|
1400
|
+
function resolveNumber(v, scope) {
|
|
1401
|
+
if (typeof v === "number") return v;
|
|
1402
|
+
const out = normalizeProps({ v }, scope).v;
|
|
1403
|
+
return typeof out === "number" ? out : Number(out) || 0;
|
|
1404
|
+
}
|
|
1405
|
+
function bindValueKeyframes(timeline, state, refresh, keyframes, parentDuration, origin, scope) {
|
|
1406
|
+
for (const kf of keyframes) {
|
|
1407
|
+
const setV = kf.set?.value;
|
|
1408
|
+
const fromV = kf.from?.value;
|
|
1409
|
+
const toV = kf.to?.value;
|
|
1410
|
+
if (setV === void 0 && fromV === void 0 && toV === void 0) continue;
|
|
1411
|
+
const at = origin + resolveAt(kf.at, parentDuration);
|
|
1412
|
+
const duration = kf.duration ?? 0;
|
|
1413
|
+
const ease = kf.ease ?? "none";
|
|
1414
|
+
const loop = loopVars(kf);
|
|
1415
|
+
if (setV !== void 0) {
|
|
1416
|
+
const v = resolveNumber(setV, scope);
|
|
1417
|
+
revertibleSet(timeline, at, () => state.value, (n) => {
|
|
1418
|
+
state.value = n;
|
|
1419
|
+
refresh();
|
|
1420
|
+
}, v);
|
|
1421
|
+
}
|
|
1422
|
+
if (toV !== void 0 && fromV !== void 0) {
|
|
1423
|
+
timeline.fromTo(
|
|
1424
|
+
state,
|
|
1425
|
+
{ value: resolveNumber(fromV, scope) },
|
|
1426
|
+
{ value: resolveNumber(toV, scope), duration, ease, ...loop, onUpdate: refresh },
|
|
1427
|
+
at
|
|
1428
|
+
);
|
|
1429
|
+
} else if (toV !== void 0) {
|
|
1430
|
+
timeline.to(state, { value: resolveNumber(toV, scope), duration, ease, ...loop, onUpdate: refresh }, at);
|
|
1431
|
+
} else if (fromV !== void 0) {
|
|
1432
|
+
timeline.from(state, { value: resolveNumber(fromV, scope), duration, ease, ...loop, onUpdate: refresh }, at);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1277
1436
|
function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, colorSpace) {
|
|
1278
1437
|
const state = { fill: text.style.fill };
|
|
1279
1438
|
const writeFill = () => {
|
|
@@ -1287,10 +1446,10 @@ function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, co
|
|
|
1287
1446
|
const fromFill = pickFill(kf.from);
|
|
1288
1447
|
const toFill = pickFill(kf.to);
|
|
1289
1448
|
if (setFill !== void 0) {
|
|
1290
|
-
timeline.
|
|
1291
|
-
state.fill =
|
|
1449
|
+
revertibleSet(timeline, at, () => state.fill, (c) => {
|
|
1450
|
+
state.fill = c;
|
|
1292
1451
|
writeFill();
|
|
1293
|
-
},
|
|
1452
|
+
}, setFill);
|
|
1294
1453
|
}
|
|
1295
1454
|
if (toFill !== void 0) {
|
|
1296
1455
|
tweenColor(
|
|
@@ -1303,7 +1462,8 @@ function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, co
|
|
|
1303
1462
|
ease,
|
|
1304
1463
|
at,
|
|
1305
1464
|
colorSpace,
|
|
1306
|
-
writeFill
|
|
1465
|
+
writeFill,
|
|
1466
|
+
loopVars(kf)
|
|
1307
1467
|
);
|
|
1308
1468
|
}
|
|
1309
1469
|
}
|
|
@@ -1320,7 +1480,13 @@ var AudioSequence = class extends Sequence {
|
|
|
1320
1480
|
const data = await Assets.get(this.spec.asset);
|
|
1321
1481
|
this._audioBuffer = data.audioBuffer;
|
|
1322
1482
|
if (this.duration === void 0) {
|
|
1323
|
-
|
|
1483
|
+
const rest = Math.max(0, (this.parent?.duration ?? this.root.duration) - this.at);
|
|
1484
|
+
this.duration = this.spec.duration ?? (this.spec.loop ? rest : data.duration) ?? this.root.duration;
|
|
1485
|
+
}
|
|
1486
|
+
if (!this.spec.loop && data.duration !== void 0 && this.duration > data.duration + 0.05) {
|
|
1487
|
+
console.warn(
|
|
1488
|
+
`pixi-effects: ${describeLayer(this.spec)}: audio asset "${this.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.`
|
|
1489
|
+
);
|
|
1324
1490
|
}
|
|
1325
1491
|
this.target = null;
|
|
1326
1492
|
}
|
|
@@ -1331,21 +1497,32 @@ var AudioSequence = class extends Sequence {
|
|
|
1331
1497
|
const initialVolume = this.spec.volume ?? 1;
|
|
1332
1498
|
const volumeKeyframes = [];
|
|
1333
1499
|
const dur = this.duration;
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1500
|
+
const t0 = baseTime + this.at;
|
|
1501
|
+
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);
|
|
1502
|
+
let current = initialVolume;
|
|
1503
|
+
const point = (time, value) => {
|
|
1504
|
+
volumeKeyframes.push({ time, value });
|
|
1505
|
+
};
|
|
1506
|
+
for (const kf of keyframes) {
|
|
1507
|
+
const start = t0 + kf.at;
|
|
1508
|
+
const end = start + kf.duration;
|
|
1509
|
+
const set = kf.set?.volume;
|
|
1510
|
+
const to = kf.to?.volume;
|
|
1511
|
+
const from = kf.from?.volume;
|
|
1512
|
+
point(start, current);
|
|
1513
|
+
if (kf.kind === "set" && set !== void 0) {
|
|
1514
|
+
point(start, set);
|
|
1515
|
+
current = set;
|
|
1516
|
+
} else if (kf.kind === "to" && to !== void 0) {
|
|
1517
|
+
point(end, to);
|
|
1518
|
+
current = to;
|
|
1519
|
+
} else if (kf.kind === "fromTo" && to !== void 0) {
|
|
1520
|
+
point(start, from ?? current);
|
|
1521
|
+
point(end, to);
|
|
1522
|
+
current = to;
|
|
1523
|
+
} else if (kf.kind === "from" && from !== void 0) {
|
|
1524
|
+
point(start, from);
|
|
1525
|
+
point(end, current);
|
|
1349
1526
|
}
|
|
1350
1527
|
}
|
|
1351
1528
|
out.push({
|
|
@@ -1491,14 +1668,15 @@ var VideoSequence = class extends Sequence {
|
|
|
1491
1668
|
});
|
|
1492
1669
|
this.buildFilters();
|
|
1493
1670
|
}
|
|
1494
|
-
bindTimeline(timeline) {
|
|
1495
|
-
super.bindTimeline(timeline);
|
|
1671
|
+
bindTimeline(timeline, offset = 0) {
|
|
1672
|
+
super.bindTimeline(timeline, offset);
|
|
1496
1673
|
const playDuration = this.spec.loop ? this.duration : Math.min(this.duration, this._sourceDuration);
|
|
1497
1674
|
timeline.fromTo(
|
|
1498
1675
|
this.target,
|
|
1499
1676
|
{ currentTime: 0 },
|
|
1500
1677
|
{ currentTime: playDuration, duration: playDuration, ease: "none" },
|
|
1501
|
-
this.at
|
|
1678
|
+
offset + this.at
|
|
1679
|
+
// offset = start of the enclosing composition(s); dropping it misplaced videos inside nested compositions
|
|
1502
1680
|
);
|
|
1503
1681
|
}
|
|
1504
1682
|
collectAudio(out, baseTime) {
|
|
@@ -1539,6 +1717,55 @@ var VideoSequence = class extends Sequence {
|
|
|
1539
1717
|
super.destroy();
|
|
1540
1718
|
}
|
|
1541
1719
|
};
|
|
1720
|
+
|
|
1721
|
+
// src/sequences/gradient.ts
|
|
1722
|
+
function cssColor(c) {
|
|
1723
|
+
return typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
|
|
1724
|
+
}
|
|
1725
|
+
function normalizedStops(g) {
|
|
1726
|
+
const stops = g.stops ?? [];
|
|
1727
|
+
if (stops.length < 2) throw new Error('pixi-effects: fillGradient needs at least two colour stops, e.g. stops: [[0, "#000"], [1, "#fff"]]');
|
|
1728
|
+
return stops.map((s) => Array.isArray(s) ? { offset: s[0], color: s[1] } : { offset: s.offset, color: s.color });
|
|
1729
|
+
}
|
|
1730
|
+
function gradientOptions(g) {
|
|
1731
|
+
const colorStops = normalizedStops(g);
|
|
1732
|
+
const a = (g.angle ?? 90) * Math.PI / 180;
|
|
1733
|
+
const dx = Math.cos(a), dy = Math.sin(a);
|
|
1734
|
+
const h = (Math.abs(dx) + Math.abs(dy)) / 2;
|
|
1735
|
+
return {
|
|
1736
|
+
type: "linear",
|
|
1737
|
+
start: { x: 0.5 - dx * h, y: 0.5 - dy * h },
|
|
1738
|
+
end: { x: 0.5 + dx * h, y: 0.5 + dy * h },
|
|
1739
|
+
colorStops,
|
|
1740
|
+
textureSpace: "local"
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
function paintRadial(ctx, size, g) {
|
|
1744
|
+
const stops = normalizedStops(g);
|
|
1745
|
+
const [cx, cy] = g.center ?? [0.5, 0.5];
|
|
1746
|
+
const grad = ctx.createRadialGradient(cx * size, cy * size, (g.innerRadius ?? 0) * size, cx * size, cy * size, (g.radius ?? 0.5) * size);
|
|
1747
|
+
for (const s of stops) grad.addColorStop(s.offset, cssColor(s.color));
|
|
1748
|
+
ctx.fillStyle = grad;
|
|
1749
|
+
ctx.fillRect(0, 0, size, size);
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
// src/sequences/gradientFill.ts
|
|
1753
|
+
var RADIAL_SIZE = 256;
|
|
1754
|
+
function makeGradientFill(g) {
|
|
1755
|
+
if (g.type === "radial") {
|
|
1756
|
+
const canvas = document.createElement("canvas");
|
|
1757
|
+
canvas.width = RADIAL_SIZE;
|
|
1758
|
+
canvas.height = RADIAL_SIZE;
|
|
1759
|
+
const ctx = canvas.getContext("2d");
|
|
1760
|
+
if (ctx) {
|
|
1761
|
+
paintRadial(ctx, RADIAL_SIZE, g);
|
|
1762
|
+
return { texture: Texture.from(canvas), textureSpace: "local" };
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
return new FillGradient(gradientOptions(g));
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
// src/sequences/Shape.ts
|
|
1542
1769
|
var STYLE_KEYS = ["fillColor", "fillAlpha", "strokeColor", "strokeAlpha", "strokeWidth"];
|
|
1543
1770
|
var COLOR_KEYS = /* @__PURE__ */ new Set(["fillColor", "strokeColor"]);
|
|
1544
1771
|
var GEOMETRY_KEYS_BY_SHAPE = {
|
|
@@ -1576,6 +1803,8 @@ var ShapeSequence = class extends Sequence {
|
|
|
1576
1803
|
for (const k of geomKeys) this._liveKeys.add(k);
|
|
1577
1804
|
seedGeometry(this._state, this.spec, scope);
|
|
1578
1805
|
seedStyle(this._state, this.spec.initial ?? {}, scope);
|
|
1806
|
+
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
1807
|
+
if (gradientSpec) this._state.fillStyle = makeGradientFill(gradientSpec);
|
|
1579
1808
|
this._drawGeometry = makeDrawGeometry(this.spec, scope, this._state);
|
|
1580
1809
|
this._drawGeometry(graphics);
|
|
1581
1810
|
applyState(graphics, this._state);
|
|
@@ -1583,25 +1812,50 @@ var ShapeSequence = class extends Sequence {
|
|
|
1583
1812
|
this.intrinsicWidth = bounds.width;
|
|
1584
1813
|
this.intrinsicHeight = bounds.height;
|
|
1585
1814
|
if (!ANCHORED_SHAPES.has(this.spec.shape)) {
|
|
1586
|
-
|
|
1815
|
+
const cx = bounds.x + bounds.width / 2;
|
|
1816
|
+
const cy = bounds.y + bounds.height / 2;
|
|
1817
|
+
graphics.pivot.set(cx, cy);
|
|
1818
|
+
const init = this.spec.initial ?? {};
|
|
1819
|
+
if (init.x === void 0) graphics.x = cx;
|
|
1820
|
+
if (init.y === void 0) graphics.y = cy;
|
|
1587
1821
|
}
|
|
1588
1822
|
graphics.onRender = () => {
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1823
|
+
if (this._fresh) {
|
|
1824
|
+
this._fresh = false;
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
this._redraw();
|
|
1592
1828
|
};
|
|
1593
1829
|
this.buildFilters();
|
|
1594
1830
|
}
|
|
1831
|
+
_fresh = false;
|
|
1832
|
+
_redraw() {
|
|
1833
|
+
const graphics = this.target;
|
|
1834
|
+
graphics.clear();
|
|
1835
|
+
this._drawGeometry(graphics);
|
|
1836
|
+
applyState(graphics, this._state);
|
|
1837
|
+
}
|
|
1838
|
+
/**
|
|
1839
|
+
* Draw from the tweened `_state` before the culler runs. The culler measures the geometry as last
|
|
1840
|
+
* drawn; a layer drawn only inside `onRender` is culled on stale bounds (a rect growing from
|
|
1841
|
+
* `width: 0` at the left edge was skipped after a jump seek, and one frame late in playback).
|
|
1842
|
+
*/
|
|
1843
|
+
syncFrame() {
|
|
1844
|
+
super.syncFrame();
|
|
1845
|
+
if (!this.target?.renderable) return;
|
|
1846
|
+
this._redraw();
|
|
1847
|
+
this._fresh = true;
|
|
1848
|
+
}
|
|
1595
1849
|
bindTimeline(timeline, offset = 0) {
|
|
1596
1850
|
if (!this.target) return;
|
|
1597
1851
|
const scope = this.scope();
|
|
1598
|
-
const
|
|
1852
|
+
const startTime = offset + this.at;
|
|
1853
|
+
const initial = stripLive(stripGradient(this.spec.initial), this._liveKeys);
|
|
1599
1854
|
const keyframes = this.spec.keyframes ? this.spec.keyframes.map((kf) => stripLiveKeyframe(kf, this._liveKeys)) : void 0;
|
|
1600
1855
|
applyInitial(this.target, initial, scope);
|
|
1601
|
-
applyKeyframes(timeline, this.target, keyframes, this.duration, scope, [],
|
|
1856
|
+
applyKeyframes(timeline, this.target, keyframes, this.duration, scope, [], startTime);
|
|
1602
1857
|
const colorSpace = this.spec.colorSpace ?? "rgb";
|
|
1603
|
-
bindLiveKeyframes(timeline, this._state, this._liveKeys, this.spec.keyframes ?? [], this.duration, scope,
|
|
1604
|
-
const startTime = offset + this.at;
|
|
1858
|
+
bindLiveKeyframes(timeline, this._state, this._liveKeys, this.spec.keyframes ?? [], this.duration, scope, startTime, colorSpace);
|
|
1605
1859
|
this.absoluteStart = startTime;
|
|
1606
1860
|
const endTime = startTime + this.duration;
|
|
1607
1861
|
this.target.renderable = startTime <= 0;
|
|
@@ -1611,8 +1865,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
1611
1865
|
};
|
|
1612
1866
|
function seedGeometry(state, spec, scope) {
|
|
1613
1867
|
const keys = GEOMETRY_KEYS_BY_SHAPE[spec.shape];
|
|
1868
|
+
const initial = spec.initial ?? {};
|
|
1614
1869
|
for (const k of keys) {
|
|
1615
|
-
const v = spec[k];
|
|
1870
|
+
const v = spec[k] ?? initial[k];
|
|
1616
1871
|
if (v !== void 0) state[k] = num(v, scope);
|
|
1617
1872
|
}
|
|
1618
1873
|
}
|
|
@@ -1623,6 +1878,11 @@ function seedStyle(state, initial, scope) {
|
|
|
1623
1878
|
state[k] = COLOR_KEYS.has(k) ? v : numOrZero(v, scope);
|
|
1624
1879
|
}
|
|
1625
1880
|
}
|
|
1881
|
+
function stripGradient(props) {
|
|
1882
|
+
if (!props || !("fillGradient" in props)) return props;
|
|
1883
|
+
const { fillGradient: _drop, ...rest } = props;
|
|
1884
|
+
return rest;
|
|
1885
|
+
}
|
|
1626
1886
|
function stripLive(props, liveKeys) {
|
|
1627
1887
|
if (!props) return props;
|
|
1628
1888
|
const out = {};
|
|
@@ -1661,7 +1921,9 @@ function resolveLiveValue(key, value, scope) {
|
|
|
1661
1921
|
return numOrZero(value, scope);
|
|
1662
1922
|
}
|
|
1663
1923
|
function applyState(g, s) {
|
|
1664
|
-
if (s.
|
|
1924
|
+
if (s.fillStyle) {
|
|
1925
|
+
g.fill(s.fillStyle);
|
|
1926
|
+
} else if (s.fillColor !== void 0) {
|
|
1665
1927
|
g.fill({ color: s.fillColor, alpha: s.fillAlpha });
|
|
1666
1928
|
}
|
|
1667
1929
|
if (s.strokeColor !== void 0 && s.strokeWidth > 0) {
|
|
@@ -1741,14 +2003,16 @@ function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration,
|
|
|
1741
2003
|
const at = offset + resolveAt(kf.at, parentDuration);
|
|
1742
2004
|
const duration = kf.duration ?? 0;
|
|
1743
2005
|
const ease = kf.ease ?? "none";
|
|
2006
|
+
const loop = loopVars(kf);
|
|
1744
2007
|
if (kf.set) {
|
|
1745
2008
|
const live = pickLive(kf.set, liveKeys);
|
|
1746
2009
|
if (live) {
|
|
1747
2010
|
for (const [k, v] of Object.entries(live)) {
|
|
1748
2011
|
const resolved = resolveLiveValue(k, v, scope);
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
2012
|
+
const live2 = state;
|
|
2013
|
+
revertibleSet(timeline, at, () => live2[k], (v2) => {
|
|
2014
|
+
live2[k] = v2;
|
|
2015
|
+
}, resolved);
|
|
1752
2016
|
}
|
|
1753
2017
|
}
|
|
1754
2018
|
}
|
|
@@ -1764,11 +2028,11 @@ function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration,
|
|
|
1764
2028
|
const toRaw = toLive?.[key];
|
|
1765
2029
|
const fromValue = fromRaw !== void 0 ? resolveLiveValue(key, fromRaw, scope) : void 0;
|
|
1766
2030
|
const toValue = toRaw !== void 0 ? resolveLiveValue(key, toRaw, scope) : void 0;
|
|
1767
|
-
tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease, at, colorSpace);
|
|
2031
|
+
tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease, at, colorSpace, loop);
|
|
1768
2032
|
}
|
|
1769
2033
|
}
|
|
1770
2034
|
}
|
|
1771
|
-
function tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease, at, colorSpace) {
|
|
2035
|
+
function tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease, at, colorSpace, loop) {
|
|
1772
2036
|
if (COLOR_KEYS.has(key) && toValue !== void 0) {
|
|
1773
2037
|
tweenColor(
|
|
1774
2038
|
timeline,
|
|
@@ -1779,13 +2043,15 @@ function tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease,
|
|
|
1779
2043
|
duration,
|
|
1780
2044
|
ease,
|
|
1781
2045
|
at,
|
|
1782
|
-
colorSpace
|
|
2046
|
+
colorSpace,
|
|
2047
|
+
void 0,
|
|
2048
|
+
loop
|
|
1783
2049
|
);
|
|
1784
2050
|
} else if (toValue !== void 0) {
|
|
1785
2051
|
if (fromValue !== void 0) {
|
|
1786
|
-
timeline.fromTo(state, { [key]: fromValue }, { [key]: toValue, duration, ease }, at);
|
|
2052
|
+
timeline.fromTo(state, { [key]: fromValue }, { [key]: toValue, duration, ease, ...loop }, at);
|
|
1787
2053
|
} else {
|
|
1788
|
-
timeline.to(state, { [key]: toValue, duration, ease }, at);
|
|
2054
|
+
timeline.to(state, { [key]: toValue, duration, ease, ...loop }, at);
|
|
1789
2055
|
}
|
|
1790
2056
|
}
|
|
1791
2057
|
}
|
|
@@ -1805,7 +2071,7 @@ function numOrZero(v, scope) {
|
|
|
1805
2071
|
var _CompositionSequence = null;
|
|
1806
2072
|
async function getCompositionSequence() {
|
|
1807
2073
|
if (!_CompositionSequence) {
|
|
1808
|
-
_CompositionSequence = (await import('./Composition-
|
|
2074
|
+
_CompositionSequence = (await import('./Composition-RGTRZ2JX.js')).CompositionSequence;
|
|
1809
2075
|
}
|
|
1810
2076
|
return _CompositionSequence;
|
|
1811
2077
|
}
|
|
@@ -1842,6 +2108,6 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
1842
2108
|
return out;
|
|
1843
2109
|
}
|
|
1844
2110
|
|
|
1845
|
-
export { CameraSequence, DEG, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, evaluateExpr, homeCamera, projectLayer, registerSequenceType, resolveAt };
|
|
1846
|
-
//# sourceMappingURL=chunk-
|
|
1847
|
-
//# sourceMappingURL=chunk-
|
|
2111
|
+
export { CameraSequence, DEFAULT_FOV, DEG, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, describeLayer, evaluateExpr, homeCamera, homeDistance, lintText, lintTiming, projectLayer, registerSequenceType, resolveAt, summarizeWarnings };
|
|
2112
|
+
//# sourceMappingURL=chunk-ZQX7WIYL.js.map
|
|
2113
|
+
//# sourceMappingURL=chunk-ZQX7WIYL.js.map
|