pixi-effects 0.18.1 → 0.19.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 +18 -0
- package/README.md +6 -6
- package/ai/CHAT.md +1 -1
- package/ai/SKILL.md +1 -1
- package/ai/chat-template.html +4 -4
- package/ai/reference/cheatsheet.md +4 -4
- package/ai/reference/pitfalls.md +4 -0
- package/ai/reference/recipes.md +65 -0
- package/ai/template.html +5 -5
- package/ai/tools/check.mjs +14 -3
- package/dist/{Base-BQUodYZK.d.ts → Base-B4WbUJO2.d.ts} +1 -1
- package/dist/{Base-OHqp8qvX.d.cts → Base-i88XXaiP.d.cts} +1 -1
- package/dist/Composition-KYNPRWK3.cjs +14 -0
- package/dist/{Composition-6JMXWNVV.cjs.map → Composition-KYNPRWK3.cjs.map} +1 -1
- package/dist/Composition-QBKEEJBV.js +5 -0
- package/dist/{Composition-MLBHYYFF.js.map → Composition-QBKEEJBV.js.map} +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/{Movie-DlHQ9C02.d.ts → Movie-8IrqL3kO.d.ts} +6 -1
- package/dist/{Movie-K2YuVAdg.d.cts → Movie-CpmdNadg.d.cts} +6 -1
- package/dist/Presenter.d.cts +2 -2
- package/dist/Presenter.d.ts +2 -2
- package/dist/{chunk-UXDR3ZDU.js → chunk-B3YB2TNY.js} +4 -3
- package/dist/chunk-B3YB2TNY.js.map +1 -0
- package/dist/{chunk-JW67MDHQ.cjs → chunk-CTZRFSVU.cjs} +27 -26
- package/dist/chunk-CTZRFSVU.cjs.map +1 -0
- package/dist/{chunk-ANO5R2E6.cjs → chunk-VTBT6NNE.cjs} +755 -48
- package/dist/chunk-VTBT6NNE.cjs.map +1 -0
- package/dist/{chunk-SG3Y66FN.js → chunk-YRXTKOV5.js} +757 -51
- package/dist/chunk-YRXTKOV5.js.map +1 -0
- package/dist/index.cjs +63 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +40 -13
- package/dist/index.js.map +1 -1
- package/dist/loader.css +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-SS51lP6O.d.cts → types-bzLJ7aUx.d.cts} +16 -6
- package/dist/{types-SS51lP6O.d.ts → types-bzLJ7aUx.d.ts} +16 -6
- package/docs/dsl.md +36 -5
- package/llms-full.txt +110 -10
- package/package.json +1 -1
- package/dist/Composition-6JMXWNVV.cjs +0 -14
- package/dist/Composition-MLBHYYFF.js +0 -5
- package/dist/chunk-ANO5R2E6.cjs.map +0 -1
- package/dist/chunk-JW67MDHQ.cjs.map +0 -1
- package/dist/chunk-SG3Y66FN.js.map +0 -1
- package/dist/chunk-UXDR3ZDU.js.map +0 -1
|
@@ -58,6 +58,113 @@ function noise(x, seed = 0) {
|
|
|
58
58
|
const u = f * f * f * (f * (f * 6 - 15) + 10);
|
|
59
59
|
return a + (b - a) * u;
|
|
60
60
|
}
|
|
61
|
+
var SETTLE_TOL = 5e-3;
|
|
62
|
+
var DEFAULTS = { mass: 1, stiffness: 100, damping: 10 };
|
|
63
|
+
function springResponse(t, { mass: m, stiffness: k, damping: c }) {
|
|
64
|
+
if (t <= 0) return 0;
|
|
65
|
+
const w0 = Math.sqrt(k / m);
|
|
66
|
+
const zeta = c / (2 * Math.sqrt(k * m));
|
|
67
|
+
if (Math.abs(zeta - 1) < 1e-6) return 1 - Math.exp(-w0 * t) * (1 + w0 * t);
|
|
68
|
+
if (zeta < 1) {
|
|
69
|
+
const wd = w0 * Math.sqrt(1 - zeta * zeta);
|
|
70
|
+
return 1 - Math.exp(-zeta * w0 * t) * (Math.cos(wd * t) + zeta * w0 / wd * Math.sin(wd * t));
|
|
71
|
+
}
|
|
72
|
+
const s = w0 * Math.sqrt(zeta * zeta - 1);
|
|
73
|
+
const r1 = -zeta * w0 + s, r2 = -zeta * w0 - s;
|
|
74
|
+
return 1 - (r2 * Math.exp(r1 * t) - r1 * Math.exp(r2 * t)) / (r2 - r1);
|
|
75
|
+
}
|
|
76
|
+
function complete(p) {
|
|
77
|
+
return { mass: p.mass ?? DEFAULTS.mass, stiffness: p.stiffness ?? DEFAULTS.stiffness, damping: p.damping ?? DEFAULTS.damping };
|
|
78
|
+
}
|
|
79
|
+
function springDuration(params = {}, tol = SETTLE_TOL) {
|
|
80
|
+
const p = complete(params);
|
|
81
|
+
const w0 = Math.sqrt(p.stiffness / p.mass);
|
|
82
|
+
const zeta = p.damping / (2 * Math.sqrt(p.stiffness * p.mass));
|
|
83
|
+
const bad = (t) => Math.abs(1 - springResponse(t, p)) > tol;
|
|
84
|
+
let lo, hi;
|
|
85
|
+
if (zeta < 1 - 1e-6) {
|
|
86
|
+
const wd = w0 * Math.sqrt(1 - zeta * zeta);
|
|
87
|
+
const decay = Math.PI * zeta / Math.sqrt(1 - zeta * zeta);
|
|
88
|
+
const n = Math.max(1, Math.ceil(Math.log(1 / tol) / decay));
|
|
89
|
+
lo = (n - 1) * Math.PI / wd;
|
|
90
|
+
hi = n * Math.PI / wd;
|
|
91
|
+
} else {
|
|
92
|
+
lo = 0;
|
|
93
|
+
hi = 1 / w0;
|
|
94
|
+
while (bad(hi)) {
|
|
95
|
+
lo = hi;
|
|
96
|
+
hi *= 2;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (let i = 0; i < 60; i++) {
|
|
100
|
+
const mid = (lo + hi) / 2;
|
|
101
|
+
if (bad(mid)) lo = mid;
|
|
102
|
+
else hi = mid;
|
|
103
|
+
}
|
|
104
|
+
return hi;
|
|
105
|
+
}
|
|
106
|
+
function springEase(params = {}) {
|
|
107
|
+
const sp = complete(params);
|
|
108
|
+
const T = springDuration(sp);
|
|
109
|
+
const end = springResponse(T, sp);
|
|
110
|
+
return (p) => p <= 0 ? 0 : p >= 1 ? 1 : springResponse(p * T, sp) / end;
|
|
111
|
+
}
|
|
112
|
+
var SPRING_PRESETS = {
|
|
113
|
+
gentle: { mass: 1, stiffness: 100, damping: 15 },
|
|
114
|
+
// zeta .75, one soft overshoot
|
|
115
|
+
snappy: { mass: 1, stiffness: 300, damping: 28 },
|
|
116
|
+
// zeta .81, quick, barely rings
|
|
117
|
+
bouncy: { mass: 1, stiffness: 170, damping: 10 },
|
|
118
|
+
// zeta .38
|
|
119
|
+
wobbly: { mass: 1, stiffness: 120, damping: 6 },
|
|
120
|
+
// zeta .27, rings several times
|
|
121
|
+
slow: { mass: 1, stiffness: 60, damping: 18 }
|
|
122
|
+
// zeta 1.16, no overshoot
|
|
123
|
+
};
|
|
124
|
+
var SPRING_RE = /^spring(?:\.(\w+)|\(([^)]*)\))?$/;
|
|
125
|
+
function springProblem(name) {
|
|
126
|
+
const m = SPRING_RE.exec(name.trim());
|
|
127
|
+
if (!m) return 'expected "spring(mass, stiffness, damping)" or "spring.<preset>"';
|
|
128
|
+
if (m[1] && !SPRING_PRESETS[m[1]]) return `no preset "${m[1]}" (presets: ${Object.keys(SPRING_PRESETS).join(", ")})`;
|
|
129
|
+
if (m[2] !== void 0 && m[2].trim() !== "") {
|
|
130
|
+
const nums = m[2].split(",").map((s) => Number(s.trim()));
|
|
131
|
+
if (nums.length > 3 || nums.some((n) => !Number.isFinite(n) || n <= 0)) return "mass, stiffness and damping must be 1 to 3 numbers greater than 0";
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
function parseSpring(name) {
|
|
136
|
+
if (typeof name !== "string" || !/^\s*spring/.test(name) || springProblem(name)) return null;
|
|
137
|
+
const m = SPRING_RE.exec(name.trim());
|
|
138
|
+
if (m[1]) return SPRING_PRESETS[m[1]];
|
|
139
|
+
const [mass, stiffness, damping] = (m[2] ?? "").split(",").map((s) => s.trim()).filter(Boolean).map(Number);
|
|
140
|
+
return complete({ mass, stiffness, damping });
|
|
141
|
+
}
|
|
142
|
+
var registered = false;
|
|
143
|
+
function registerSpringEases() {
|
|
144
|
+
if (registered) return;
|
|
145
|
+
registered = true;
|
|
146
|
+
const base = springEase();
|
|
147
|
+
const ease = (p) => base(p);
|
|
148
|
+
ease.config = (mass, stiffness, damping) => {
|
|
149
|
+
const bad = [mass, stiffness, damping].some((v) => v !== void 0 && !(typeof v === "number" && v > 0 && Number.isFinite(v)));
|
|
150
|
+
return springEase(bad ? {} : { mass, stiffness, damping });
|
|
151
|
+
};
|
|
152
|
+
gsap.gsap.registerEase("spring", ease);
|
|
153
|
+
for (const [name, p] of Object.entries(SPRING_PRESETS)) gsap.gsap.registerEase(`spring.${name}`, springEase(p));
|
|
154
|
+
}
|
|
155
|
+
var autoWarned = /* @__PURE__ */ new Set();
|
|
156
|
+
function kfDuration(kf) {
|
|
157
|
+
if (kf.duration !== "auto") return kf.duration ?? 0;
|
|
158
|
+
const sp = parseSpring(kf.ease);
|
|
159
|
+
if (sp) return Math.round(springDuration(sp) * 1e3) / 1e3;
|
|
160
|
+
const name = String(kf.ease ?? "none");
|
|
161
|
+
if (!/^\s*spring/.test(name) && !autoWarned.has(name)) {
|
|
162
|
+
autoWarned.add(name);
|
|
163
|
+
console.warn(`pixi-effects: keyframe duration 'auto' needs a spring ease (ease: 'spring(1, 170, 12)' or 'spring.bouncy'), got ease ${JSON.stringify(name)} \u2014 using 0.5 s.`);
|
|
164
|
+
}
|
|
165
|
+
return 0.5;
|
|
166
|
+
}
|
|
167
|
+
registerSpringEases();
|
|
61
168
|
|
|
62
169
|
// src/expr/Parser.ts
|
|
63
170
|
var FUNCS = {
|
|
@@ -315,6 +422,13 @@ var EASE_NAMES = ["none", ...FAMILIES.flatMap((f) => [`${f}.in`, `${f}.out`, `${
|
|
|
315
422
|
var warned = /* @__PURE__ */ new Set();
|
|
316
423
|
function checkEase(ease, where) {
|
|
317
424
|
if (typeof ease !== "string") return;
|
|
425
|
+
if (/^\s*spring/.test(ease)) {
|
|
426
|
+
const problem = springProblem(ease);
|
|
427
|
+
if (!problem || warned.has(ease)) return;
|
|
428
|
+
warned.add(ease);
|
|
429
|
+
console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. GSAP would run it as its default ease, power1.out.`);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
318
432
|
const found = gsap.gsap.parseEase(ease);
|
|
319
433
|
if (typeof found === "function") return;
|
|
320
434
|
if (warned.has(ease)) return;
|
|
@@ -355,7 +469,7 @@ function resolveAt(at, duration) {
|
|
|
355
469
|
}
|
|
356
470
|
function normalizeKeyframe(kf, parentDuration) {
|
|
357
471
|
const at = resolveAt(kf.at, parentDuration);
|
|
358
|
-
const duration = kf
|
|
472
|
+
const duration = kfDuration(kf);
|
|
359
473
|
const ease = kf.ease ?? "none";
|
|
360
474
|
checkEase(ease, "a keyframe");
|
|
361
475
|
const hasSet = !!kf.set;
|
|
@@ -785,8 +899,217 @@ var ChromaKeyFilter = class extends PIXI.Filter {
|
|
|
785
899
|
u[2] = rgb[2];
|
|
786
900
|
}
|
|
787
901
|
};
|
|
902
|
+
var HASH_GL = `
|
|
903
|
+
uint hash(uint x) { x ^= x >> 16; x *= 0x7feb352du; x ^= x >> 15; x *= 0x846ca68bu; x ^= x >> 16; return x; }
|
|
904
|
+
// one gaussian-ish value (sum of the four bytes of a hash), mean 0, std 1
|
|
905
|
+
float gauss(ivec2 p, uint k) {
|
|
906
|
+
uint h = hash(uint(p.x) + hash(uint(p.y) + hash(k)));
|
|
907
|
+
float s = float(h & 255u) + float((h >> 8) & 255u) + float((h >> 16) & 255u) + float(h >> 24);
|
|
908
|
+
return (s / 255.0 - 2.0) * 1.7320508;
|
|
909
|
+
}
|
|
910
|
+
// the grain value at a pixel: cells of size pixels, smoothly blended
|
|
911
|
+
float cell(vec2 pos, float size, uint k) {
|
|
912
|
+
vec2 q = pos / size - 0.5;
|
|
913
|
+
vec2 i = floor(q);
|
|
914
|
+
vec2 f = fract(q);
|
|
915
|
+
ivec2 p = ivec2(i);
|
|
916
|
+
float a = gauss(p, k), b = gauss(p + ivec2(1, 0), k), c = gauss(p + ivec2(0, 1), k), d = gauss(p + ivec2(1, 1), k);
|
|
917
|
+
float v = mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
918
|
+
vec2 wx = vec2(1.0 - f.x, f.x), wy = vec2(1.0 - f.y, f.y);
|
|
919
|
+
return v * inversesqrt(dot(wx, wx) * dot(wy, wy)); // blending lowers the spread: keep std exactly 1 at every pixel
|
|
920
|
+
}`;
|
|
921
|
+
var GL_VERTEX = `#version 300 es
|
|
922
|
+
in vec2 aPosition;
|
|
923
|
+
out vec2 vTextureCoord;
|
|
924
|
+
uniform vec4 uInputSize;
|
|
925
|
+
uniform vec4 uOutputFrame;
|
|
926
|
+
uniform vec4 uOutputTexture;
|
|
927
|
+
void main(void) {
|
|
928
|
+
vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
|
|
929
|
+
position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
|
|
930
|
+
position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
|
|
931
|
+
gl_Position = vec4(position, 0.0, 1.0);
|
|
932
|
+
vTextureCoord = aPosition * (uOutputFrame.zw * uInputSize.zw);
|
|
933
|
+
}`;
|
|
934
|
+
var GL_FRAGMENT2 = `#version 300 es
|
|
935
|
+
precision highp float;
|
|
936
|
+
precision highp int;
|
|
937
|
+
in vec2 vTextureCoord;
|
|
938
|
+
uniform sampler2D uTexture;
|
|
939
|
+
uniform vec4 uInputSize;
|
|
940
|
+
uniform float uAmount;
|
|
941
|
+
uniform float uSize;
|
|
942
|
+
uniform float uSeed;
|
|
943
|
+
uniform float uFrame;
|
|
944
|
+
uniform float uColor;
|
|
945
|
+
out vec4 finalColor;
|
|
946
|
+
${HASH_GL}
|
|
947
|
+
void main(void) {
|
|
948
|
+
vec4 raw = texture(uTexture, vTextureCoord);
|
|
949
|
+
vec3 rgb = raw.a > 0.0 ? raw.rgb / raw.a : vec3(0.0);
|
|
950
|
+
float L = dot(rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
951
|
+
float w = clamp(4.0 * L * (1.0 - L), 0.0, 1.0);
|
|
952
|
+
vec2 pos = vTextureCoord * uInputSize.xy;
|
|
953
|
+
uint k = hash(uint(uSeed) * 0x9E3779B1u + uint(uFrame));
|
|
954
|
+
float n0 = cell(pos, uSize, k);
|
|
955
|
+
vec3 n = vec3(n0);
|
|
956
|
+
if (uColor > 0.0) {
|
|
957
|
+
vec3 nc = vec3(cell(pos, uSize, k + 1u), cell(pos, uSize, k + 2u), cell(pos, uSize, k + 3u));
|
|
958
|
+
n = mix(n, nc, uColor);
|
|
959
|
+
}
|
|
960
|
+
rgb = clamp(rgb + n * (uAmount * w), 0.0, 1.0);
|
|
961
|
+
finalColor = vec4(rgb * raw.a, raw.a);
|
|
962
|
+
}`;
|
|
963
|
+
var WGSL_SOURCE2 = `
|
|
964
|
+
struct GlobalFilterUniforms {
|
|
965
|
+
uInputSize: vec4<f32>,
|
|
966
|
+
uInputPixel: vec4<f32>,
|
|
967
|
+
uInputClamp: vec4<f32>,
|
|
968
|
+
uOutputFrame: vec4<f32>,
|
|
969
|
+
uGlobalFrame: vec4<f32>,
|
|
970
|
+
uOutputTexture: vec4<f32>,
|
|
971
|
+
};
|
|
972
|
+
struct GrainUniforms {
|
|
973
|
+
uAmount: f32,
|
|
974
|
+
uSize: f32,
|
|
975
|
+
uSeed: f32,
|
|
976
|
+
uFrame: f32,
|
|
977
|
+
uColor: f32,
|
|
978
|
+
};
|
|
979
|
+
@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;
|
|
980
|
+
@group(0) @binding(1) var uTexture: texture_2d<f32>;
|
|
981
|
+
@group(0) @binding(2) var uSampler : sampler;
|
|
982
|
+
@group(1) @binding(0) var<uniform> grainUniforms : GrainUniforms;
|
|
983
|
+
|
|
984
|
+
struct VSOutput {
|
|
985
|
+
@builtin(position) position: vec4<f32>,
|
|
986
|
+
@location(0) uv : vec2<f32>,
|
|
987
|
+
};
|
|
988
|
+
fn filterVertexPosition(aPosition : vec2<f32>) -> vec4<f32> {
|
|
989
|
+
var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;
|
|
990
|
+
position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;
|
|
991
|
+
position.y = position.y * (2.0 * gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;
|
|
992
|
+
return vec4<f32>(position, 0.0, 1.0);
|
|
993
|
+
}
|
|
994
|
+
fn filterTextureCoord(aPosition : vec2<f32>) -> vec2<f32> {
|
|
995
|
+
return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);
|
|
996
|
+
}
|
|
997
|
+
@vertex
|
|
998
|
+
fn mainVertex(
|
|
999
|
+
@location(0) aPosition : vec2<f32>,
|
|
1000
|
+
) -> VSOutput {
|
|
1001
|
+
return VSOutput(
|
|
1002
|
+
filterVertexPosition(aPosition),
|
|
1003
|
+
filterTextureCoord(aPosition),
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
fn hash(xIn: u32) -> u32 {
|
|
1008
|
+
var x = xIn;
|
|
1009
|
+
x = x ^ (x >> 16u); x = x * 0x7feb352du; x = x ^ (x >> 15u); x = x * 0x846ca68bu; x = x ^ (x >> 16u);
|
|
1010
|
+
return x;
|
|
1011
|
+
}
|
|
1012
|
+
fn gauss(p: vec2<i32>, k: u32) -> f32 {
|
|
1013
|
+
let h = hash(u32(p.x) + hash(u32(p.y) + hash(k)));
|
|
1014
|
+
let s = f32(h & 255u) + f32((h >> 8u) & 255u) + f32((h >> 16u) & 255u) + f32(h >> 24u);
|
|
1015
|
+
return (s / 255.0 - 2.0) * 1.7320508;
|
|
1016
|
+
}
|
|
1017
|
+
fn cell(pos: vec2<f32>, size: f32, k: u32) -> f32 {
|
|
1018
|
+
let q = pos / size - vec2<f32>(0.5);
|
|
1019
|
+
let i = floor(q);
|
|
1020
|
+
let f = fract(q);
|
|
1021
|
+
let p = vec2<i32>(i);
|
|
1022
|
+
let a = gauss(p, k);
|
|
1023
|
+
let b = gauss(p + vec2<i32>(1, 0), k);
|
|
1024
|
+
let c = gauss(p + vec2<i32>(0, 1), k);
|
|
1025
|
+
let d = gauss(p + vec2<i32>(1, 1), k);
|
|
1026
|
+
let v = mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
1027
|
+
let wx = vec2<f32>(1.0 - f.x, f.x);
|
|
1028
|
+
let wy = vec2<f32>(1.0 - f.y, f.y);
|
|
1029
|
+
return v * inverseSqrt(dot(wx, wx) * dot(wy, wy));
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
@fragment
|
|
1033
|
+
fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
1034
|
+
let raw = textureSample(uTexture, uSampler, uv);
|
|
1035
|
+
var rgb = vec3<f32>(0.0);
|
|
1036
|
+
if (raw.a > 0.0) { rgb = raw.rgb / raw.a; }
|
|
1037
|
+
let L = dot(rgb, vec3<f32>(0.2126, 0.7152, 0.0722));
|
|
1038
|
+
let w = clamp(4.0 * L * (1.0 - L), 0.0, 1.0);
|
|
1039
|
+
let pos = uv * gfu.uInputSize.xy;
|
|
1040
|
+
let k = hash(u32(grainUniforms.uSeed) * 0x9E3779B1u + u32(grainUniforms.uFrame));
|
|
1041
|
+
let n0 = cell(pos, grainUniforms.uSize, k);
|
|
1042
|
+
var n = vec3<f32>(n0);
|
|
1043
|
+
if (grainUniforms.uColor > 0.0) {
|
|
1044
|
+
let nc = vec3<f32>(cell(pos, grainUniforms.uSize, k + 1u), cell(pos, grainUniforms.uSize, k + 2u), cell(pos, grainUniforms.uSize, k + 3u));
|
|
1045
|
+
n = mix(n, nc, grainUniforms.uColor);
|
|
1046
|
+
}
|
|
1047
|
+
rgb = clamp(rgb + n * (grainUniforms.uAmount * w), vec3<f32>(0.0), vec3<f32>(1.0));
|
|
1048
|
+
return vec4<f32>(rgb * raw.a, raw.a);
|
|
1049
|
+
}`;
|
|
1050
|
+
var GRAIN_KEYS = ["amount", "size", "seed", "fps", "color"];
|
|
1051
|
+
var GrainFilter = class extends PIXI.Filter {
|
|
1052
|
+
_fps;
|
|
1053
|
+
constructor(options = {}) {
|
|
1054
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("grain filter", options, GRAIN_KEYS);
|
|
1055
|
+
const { amount = 0.08, size = 1.5, seed = 0, fps = 24, color = 0 } = options;
|
|
1056
|
+
super({
|
|
1057
|
+
glProgram: PIXI.GlProgram.from({ vertex: GL_VERTEX, fragment: GL_FRAGMENT2, name: "grain-filter" }),
|
|
1058
|
+
gpuProgram: PIXI.GpuProgram.from({ vertex: { source: WGSL_SOURCE2, entryPoint: "mainVertex" }, fragment: { source: WGSL_SOURCE2, entryPoint: "mainFragment" } }),
|
|
1059
|
+
resources: {
|
|
1060
|
+
grainUniforms: new PIXI.UniformGroup({
|
|
1061
|
+
uAmount: { value: amount, type: "f32" },
|
|
1062
|
+
uSize: { value: Math.max(size, 0.25), type: "f32" },
|
|
1063
|
+
uSeed: { value: Math.floor(seed), type: "f32" },
|
|
1064
|
+
uFrame: { value: 0, type: "f32" },
|
|
1065
|
+
uColor: { value: color, type: "f32" }
|
|
1066
|
+
})
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
this._fps = fps;
|
|
1070
|
+
}
|
|
1071
|
+
get u() {
|
|
1072
|
+
return this.resources.grainUniforms.uniforms;
|
|
1073
|
+
}
|
|
1074
|
+
get amount() {
|
|
1075
|
+
return this.u.uAmount;
|
|
1076
|
+
}
|
|
1077
|
+
set amount(v) {
|
|
1078
|
+
this.u.uAmount = v;
|
|
1079
|
+
}
|
|
1080
|
+
get size() {
|
|
1081
|
+
return this.u.uSize;
|
|
1082
|
+
}
|
|
1083
|
+
set size(v) {
|
|
1084
|
+
this.u.uSize = Math.max(v, 0.25);
|
|
1085
|
+
}
|
|
1086
|
+
get seed() {
|
|
1087
|
+
return this.u.uSeed;
|
|
1088
|
+
}
|
|
1089
|
+
set seed(v) {
|
|
1090
|
+
this.u.uSeed = Math.floor(v);
|
|
1091
|
+
}
|
|
1092
|
+
get color() {
|
|
1093
|
+
return this.u.uColor;
|
|
1094
|
+
}
|
|
1095
|
+
set color(v) {
|
|
1096
|
+
this.u.uColor = v;
|
|
1097
|
+
}
|
|
1098
|
+
get fps() {
|
|
1099
|
+
return this._fps;
|
|
1100
|
+
}
|
|
1101
|
+
set fps(v) {
|
|
1102
|
+
this._fps = v;
|
|
1103
|
+
}
|
|
1104
|
+
/** The movie calls this with the time (s) of the frame it is about to draw: the grain is new every 1/fps s. */
|
|
1105
|
+
setTime(t) {
|
|
1106
|
+
this.u.uFrame = this._fps > 0 ? Math.floor(t * this._fps + 1e-6) : 0;
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
// src/filters/named.ts
|
|
788
1111
|
var CORE = { blur: "BlurFilter", noise: "NoiseFilter", alpha: "AlphaFilter" };
|
|
789
|
-
var CORE_TYPES = [...Object.keys(CORE), "colorMatrix"];
|
|
1112
|
+
var CORE_TYPES = [...Object.keys(CORE), "colorMatrix", "grain"];
|
|
790
1113
|
var LIBRARY_TYPES = [
|
|
791
1114
|
"adjustment",
|
|
792
1115
|
"advancedBloom",
|
|
@@ -903,6 +1226,7 @@ function colorGradientParams(params) {
|
|
|
903
1226
|
}
|
|
904
1227
|
function createNamedFilter(type, params) {
|
|
905
1228
|
if (lower(type) === "colormatrix") return colorMatrix(params);
|
|
1229
|
+
if (lower(type) === "grain") return new GrainFilter(params);
|
|
906
1230
|
const core = Object.entries(CORE).find(([k]) => lower(k) === lower(type));
|
|
907
1231
|
if (core) return new PIXI__namespace[core[1]](params);
|
|
908
1232
|
if (!isLibraryType(type)) throw unknownType(type);
|
|
@@ -1051,6 +1375,140 @@ function collectPropKeys(spec) {
|
|
|
1051
1375
|
return out;
|
|
1052
1376
|
}
|
|
1053
1377
|
|
|
1378
|
+
// src/core/layerKeys.ts
|
|
1379
|
+
var COMMON = ["type", "name", "parent", "at", "duration", "initial", "keyframes", "filters", "filterArea", "mask", "maskInverted", "blendMode", "threeD", "hideBehindCamera"];
|
|
1380
|
+
var VIDEO = [...COMMON, "asset", "loop", "audio", "volume"];
|
|
1381
|
+
var IMAGE = [...COMMON, "asset", "colorSpace"];
|
|
1382
|
+
var TEXT = [...COMMON, "text", "format", "style", "colorSpace", "fillGradient"];
|
|
1383
|
+
var AUDIO = [...COMMON, "volume", "asset", "loop", "sfx", "music"];
|
|
1384
|
+
var COMPOSITION = [...COMMON, "width", "height", "sequences", "transitions"];
|
|
1385
|
+
var CAMERA = [...COMMON];
|
|
1386
|
+
var NULL = [...COMMON];
|
|
1387
|
+
var SHAPE = [...COMMON, "shape", "fillGradient", "colorSpace", "strokeCap", "strokeJoin"];
|
|
1388
|
+
var TRIM = ["trimStart", "trimEnd", "trimEach"];
|
|
1389
|
+
var RECT = [...SHAPE, ...TRIM, "width", "height", "cornerRadius", "anchorX", "anchorY"];
|
|
1390
|
+
var CIRCLE = [...SHAPE, ...TRIM, "radius", "anchorX", "anchorY"];
|
|
1391
|
+
var ELLIPSE = [...SHAPE, ...TRIM, "radiusX", "radiusY", "anchorX", "anchorY"];
|
|
1392
|
+
var ARC = [...SHAPE, "radius", "innerRadius", "startAngle", "endAngle"];
|
|
1393
|
+
var LINE = [...SHAPE, ...TRIM, "from", "to"];
|
|
1394
|
+
var POLYGON = [...SHAPE, ...TRIM, "points", "open"];
|
|
1395
|
+
var PATH = [...SHAPE, ...TRIM, "d", "morphTo", "morph", "morphPoints"];
|
|
1396
|
+
var SHAPES = { rect: RECT, circle: CIRCLE, ellipse: ELLIPSE, arc: ARC, line: LINE, polygon: POLYGON, path: PATH };
|
|
1397
|
+
var BY_TYPE = { video: VIDEO, image: IMAGE, text: TEXT, audio: AUDIO, composition: COMPOSITION, camera: CAMERA, null: NULL };
|
|
1398
|
+
function kindName(spec) {
|
|
1399
|
+
return spec.type === "shape" && spec.shape ? `${spec.shape} shape` : `${spec.type} layer`;
|
|
1400
|
+
}
|
|
1401
|
+
function layerKeys(spec) {
|
|
1402
|
+
if (spec.type === "shape") return spec.shape && SHAPES[spec.shape] || null;
|
|
1403
|
+
return BY_TYPE[spec.type] ?? null;
|
|
1404
|
+
}
|
|
1405
|
+
function kindsWithKey(key) {
|
|
1406
|
+
const out = [];
|
|
1407
|
+
for (const [shape, keys] of Object.entries(SHAPES)) if (keys.includes(key)) out.push(`${shape} shape`);
|
|
1408
|
+
for (const [type, keys] of Object.entries(BY_TYPE)) if (keys.includes(key)) out.push(`${type} layer`);
|
|
1409
|
+
return out;
|
|
1410
|
+
}
|
|
1411
|
+
var PROP_KEYS = /* @__PURE__ */ new Set([
|
|
1412
|
+
// transform and look (GSAP + PixiPlugin names)
|
|
1413
|
+
"x",
|
|
1414
|
+
"y",
|
|
1415
|
+
"z",
|
|
1416
|
+
"alpha",
|
|
1417
|
+
"rotation",
|
|
1418
|
+
"rotationX",
|
|
1419
|
+
"rotationY",
|
|
1420
|
+
"width",
|
|
1421
|
+
"height",
|
|
1422
|
+
"visible",
|
|
1423
|
+
"autoAlpha",
|
|
1424
|
+
"scale",
|
|
1425
|
+
"scaleX",
|
|
1426
|
+
"scaleY",
|
|
1427
|
+
"anchor",
|
|
1428
|
+
"anchorX",
|
|
1429
|
+
"anchorY",
|
|
1430
|
+
"pivot",
|
|
1431
|
+
"pivotX",
|
|
1432
|
+
"pivotY",
|
|
1433
|
+
"skew",
|
|
1434
|
+
"skewX",
|
|
1435
|
+
"skewY",
|
|
1436
|
+
"position",
|
|
1437
|
+
"positionX",
|
|
1438
|
+
"positionY",
|
|
1439
|
+
"tint",
|
|
1440
|
+
"colorize",
|
|
1441
|
+
"colorizeAmount",
|
|
1442
|
+
"blur",
|
|
1443
|
+
"blurX",
|
|
1444
|
+
"blurY",
|
|
1445
|
+
"blurPadding",
|
|
1446
|
+
// shapes
|
|
1447
|
+
"fillColor",
|
|
1448
|
+
"fillAlpha",
|
|
1449
|
+
"strokeColor",
|
|
1450
|
+
"strokeAlpha",
|
|
1451
|
+
"strokeWidth",
|
|
1452
|
+
"lineColor",
|
|
1453
|
+
"lineAlpha",
|
|
1454
|
+
"cornerRadius",
|
|
1455
|
+
"radius",
|
|
1456
|
+
"radiusX",
|
|
1457
|
+
"radiusY",
|
|
1458
|
+
"innerRadius",
|
|
1459
|
+
"startAngle",
|
|
1460
|
+
"endAngle",
|
|
1461
|
+
"trimStart",
|
|
1462
|
+
"trimEnd",
|
|
1463
|
+
"trimEach",
|
|
1464
|
+
"morph",
|
|
1465
|
+
"fillGradient",
|
|
1466
|
+
"strokeCap",
|
|
1467
|
+
"strokeJoin",
|
|
1468
|
+
// text, audio, video
|
|
1469
|
+
"fill",
|
|
1470
|
+
"value",
|
|
1471
|
+
"visibleChars",
|
|
1472
|
+
"text",
|
|
1473
|
+
"volume",
|
|
1474
|
+
// camera
|
|
1475
|
+
"lookAtX",
|
|
1476
|
+
"lookAtY",
|
|
1477
|
+
"lookAtZ",
|
|
1478
|
+
"fov",
|
|
1479
|
+
"offsetX",
|
|
1480
|
+
"offsetY",
|
|
1481
|
+
"offsetZ",
|
|
1482
|
+
"lookOffsetX",
|
|
1483
|
+
"lookOffsetY",
|
|
1484
|
+
"lookOffsetZ"
|
|
1485
|
+
]);
|
|
1486
|
+
var STYLE_KEYS = [
|
|
1487
|
+
"fontSize",
|
|
1488
|
+
"fontFamily",
|
|
1489
|
+
"fontWeight",
|
|
1490
|
+
"fontStyle",
|
|
1491
|
+
"fontVariant",
|
|
1492
|
+
"fill",
|
|
1493
|
+
"stroke",
|
|
1494
|
+
"dropShadow",
|
|
1495
|
+
"letterSpacing",
|
|
1496
|
+
"lineHeight",
|
|
1497
|
+
"leading",
|
|
1498
|
+
"align",
|
|
1499
|
+
"wordWrap",
|
|
1500
|
+
"wordWrapWidth",
|
|
1501
|
+
"breakWords",
|
|
1502
|
+
"whiteSpace",
|
|
1503
|
+
"padding",
|
|
1504
|
+
"textBaseline",
|
|
1505
|
+
"trim",
|
|
1506
|
+
"lineJoin",
|
|
1507
|
+
"miterLimit",
|
|
1508
|
+
"filters",
|
|
1509
|
+
"tagStyles"
|
|
1510
|
+
];
|
|
1511
|
+
|
|
1054
1512
|
// src/core/lint.ts
|
|
1055
1513
|
var defaultWarn = (m) => console.warn(m);
|
|
1056
1514
|
function describeLayer(spec) {
|
|
@@ -1089,6 +1547,38 @@ function lintText(spec, warn = defaultWarn) {
|
|
|
1089
1547
|
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').`);
|
|
1090
1548
|
}
|
|
1091
1549
|
}
|
|
1550
|
+
function lintKeys(spec, warn = defaultWarn) {
|
|
1551
|
+
const who = describeLayer(spec);
|
|
1552
|
+
const valid = layerKeys(spec);
|
|
1553
|
+
if (valid) {
|
|
1554
|
+
for (const key of Object.keys(spec)) {
|
|
1555
|
+
if (valid.includes(key) || spec[key] === void 0) continue;
|
|
1556
|
+
const guess = chunkUQBGW5DO_cjs.suggestName(key, valid.filter((k) => k !== "type"));
|
|
1557
|
+
const owners = kindsWithKey(key);
|
|
1558
|
+
const belongs = owners.length ? ` (it belongs to ${owners.slice(0, 3).join(", ")})` : "";
|
|
1559
|
+
const hint = guess ? ` \u2014 did you mean "${guess}"?${belongs}` : belongs;
|
|
1560
|
+
warn(`pixi-effects: ${who}: "${key}" is not a ${kindName(spec)} key${hint}. Valid keys: ${valid.join(", ")}`);
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
const said = /* @__PURE__ */ new Set();
|
|
1564
|
+
const bags = [spec.initial, ...(spec.keyframes ?? []).flatMap((kf) => [kf.set, kf.to, kf.from])];
|
|
1565
|
+
for (const bag of bags) {
|
|
1566
|
+
for (const key of Object.keys(bag ?? {})) {
|
|
1567
|
+
if (bag[key] === void 0) continue;
|
|
1568
|
+
if (PROP_KEYS.has(key) || key.includes(".") || /^gradient/i.test(key) || said.has(key)) continue;
|
|
1569
|
+
said.add(key);
|
|
1570
|
+
const guess = chunkUQBGW5DO_cjs.suggestName(key, [...PROP_KEYS]);
|
|
1571
|
+
warn(`pixi-effects: ${who}: "${key}" is not an animatable property${guess ? ` \u2014 did you mean "${guess}"?` : ""} (in initial, set, to or from). See the cheatsheet for the properties of this kind of layer`);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
if (spec.type === "text" && spec.style && typeof spec.style === "object") {
|
|
1575
|
+
for (const key of Object.keys(spec.style)) {
|
|
1576
|
+
if (STYLE_KEYS.includes(key) || spec.style[key] === void 0) continue;
|
|
1577
|
+
const guess = chunkUQBGW5DO_cjs.suggestName(key, STYLE_KEYS);
|
|
1578
|
+
warn(`pixi-effects: ${who}: style.${key} is not a text style key${guess ? ` \u2014 did you mean "${guess}"?` : ""} (it is ignored). Keys: ${STYLE_KEYS.join(", ")}`);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1092
1582
|
|
|
1093
1583
|
// src/space/math.ts
|
|
1094
1584
|
var DEG = Math.PI / 180;
|
|
@@ -1414,6 +1904,7 @@ function shortestHueDelta(from, to) {
|
|
|
1414
1904
|
}
|
|
1415
1905
|
|
|
1416
1906
|
// src/expr/colorTween.ts
|
|
1907
|
+
var css = (c) => typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
|
|
1417
1908
|
function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, at, colorSpace, onUpdate, loop = {}) {
|
|
1418
1909
|
let interp = null;
|
|
1419
1910
|
const proxy = { p: 0 };
|
|
@@ -1428,7 +1919,7 @@ function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, a
|
|
|
1428
1919
|
onStart: () => {
|
|
1429
1920
|
const start = fromValue !== void 0 ? fromValue : target[key];
|
|
1430
1921
|
if (start === void 0) return;
|
|
1431
|
-
interp = colorSpace === "rgb" ? gsap.gsap.utils.interpolate(start, toValue) : buildColorInterp(start, toValue, colorSpace);
|
|
1922
|
+
interp = colorSpace === "rgb" ? gsap.gsap.utils.interpolate(css(start), css(toValue)) : buildColorInterp(start, toValue, colorSpace);
|
|
1432
1923
|
},
|
|
1433
1924
|
onUpdate: () => {
|
|
1434
1925
|
if (interp) {
|
|
@@ -1472,7 +1963,7 @@ var ImageSequence = class extends Sequence {
|
|
|
1472
1963
|
if (initTint !== void 0) this.target.tint = initTint;
|
|
1473
1964
|
for (const kf of this.spec.keyframes ?? []) {
|
|
1474
1965
|
const at = startTime + resolveAt(kf.at, this.duration);
|
|
1475
|
-
const duration = kf
|
|
1966
|
+
const duration = kfDuration(kf);
|
|
1476
1967
|
const ease = kf.ease ?? "none";
|
|
1477
1968
|
const fromTint = kf.from?.tint;
|
|
1478
1969
|
const toTint = kf.to?.tint;
|
|
@@ -1529,6 +2020,207 @@ function stripKeysInKeyframe(kf, keys) {
|
|
|
1529
2020
|
from: stripKeys(kf.from, keys)
|
|
1530
2021
|
};
|
|
1531
2022
|
}
|
|
2023
|
+
|
|
2024
|
+
// src/sequences/gradient.ts
|
|
2025
|
+
function cssColor(c) {
|
|
2026
|
+
return typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
|
|
2027
|
+
}
|
|
2028
|
+
function normalizedStops(g) {
|
|
2029
|
+
const stops = g.stops ?? [];
|
|
2030
|
+
if (stops.length < 2) throw new Error('pixi-effects: fillGradient needs at least two colour stops, e.g. stops: [[0, "#000"], [1, "#fff"]]');
|
|
2031
|
+
return stops.map((s) => Array.isArray(s) ? { offset: s[0], color: s[1] } : { offset: s.offset, color: s.color });
|
|
2032
|
+
}
|
|
2033
|
+
function gradientOptions(g) {
|
|
2034
|
+
const colorStops = normalizedStops(g);
|
|
2035
|
+
const a = (g.angle ?? 90) * Math.PI / 180;
|
|
2036
|
+
const dx = Math.cos(a), dy = Math.sin(a);
|
|
2037
|
+
const h = (Math.abs(dx) + Math.abs(dy)) / 2;
|
|
2038
|
+
return {
|
|
2039
|
+
type: "linear",
|
|
2040
|
+
start: { x: 0.5 - dx * h, y: 0.5 - dy * h },
|
|
2041
|
+
end: { x: 0.5 + dx * h, y: 0.5 + dy * h },
|
|
2042
|
+
colorStops,
|
|
2043
|
+
textureSpace: "local"
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
function paintRadial(ctx, size, g) {
|
|
2047
|
+
const stops = normalizedStops(g);
|
|
2048
|
+
const [cx, cy] = g.center ?? [0.5, 0.5];
|
|
2049
|
+
const grad = ctx.createRadialGradient(cx * size, cy * size, (g.innerRadius ?? 0) * size, cx * size, cy * size, (g.radius ?? 0.5) * size);
|
|
2050
|
+
for (const s of stops) grad.addColorStop(s.offset, cssColor(s.color));
|
|
2051
|
+
ctx.fillStyle = grad;
|
|
2052
|
+
ctx.fillRect(0, 0, size, size);
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// src/sequences/gradientAnim.ts
|
|
2056
|
+
var PATCH_KEYS = ["type", "angle", "center", "innerRadius", "radius", "stops"];
|
|
2057
|
+
function gradStateFrom(g) {
|
|
2058
|
+
return {
|
|
2059
|
+
type: g.type ?? "linear",
|
|
2060
|
+
angle: g.angle ?? 90,
|
|
2061
|
+
center: [...g.center ?? [0.5, 0.5]],
|
|
2062
|
+
innerRadius: g.innerRadius ?? 0,
|
|
2063
|
+
radius: g.radius ?? 0.5,
|
|
2064
|
+
stops: (g.stops ?? []).map((s) => Array.isArray(s) ? { offset: s[0], color: cssColor(s[1]) } : { offset: s.offset, color: cssColor(s.color) })
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
function mergeGrad(base, patch) {
|
|
2068
|
+
const out = { ...base, center: [...base.center], stops: base.stops.map((s) => ({ ...s })) };
|
|
2069
|
+
if (patch === null || typeof patch !== "object" || Array.isArray(patch)) return out;
|
|
2070
|
+
const p = patch;
|
|
2071
|
+
if (typeof p.angle === "number") out.angle = p.angle;
|
|
2072
|
+
if (Array.isArray(p.center)) out.center = [Number(p.center[0]), Number(p.center[1])];
|
|
2073
|
+
if (typeof p.innerRadius === "number") out.innerRadius = p.innerRadius;
|
|
2074
|
+
if (typeof p.radius === "number") out.radius = p.radius;
|
|
2075
|
+
if (p.stops !== void 0) {
|
|
2076
|
+
const next = gradStateFrom({ stops: p.stops }).stops;
|
|
2077
|
+
if (next.length === base.stops.length) out.stops = next;
|
|
2078
|
+
}
|
|
2079
|
+
return out;
|
|
2080
|
+
}
|
|
2081
|
+
var objectHint = "a keyframe's fillGradient must be an object like { angle: 200, stops: [[0, '#f00'], [1, '#00f']] }";
|
|
2082
|
+
function validateGradientKeyframes(spec, who, warn = (m) => console.warn(m), kind = "shape") {
|
|
2083
|
+
const said = /* @__PURE__ */ new Set();
|
|
2084
|
+
const say = (m) => {
|
|
2085
|
+
if (!said.has(m)) {
|
|
2086
|
+
said.add(m);
|
|
2087
|
+
warn(`pixi-effects: ${who}: ${m}`);
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
const startSpec = spec.fillGradient ?? spec.initial?.fillGradient;
|
|
2091
|
+
const start = startSpec && typeof startSpec === "object" && Array.isArray(startSpec.stops) ? gradStateFrom(startSpec) : null;
|
|
2092
|
+
let animated = false;
|
|
2093
|
+
if (kind === "text") {
|
|
2094
|
+
const radial = (g) => !!g && typeof g === "object" && ["type", "center", "innerRadius", "radius"].some((k) => g[k] !== void 0 && !(k === "type" && g.type === "linear"));
|
|
2095
|
+
const asked = radial(startSpec) || (spec.keyframes ?? []).some((kf) => [kf.set, kf.to, kf.from].some((b) => radial(b?.fillGradient)));
|
|
2096
|
+
if (asked) say("a text gradient is linear: type, center, innerRadius and radius are ignored (only angle and stops apply); use a shape for a radial gradient");
|
|
2097
|
+
}
|
|
2098
|
+
for (const kf of spec.keyframes ?? []) {
|
|
2099
|
+
for (const bag of [kf.set, kf.to, kf.from]) {
|
|
2100
|
+
if (!bag) continue;
|
|
2101
|
+
for (const [key, value] of Object.entries(bag)) {
|
|
2102
|
+
if (key === "fillGradient") {
|
|
2103
|
+
animated = true;
|
|
2104
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
2105
|
+
say(objectHint);
|
|
2106
|
+
continue;
|
|
2107
|
+
}
|
|
2108
|
+
const p = value;
|
|
2109
|
+
for (const k of Object.keys(p)) {
|
|
2110
|
+
if (PATCH_KEYS.includes(k)) continue;
|
|
2111
|
+
const guess = chunkUQBGW5DO_cjs.suggestName(k, PATCH_KEYS.filter((x) => x !== "type"));
|
|
2112
|
+
say(`fillGradient.${k} is not a gradient property${guess ? ` \u2014 did you mean "${guess}"?` : ""} (valid: ${PATCH_KEYS.join(", ")}); it is ignored`);
|
|
2113
|
+
}
|
|
2114
|
+
if (p.type !== void 0 && start && p.type !== start.type) say("fillGradient.type cannot change over time (linear <-> radial); it is ignored");
|
|
2115
|
+
if (p.stops !== void 0 && start) {
|
|
2116
|
+
const n = Array.isArray(p.stops) ? p.stops.length : 0;
|
|
2117
|
+
if (n !== start.stops.length) say(`a fillGradient keyframe must give the same number of stops as the gradient has (${start.stops.length}, got ${n}); the stops are left as they were`);
|
|
2118
|
+
}
|
|
2119
|
+
} else if (/^fillGradient\./i.test(key) || /^gradient/i.test(key)) {
|
|
2120
|
+
const tail = key.replace(/^fillGradient\./i, "").replace(/^gradient/i, "");
|
|
2121
|
+
const sub = tail ? tail[0].toLowerCase() + tail.slice(1) : "angle";
|
|
2122
|
+
say(`"${key}" is not an animatable property: write fillGradient: { ${PATCH_KEYS.includes(sub) ? sub : "angle"} } (the whole gradient is one object) in the keyframe's to / from / set`);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
if (animated && !start) say("a keyframe animates fillGradient but the layer has none to start from: give it a fillGradient first (top level or in initial)");
|
|
2128
|
+
}
|
|
2129
|
+
function tweenGradient(timeline, holder, fromPatch, toPatch, duration, ease, at, colorSpace, onChange, loop = {}) {
|
|
2130
|
+
let a = null, b = null;
|
|
2131
|
+
let resting = null;
|
|
2132
|
+
let colors = [];
|
|
2133
|
+
const proxy = { p: 0 };
|
|
2134
|
+
timeline.fromTo(proxy, { p: 0 }, {
|
|
2135
|
+
p: 1,
|
|
2136
|
+
duration,
|
|
2137
|
+
ease,
|
|
2138
|
+
...loop,
|
|
2139
|
+
onStart: () => {
|
|
2140
|
+
const live = holder.grad;
|
|
2141
|
+
a = fromPatch !== void 0 ? mergeGrad(live, fromPatch) : live;
|
|
2142
|
+
if (toPatch === void 0) resting ??= live;
|
|
2143
|
+
b = toPatch !== void 0 ? mergeGrad(a, toPatch) : resting;
|
|
2144
|
+
colors = a.stops.map((s, i) => colorSpace === "rgb" ? gsap.gsap.utils.interpolate(s.color, b.stops[i].color) : buildColorInterp(s.color, b.stops[i].color, colorSpace));
|
|
2145
|
+
},
|
|
2146
|
+
onUpdate: () => {
|
|
2147
|
+
if (!a || !b) return;
|
|
2148
|
+
const t = proxy.p;
|
|
2149
|
+
const l = (x, y) => x + (y - x) * t;
|
|
2150
|
+
holder.grad = {
|
|
2151
|
+
type: a.type,
|
|
2152
|
+
angle: l(a.angle, b.angle),
|
|
2153
|
+
center: [l(a.center[0], b.center[0]), l(a.center[1], b.center[1])],
|
|
2154
|
+
innerRadius: l(a.innerRadius, b.innerRadius),
|
|
2155
|
+
radius: l(a.radius, b.radius),
|
|
2156
|
+
stops: a.stops.map((s, i) => ({ offset: l(s.offset, b.stops[i].offset), color: colors[i](t) }))
|
|
2157
|
+
};
|
|
2158
|
+
onChange();
|
|
2159
|
+
}
|
|
2160
|
+
}, at);
|
|
2161
|
+
}
|
|
2162
|
+
var PAINT_SIZE = 512;
|
|
2163
|
+
var GradientPainter = class {
|
|
2164
|
+
constructor(size = PAINT_SIZE) {
|
|
2165
|
+
this.size = size;
|
|
2166
|
+
this.canvas.width = size;
|
|
2167
|
+
this.canvas.height = size;
|
|
2168
|
+
this.tex = PIXI.Texture.from(this.canvas);
|
|
2169
|
+
globalThis.__gradientPainters = (globalThis.__gradientPainters ?? 0) + 1;
|
|
2170
|
+
}
|
|
2171
|
+
size;
|
|
2172
|
+
canvas = document.createElement("canvas");
|
|
2173
|
+
tex;
|
|
2174
|
+
/** Paint `g` and return what `Graphics.fill(...)` takes. */
|
|
2175
|
+
paint(g) {
|
|
2176
|
+
const ctx = this.canvas.getContext("2d"), s = this.size;
|
|
2177
|
+
if (!ctx) return new PIXI.FillGradient(gradientOptions({ angle: g.angle, stops: g.stops.map((x) => [x.offset, x.color]) }));
|
|
2178
|
+
ctx.clearRect(0, 0, s, s);
|
|
2179
|
+
if (g.type === "radial") {
|
|
2180
|
+
paintRadial(ctx, s, { stops: g.stops.map((x) => [x.offset, x.color]), center: g.center, innerRadius: g.innerRadius, radius: g.radius });
|
|
2181
|
+
} else {
|
|
2182
|
+
const a = g.angle * Math.PI / 180, dx = Math.cos(a), dy = Math.sin(a);
|
|
2183
|
+
const h = (Math.abs(dx) + Math.abs(dy)) / 2;
|
|
2184
|
+
const grad = ctx.createLinearGradient((0.5 - dx * h) * s, (0.5 - dy * h) * s, (0.5 + dx * h) * s, (0.5 + dy * h) * s);
|
|
2185
|
+
for (const st of g.stops) grad.addColorStop(Math.min(1, Math.max(0, st.offset)), st.color);
|
|
2186
|
+
ctx.fillStyle = grad;
|
|
2187
|
+
ctx.fillRect(0, 0, s, s);
|
|
2188
|
+
}
|
|
2189
|
+
this.tex.source.update();
|
|
2190
|
+
return { texture: this.tex, textureSpace: "local" };
|
|
2191
|
+
}
|
|
2192
|
+
/** Give the texture and the canvas back (a layer that is destroyed must not leave them). */
|
|
2193
|
+
destroy() {
|
|
2194
|
+
this.tex.destroy(true);
|
|
2195
|
+
this.canvas.width = this.canvas.height = 0;
|
|
2196
|
+
globalThis.__gradientPainters = Math.max(0, (globalThis.__gradientPainters ?? 1) - 1);
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
function bindGradientKeyframes(timeline, holder, keyframes, duration, offset, colorSpace, onChange) {
|
|
2200
|
+
const bag = (b) => b?.fillGradient;
|
|
2201
|
+
for (const kf of keyframes) {
|
|
2202
|
+
const at = offset + resolveAt(kf.at, duration);
|
|
2203
|
+
const setV = bag(kf.set), fromV = bag(kf.from), toV = bag(kf.to);
|
|
2204
|
+
if (setV !== void 0) {
|
|
2205
|
+
revertibleSet(
|
|
2206
|
+
timeline,
|
|
2207
|
+
at,
|
|
2208
|
+
() => ({ state: holder.grad }),
|
|
2209
|
+
(v) => {
|
|
2210
|
+
holder.grad = v.state ?? mergeGrad(holder.grad, v.patch);
|
|
2211
|
+
onChange();
|
|
2212
|
+
},
|
|
2213
|
+
{ patch: setV }
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
if (fromV !== void 0 || toV !== void 0) {
|
|
2217
|
+
tweenGradient(timeline, holder, fromV, toV, kfDuration(kf), kf.ease ?? "none", at, colorSpace, onChange, loopVars(kf));
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
var hasGradientKeys = (keyframes) => (keyframes ?? []).some((kf) => [kf.set, kf.to, kf.from].some((b) => b && b.fillGradient !== void 0));
|
|
2222
|
+
|
|
2223
|
+
// src/sequences/Text.ts
|
|
1532
2224
|
var STYLE_OPAQUE_KEYS = [
|
|
1533
2225
|
"fontFamily",
|
|
1534
2226
|
"fill",
|
|
@@ -1563,6 +2255,21 @@ var TextSequence = class extends Sequence {
|
|
|
1563
2255
|
/** `visibleChars` is in play (initial or animated): otherwise the whole text shows. */
|
|
1564
2256
|
_typed = false;
|
|
1565
2257
|
_lastText = "";
|
|
2258
|
+
/** A gradient fill for the text (`fillGradient`, static or animated): rebuilt as a FillGradient on each change (the text is re-rasterised). */
|
|
2259
|
+
_grad = null;
|
|
2260
|
+
_fillGradient = null;
|
|
2261
|
+
_applyGradient() {
|
|
2262
|
+
const g = this._grad.grad;
|
|
2263
|
+
const next = new PIXI.FillGradient(gradientOptions({ angle: g.angle, stops: g.stops.map((s) => [s.offset, s.color]) }));
|
|
2264
|
+
this.target.style.fill = next;
|
|
2265
|
+
this._fillGradient?.destroy();
|
|
2266
|
+
this._fillGradient = next;
|
|
2267
|
+
}
|
|
2268
|
+
destroy() {
|
|
2269
|
+
super.destroy();
|
|
2270
|
+
this._fillGradient?.destroy();
|
|
2271
|
+
this._fillGradient = null;
|
|
2272
|
+
}
|
|
1566
2273
|
/** A typewriter that has typed nothing yet: the layer is empty on purpose (inspect must not call that "no size"). */
|
|
1567
2274
|
get showsNothingYet() {
|
|
1568
2275
|
return this._typed && this._lastText === "" && this._template !== "";
|
|
@@ -1609,6 +2316,12 @@ var TextSequence = class extends Sequence {
|
|
|
1609
2316
|
this.intrinsicWidth = text.width;
|
|
1610
2317
|
this.intrinsicHeight = text.height;
|
|
1611
2318
|
}
|
|
2319
|
+
validateGradientKeyframes(this.spec, describeLayer(this.spec), void 0, "text");
|
|
2320
|
+
const gradientSpec = this.spec.fillGradient ?? initialProps.fillGradient;
|
|
2321
|
+
if (gradientSpec) {
|
|
2322
|
+
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
2323
|
+
this._applyGradient();
|
|
2324
|
+
}
|
|
1612
2325
|
const scope = this.scope();
|
|
1613
2326
|
if (initialProps.value !== void 0) this._counters.value = resolveNumber(initialProps.value, scope);
|
|
1614
2327
|
this._typed = initialProps.visibleChars !== void 0 || animates(this.spec.keyframes, "visibleChars");
|
|
@@ -1627,11 +2340,12 @@ var TextSequence = class extends Sequence {
|
|
|
1627
2340
|
bindTimeline(timeline, offset = 0) {
|
|
1628
2341
|
if (!this.target) return;
|
|
1629
2342
|
const colorSpace = this.spec.colorSpace ?? "rgb";
|
|
1630
|
-
const stripped = stripKeys2(this.spec, ["fill", "value", "text", "visibleChars"]);
|
|
2343
|
+
const stripped = stripKeys2(this.spec, ["fill", "value", "text", "visibleChars", "fillGradient"]);
|
|
1631
2344
|
runSuperWithStrippedSpec(this, stripped, timeline, offset);
|
|
1632
2345
|
const keyframes = this.spec.keyframes ?? [];
|
|
1633
2346
|
const origin = offset + this.at;
|
|
1634
2347
|
bindFillKeyframes(timeline, this.target, keyframes, this.duration, origin, colorSpace);
|
|
2348
|
+
if (this._grad) bindGradientKeyframes(timeline, this._grad, keyframes, this.duration, origin, colorSpace, () => this._applyGradient());
|
|
1635
2349
|
const refresh = () => this._refreshText();
|
|
1636
2350
|
bindCounterKeyframes(timeline, this._counters, "value", refresh, keyframes, this.duration, origin, this.scope());
|
|
1637
2351
|
bindCounterKeyframes(timeline, this._counters, "visibleChars", refresh, keyframes, this.duration, origin, this.scope());
|
|
@@ -1681,7 +2395,7 @@ function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDu
|
|
|
1681
2395
|
const toV = kf.to?.[key];
|
|
1682
2396
|
if (setV === void 0 && fromV === void 0 && toV === void 0) continue;
|
|
1683
2397
|
const at = origin + resolveAt(kf.at, parentDuration);
|
|
1684
|
-
const duration = kf
|
|
2398
|
+
const duration = kfDuration(kf);
|
|
1685
2399
|
const ease = kf.ease ?? "none";
|
|
1686
2400
|
const loop = loopVars(kf);
|
|
1687
2401
|
if (setV !== void 0) {
|
|
@@ -1727,7 +2441,7 @@ function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, co
|
|
|
1727
2441
|
};
|
|
1728
2442
|
for (const kf of keyframes) {
|
|
1729
2443
|
const at = offset + resolveAt(kf.at, parentDuration);
|
|
1730
|
-
const duration = kf
|
|
2444
|
+
const duration = kfDuration(kf);
|
|
1731
2445
|
const ease = kf.ease ?? "none";
|
|
1732
2446
|
const setFill = pickFill(kf.set);
|
|
1733
2447
|
const fromFill = pickFill(kf.from);
|
|
@@ -2061,39 +2775,6 @@ var VideoSequence = class extends Sequence {
|
|
|
2061
2775
|
super.destroy();
|
|
2062
2776
|
}
|
|
2063
2777
|
};
|
|
2064
|
-
|
|
2065
|
-
// src/sequences/gradient.ts
|
|
2066
|
-
function cssColor(c) {
|
|
2067
|
-
return typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
|
|
2068
|
-
}
|
|
2069
|
-
function normalizedStops(g) {
|
|
2070
|
-
const stops = g.stops ?? [];
|
|
2071
|
-
if (stops.length < 2) throw new Error('pixi-effects: fillGradient needs at least two colour stops, e.g. stops: [[0, "#000"], [1, "#fff"]]');
|
|
2072
|
-
return stops.map((s) => Array.isArray(s) ? { offset: s[0], color: s[1] } : { offset: s.offset, color: s.color });
|
|
2073
|
-
}
|
|
2074
|
-
function gradientOptions(g) {
|
|
2075
|
-
const colorStops = normalizedStops(g);
|
|
2076
|
-
const a = (g.angle ?? 90) * Math.PI / 180;
|
|
2077
|
-
const dx = Math.cos(a), dy = Math.sin(a);
|
|
2078
|
-
const h = (Math.abs(dx) + Math.abs(dy)) / 2;
|
|
2079
|
-
return {
|
|
2080
|
-
type: "linear",
|
|
2081
|
-
start: { x: 0.5 - dx * h, y: 0.5 - dy * h },
|
|
2082
|
-
end: { x: 0.5 + dx * h, y: 0.5 + dy * h },
|
|
2083
|
-
colorStops,
|
|
2084
|
-
textureSpace: "local"
|
|
2085
|
-
};
|
|
2086
|
-
}
|
|
2087
|
-
function paintRadial(ctx, size, g) {
|
|
2088
|
-
const stops = normalizedStops(g);
|
|
2089
|
-
const [cx, cy] = g.center ?? [0.5, 0.5];
|
|
2090
|
-
const grad = ctx.createRadialGradient(cx * size, cy * size, (g.innerRadius ?? 0) * size, cx * size, cy * size, (g.radius ?? 0.5) * size);
|
|
2091
|
-
for (const s of stops) grad.addColorStop(s.offset, cssColor(s.color));
|
|
2092
|
-
ctx.fillStyle = grad;
|
|
2093
|
-
ctx.fillRect(0, 0, size, size);
|
|
2094
|
-
}
|
|
2095
|
-
|
|
2096
|
-
// src/sequences/gradientFill.ts
|
|
2097
2778
|
var RADIAL_SIZE = 256;
|
|
2098
2779
|
function makeGradientFill(g) {
|
|
2099
2780
|
if (g.type === "radial") {
|
|
@@ -2285,7 +2966,7 @@ function morphAt(pairs, t) {
|
|
|
2285
2966
|
}
|
|
2286
2967
|
|
|
2287
2968
|
// src/sequences/Shape.ts
|
|
2288
|
-
var
|
|
2969
|
+
var STYLE_KEYS2 = ["fillColor", "fillAlpha", "strokeColor", "strokeAlpha", "strokeWidth"];
|
|
2289
2970
|
var COLOR_KEYS = /* @__PURE__ */ new Set(["fillColor", "strokeColor"]);
|
|
2290
2971
|
var TRIM_KEYS = ["trimStart", "trimEnd"];
|
|
2291
2972
|
var GEOMETRY_KEYS_BY_SHAPE = {
|
|
@@ -2311,7 +2992,7 @@ var ShapeSequence = class extends Sequence {
|
|
|
2311
2992
|
// by `Container.onRender`.
|
|
2312
2993
|
_drawGeometry = () => {
|
|
2313
2994
|
};
|
|
2314
|
-
_liveKeys = new Set(
|
|
2995
|
+
_liveKeys = new Set(STYLE_KEYS2);
|
|
2315
2996
|
async build() {
|
|
2316
2997
|
const graphics = new PIXI.Graphics({ label: this.spec.name });
|
|
2317
2998
|
graphics.cullable = true;
|
|
@@ -2337,7 +3018,15 @@ var ShapeSequence = class extends Sequence {
|
|
|
2337
3018
|
this._state.trimEnd ??= 1;
|
|
2338
3019
|
}
|
|
2339
3020
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
2340
|
-
|
|
3021
|
+
validateGradientKeyframes(this.spec, describeLayer(this.spec));
|
|
3022
|
+
if (gradientSpec) {
|
|
3023
|
+
if (hasGradientKeys(this.spec.keyframes)) {
|
|
3024
|
+
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
3025
|
+
this._painter = new GradientPainter();
|
|
3026
|
+
this._gradDirty = true;
|
|
3027
|
+
this._liveKeys.add("fillGradient");
|
|
3028
|
+
} else this._state.fillStyle = makeGradientFill(gradientSpec);
|
|
3029
|
+
}
|
|
2341
3030
|
const morph = this._setupMorph();
|
|
2342
3031
|
this._drawGeometry = makeDrawGeometry(this.spec, scope, this._state, morph);
|
|
2343
3032
|
this._outline = makeOutline(this.spec, scope, this._state, morph);
|
|
@@ -2396,11 +3085,23 @@ var ShapeSequence = class extends Sequence {
|
|
|
2396
3085
|
this._state.morph ??= 0;
|
|
2397
3086
|
return { pairs, to: String(top.morphTo) };
|
|
2398
3087
|
}
|
|
3088
|
+
destroy() {
|
|
3089
|
+
super.destroy();
|
|
3090
|
+
this._painter?.destroy();
|
|
3091
|
+
this._painter = null;
|
|
3092
|
+
}
|
|
2399
3093
|
_fresh = false;
|
|
3094
|
+
_grad = null;
|
|
3095
|
+
_painter = null;
|
|
3096
|
+
_gradDirty = false;
|
|
2400
3097
|
_outline = null;
|
|
2401
3098
|
_redraw() {
|
|
2402
3099
|
const graphics = this.target;
|
|
2403
3100
|
const s = this._state;
|
|
3101
|
+
if (this._grad && this._gradDirty) {
|
|
3102
|
+
s.fillStyle = this._painter.paint(this._grad.grad);
|
|
3103
|
+
this._gradDirty = false;
|
|
3104
|
+
}
|
|
2404
3105
|
graphics.clear();
|
|
2405
3106
|
const trimmed = (s.trimStart ?? 0) > 0 || (s.trimEnd ?? 1) < 1;
|
|
2406
3107
|
if (!trimmed || !this._outline || !(s.strokeColor !== void 0 && s.strokeWidth > 0)) {
|
|
@@ -2446,6 +3147,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
2446
3147
|
applyKeyframes(timeline, this.target, keyframes, this.duration, scope, [], startTime);
|
|
2447
3148
|
const colorSpace = this.spec.colorSpace ?? "rgb";
|
|
2448
3149
|
bindLiveKeyframes(timeline, this._state, this._liveKeys, this.spec.keyframes ?? [], this.duration, scope, startTime, colorSpace);
|
|
3150
|
+
if (this._grad) bindGradientKeyframes(timeline, this._grad, this.spec.keyframes ?? [], this.duration, startTime, colorSpace, () => {
|
|
3151
|
+
this._gradDirty = true;
|
|
3152
|
+
});
|
|
2449
3153
|
this.absoluteStart = startTime;
|
|
2450
3154
|
const endTime = startTime + this.duration;
|
|
2451
3155
|
this.target.renderable = startTime <= 0;
|
|
@@ -2482,7 +3186,7 @@ function seedStrokeStyle(state, spec, initial, who) {
|
|
|
2482
3186
|
}
|
|
2483
3187
|
}
|
|
2484
3188
|
function seedStyle(state, initial, scope) {
|
|
2485
|
-
for (const k of
|
|
3189
|
+
for (const k of STYLE_KEYS2) {
|
|
2486
3190
|
const v = initial[k];
|
|
2487
3191
|
if (v === void 0) continue;
|
|
2488
3192
|
state[k] = COLOR_KEYS.has(k) ? v : numOrZero(v, scope);
|
|
@@ -2705,13 +3409,14 @@ function makeOutline(spec, scope, s, morph) {
|
|
|
2705
3409
|
function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration, scope, offset, colorSpace) {
|
|
2706
3410
|
for (const kf of keyframes) {
|
|
2707
3411
|
const at = offset + resolveAt(kf.at, parentDuration);
|
|
2708
|
-
const duration = kf
|
|
3412
|
+
const duration = kfDuration(kf);
|
|
2709
3413
|
const ease = kf.ease ?? "none";
|
|
2710
3414
|
const loop = loopVars(kf);
|
|
2711
3415
|
if (kf.set) {
|
|
2712
3416
|
const live = pickLive(kf.set, liveKeys);
|
|
2713
3417
|
if (live) {
|
|
2714
3418
|
for (const [k, v] of Object.entries(live)) {
|
|
3419
|
+
if (k === "fillGradient") continue;
|
|
2715
3420
|
const resolved = resolveLiveValue(k, v, scope);
|
|
2716
3421
|
const live2 = state;
|
|
2717
3422
|
revertibleSet(timeline, at, () => live2[k], (v2) => {
|
|
@@ -2727,6 +3432,7 @@ function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration,
|
|
|
2727
3432
|
...toLive ? Object.keys(toLive) : []
|
|
2728
3433
|
]);
|
|
2729
3434
|
for (const k of allKeys) {
|
|
3435
|
+
if (k === "fillGradient") continue;
|
|
2730
3436
|
const key = k;
|
|
2731
3437
|
const fromRaw = fromLive?.[key];
|
|
2732
3438
|
const toRaw = toLive?.[key];
|
|
@@ -2775,7 +3481,7 @@ function numOrZero(v, scope) {
|
|
|
2775
3481
|
var _CompositionSequence = null;
|
|
2776
3482
|
async function getCompositionSequence() {
|
|
2777
3483
|
if (!_CompositionSequence) {
|
|
2778
|
-
_CompositionSequence = (await import('./Composition-
|
|
3484
|
+
_CompositionSequence = (await import('./Composition-KYNPRWK3.cjs')).CompositionSequence;
|
|
2779
3485
|
}
|
|
2780
3486
|
return _CompositionSequence;
|
|
2781
3487
|
}
|
|
@@ -2830,6 +3536,7 @@ exports.evaluateExpr = evaluateExpr;
|
|
|
2830
3536
|
exports.flattenSvgPath = flattenSvgPath;
|
|
2831
3537
|
exports.homeCamera = homeCamera;
|
|
2832
3538
|
exports.homeDistance = homeDistance;
|
|
3539
|
+
exports.lintKeys = lintKeys;
|
|
2833
3540
|
exports.lintText = lintText;
|
|
2834
3541
|
exports.lintTiming = lintTiming;
|
|
2835
3542
|
exports.noise = noise;
|
|
@@ -2839,5 +3546,5 @@ exports.random = random;
|
|
|
2839
3546
|
exports.registerSequenceType = registerSequenceType;
|
|
2840
3547
|
exports.resolveAt = resolveAt;
|
|
2841
3548
|
exports.summarizeWarnings = summarizeWarnings;
|
|
2842
|
-
//# sourceMappingURL=chunk-
|
|
2843
|
-
//# sourceMappingURL=chunk-
|
|
3549
|
+
//# sourceMappingURL=chunk-VTBT6NNE.cjs.map
|
|
3550
|
+
//# sourceMappingURL=chunk-VTBT6NNE.cjs.map
|