pixi-effects 0.26.2 → 0.27.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 +28 -0
- package/README.md +8 -10
- package/ai/CHAT.md +1 -1
- package/ai/chat-template.html +4 -6
- package/ai/tools/render.mjs +16 -11
- package/dist/{Base-CpdDs4HT.d.ts → Base-CVezIEdo.d.ts} +2 -4
- package/dist/{Base-TbBhHPrG.d.cts → Base-DzC3i919.d.cts} +2 -4
- package/dist/Composition-4TYDRRRY.js +7 -0
- package/dist/{Composition-H4QA24MV.js.map → Composition-4TYDRRRY.js.map} +1 -1
- package/dist/Composition-QCOWQSDB.cjs +16 -0
- package/dist/{Composition-HM4YT5L7.cjs.map → Composition-QCOWQSDB.cjs.map} +1 -1
- package/dist/Controller.d.cts +2 -3
- package/dist/Controller.d.ts +2 -3
- package/dist/{Movie-i05Oh9mJ.d.cts → Movie-CQ0Nz62a.d.cts} +12 -6
- package/dist/{Movie-DVeDTdnc.d.ts → Movie-M9dKm9dI.d.ts} +12 -6
- package/dist/Presenter.d.cts +2 -3
- package/dist/Presenter.d.ts +2 -3
- package/dist/{blendModes-YV43K6E7.cjs → blendModes-HDOP6R7T.cjs} +5 -5
- package/dist/{blendModes-YV43K6E7.cjs.map → blendModes-HDOP6R7T.cjs.map} +1 -1
- package/dist/{blendModes-G3NOAU3T.js → blendModes-PAVTW3BO.js} +4 -4
- package/dist/{blendModes-G3NOAU3T.js.map → blendModes-PAVTW3BO.js.map} +1 -1
- package/dist/{chunk-TLYTYBWX.js → chunk-45QKLD6M.js} +9 -11
- package/dist/chunk-45QKLD6M.js.map +1 -0
- package/dist/{chunk-GBUM7X2S.js → chunk-CKTS6G6I.js} +7 -11
- package/dist/chunk-CKTS6G6I.js.map +1 -0
- package/dist/{chunk-555URQHQ.cjs → chunk-NDR2VQFV.cjs} +91 -95
- package/dist/chunk-NDR2VQFV.cjs.map +1 -0
- package/dist/{chunk-3DLYAPK7.cjs → chunk-P4GY3Z4G.cjs} +5 -5
- package/dist/{chunk-3DLYAPK7.cjs.map → chunk-P4GY3Z4G.cjs.map} +1 -1
- package/dist/{chunk-WPXDRSGN.cjs → chunk-RQMI7EJT.cjs} +1170 -280
- package/dist/chunk-RQMI7EJT.cjs.map +1 -0
- package/dist/{chunk-X3HB4DSR.js → chunk-TGJACVLD.js} +1150 -263
- package/dist/chunk-TGJACVLD.js.map +1 -0
- package/dist/{chunk-AXZUKNXF.js → chunk-TYWFKCPY.js} +4 -4
- package/dist/{chunk-AXZUKNXF.js.map → chunk-TYWFKCPY.js.map} +1 -1
- package/dist/{chunk-ECA2WNRX.cjs → chunk-ZMAD3KJU.cjs} +9 -11
- package/dist/chunk-ZMAD3KJU.cjs.map +1 -0
- package/dist/index.cjs +189 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -14
- package/dist/index.d.ts +16 -14
- package/dist/index.js +136 -45
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/three.cjs +6 -6
- package/dist/three.d.cts +2 -3
- package/dist/three.d.ts +2 -3
- package/dist/three.js +2 -2
- package/dist/{types-DSGwN5w1.d.ts → types-DUVefWiB.d.cts} +128 -3
- package/dist/{types-DSGwN5w1.d.cts → types-DUVefWiB.d.ts} +128 -3
- package/docs/api.md +16 -6
- package/docs/dsl.md +14 -14
- package/llms-full.txt +38 -28
- package/llms.txt +1 -1
- package/package.json +3 -4
- package/skills/pixi-effects/SKILL.md +1 -1
- package/skills/pixi-effects/reference/cheatsheet.md +3 -3
- package/skills/pixi-effects/reference/pitfalls.md +3 -3
- package/skills/pixi-effects/reference/recipes.md +1 -1
- package/skills/pixi-effects/template.html +6 -8
- package/dist/Composition-H4QA24MV.js +0 -7
- package/dist/Composition-HM4YT5L7.cjs +0 -16
- package/dist/chunk-555URQHQ.cjs.map +0 -1
- package/dist/chunk-ECA2WNRX.cjs.map +0 -1
- package/dist/chunk-GBUM7X2S.js.map +0 -1
- package/dist/chunk-TLYTYBWX.js.map +0 -1
- package/dist/chunk-WPXDRSGN.cjs.map +0 -1
- package/dist/chunk-X3HB4DSR.js.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkZMAD3KJU_cjs = require('./chunk-ZMAD3KJU.cjs');
|
|
4
4
|
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
5
5
|
var PIXI = require('pixi.js');
|
|
6
|
-
var gsap = require('gsap');
|
|
7
6
|
|
|
8
7
|
function _interopNamespace(e) {
|
|
9
8
|
if (e && e.__esModule) return e;
|
|
@@ -25,40 +24,7 @@ function _interopNamespace(e) {
|
|
|
25
24
|
|
|
26
25
|
var PIXI__namespace = /*#__PURE__*/_interopNamespace(PIXI);
|
|
27
26
|
|
|
28
|
-
// src/
|
|
29
|
-
function mix(h) {
|
|
30
|
-
h = Math.imul(h ^ h >>> 16, 2246822507);
|
|
31
|
-
h = Math.imul(h ^ h >>> 13, 3266489909);
|
|
32
|
-
return (h ^ h >>> 16) >>> 0;
|
|
33
|
-
}
|
|
34
|
-
function fold(n) {
|
|
35
|
-
if (!Number.isFinite(n)) return 0;
|
|
36
|
-
const i = Math.floor(n);
|
|
37
|
-
const f = n - i;
|
|
38
|
-
return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
|
|
39
|
-
}
|
|
40
|
-
function rand(seed) {
|
|
41
|
-
return mix(fold(seed) + 2654435769) / 4294967296;
|
|
42
|
-
}
|
|
43
|
-
function random(seed) {
|
|
44
|
-
let a = fold(seed) + 1831565813 | 0;
|
|
45
|
-
return () => {
|
|
46
|
-
a = a + 1831565813 | 0;
|
|
47
|
-
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
48
|
-
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
49
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function noise(x, seed = 0) {
|
|
53
|
-
if (!Number.isFinite(x)) return 0;
|
|
54
|
-
const i = Math.floor(x);
|
|
55
|
-
const f = x - i;
|
|
56
|
-
const s = fold(seed) * 668265261;
|
|
57
|
-
const a = mix((i | 0) + s) / 2147483648 - 1;
|
|
58
|
-
const b = mix((i + 1 | 0) + s) / 2147483648 - 1;
|
|
59
|
-
const u = f * f * f * (f * (f * 6 - 15) + 10);
|
|
60
|
-
return a + (b - a) * u;
|
|
61
|
-
}
|
|
27
|
+
// src/core/spring.ts
|
|
62
28
|
var SETTLE_TOL = 5e-3;
|
|
63
29
|
var DEFAULTS = { mass: 1, stiffness: 100, damping: 10 };
|
|
64
30
|
function springResponse(t, { mass: m, stiffness: k, damping: c }) {
|
|
@@ -140,19 +106,6 @@ function parseSpring(name) {
|
|
|
140
106
|
const [mass, stiffness, damping] = (m[2] ?? "").split(",").map((s) => s.trim()).filter(Boolean).map(Number);
|
|
141
107
|
return complete({ mass, stiffness, damping });
|
|
142
108
|
}
|
|
143
|
-
var registered = false;
|
|
144
|
-
function registerSpringEases() {
|
|
145
|
-
if (registered) return;
|
|
146
|
-
registered = true;
|
|
147
|
-
const base = springEase();
|
|
148
|
-
const ease = (p) => base(p);
|
|
149
|
-
ease.config = (mass, stiffness, damping) => {
|
|
150
|
-
const bad = [mass, stiffness, damping].some((v) => v !== void 0 && !(typeof v === "number" && v > 0 && Number.isFinite(v)));
|
|
151
|
-
return springEase(bad ? {} : { mass, stiffness, damping });
|
|
152
|
-
};
|
|
153
|
-
gsap.gsap.registerEase("spring", ease);
|
|
154
|
-
for (const [name, p] of Object.entries(SPRING_PRESETS)) gsap.gsap.registerEase(`spring.${name}`, springEase(p));
|
|
155
|
-
}
|
|
156
109
|
var autoWarned = /* @__PURE__ */ new Set();
|
|
157
110
|
function kfDuration(kf) {
|
|
158
111
|
if (kf.duration !== "auto") return kf.duration ?? 0;
|
|
@@ -165,7 +118,837 @@ function kfDuration(kf) {
|
|
|
165
118
|
}
|
|
166
119
|
return 0.5;
|
|
167
120
|
}
|
|
168
|
-
|
|
121
|
+
|
|
122
|
+
// src/core/cubicBezier.ts
|
|
123
|
+
function cubicBezierEase(x1, y1, x2, y2) {
|
|
124
|
+
const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;
|
|
125
|
+
const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;
|
|
126
|
+
const X = (t) => ((ax * t + bx) * t + cx) * t;
|
|
127
|
+
const Y = (t) => ((ay * t + by) * t + cy) * t;
|
|
128
|
+
const dX = (t) => (3 * ax * t + 2 * bx) * t + cx;
|
|
129
|
+
return (p) => {
|
|
130
|
+
if (p <= 0) return 0;
|
|
131
|
+
if (p >= 1) return 1;
|
|
132
|
+
let t = p;
|
|
133
|
+
for (let i = 0; i < 8; i++) {
|
|
134
|
+
const err = X(t) - p;
|
|
135
|
+
if (Math.abs(err) < 1e-9) return Y(t);
|
|
136
|
+
const d = dX(t);
|
|
137
|
+
if (Math.abs(d) < 1e-6) break;
|
|
138
|
+
t -= err / d;
|
|
139
|
+
}
|
|
140
|
+
let lo = 0, hi = 1;
|
|
141
|
+
t = p;
|
|
142
|
+
for (let i = 0; i < 60; i++) {
|
|
143
|
+
const x = X(t);
|
|
144
|
+
if (Math.abs(x - p) < 1e-10) break;
|
|
145
|
+
if (x < p) lo = t;
|
|
146
|
+
else hi = t;
|
|
147
|
+
t = (lo + hi) / 2;
|
|
148
|
+
}
|
|
149
|
+
return Y(t);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
var NUM = String.raw`\s*(-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)\s*`;
|
|
153
|
+
var RE = new RegExp(`^\\s*cubic-bezier\\(${NUM},${NUM},${NUM},${NUM}\\)\\s*$`, "i");
|
|
154
|
+
function parseCubicBezier(name) {
|
|
155
|
+
const m = RE.exec(name);
|
|
156
|
+
return m && !cubicBezierProblem(name) ? [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])] : null;
|
|
157
|
+
}
|
|
158
|
+
function cubicBezierProblem(name) {
|
|
159
|
+
const m = RE.exec(name);
|
|
160
|
+
if (!m) return 'expected "cubic-bezier(x1, y1, x2, y2)" with four numbers, like CSS';
|
|
161
|
+
const x1 = Number(m[1]), x2 = Number(m[3]);
|
|
162
|
+
if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) return "x1 and x2 must be between 0 and 1 (y1 and y2 may overshoot)";
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/core/pure/ease.ts
|
|
167
|
+
var PI = Math.PI;
|
|
168
|
+
var power = (strength) => ({
|
|
169
|
+
in: (p) => Math.pow(p, strength),
|
|
170
|
+
out: (p) => 1 - Math.pow(1 - p, strength),
|
|
171
|
+
inOut: (p) => p < 0.5 ? 0.5 * Math.pow(2 * p, strength) : 1 - 0.5 * Math.pow(2 * (1 - p), strength)
|
|
172
|
+
});
|
|
173
|
+
var fromOut = (out) => ({
|
|
174
|
+
in: (p) => 1 - out(1 - p),
|
|
175
|
+
out,
|
|
176
|
+
inOut: (p) => p < 0.5 ? 0.5 * (1 - out(1 - 2 * p)) : 0.5 + 0.5 * out(2 * p - 1)
|
|
177
|
+
});
|
|
178
|
+
var mirrored = (easeIn) => ({
|
|
179
|
+
in: easeIn,
|
|
180
|
+
out: (p) => 1 - easeIn(1 - p),
|
|
181
|
+
inOut: (p) => p < 0.5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2
|
|
182
|
+
});
|
|
183
|
+
var sine = mirrored((p) => p === 1 ? 1 : -Math.cos(p * PI / 2) + 1);
|
|
184
|
+
var circ = mirrored((p) => -(Math.sqrt(1 - p * p) - 1));
|
|
185
|
+
var expoIn = (p) => Math.pow(2, 10 * (p - 1)) * p + p * p * p * p * p * p * (1 - p);
|
|
186
|
+
var expo = {
|
|
187
|
+
in: expoIn,
|
|
188
|
+
out: (p) => 1 - expoIn(1 - p),
|
|
189
|
+
inOut: (p) => p < 0.5 ? expoIn(p * 2) / 2 : 1 - expoIn((1 - p) * 2) / 2
|
|
190
|
+
};
|
|
191
|
+
var bounceOut = (p) => {
|
|
192
|
+
if (p < 1 / 2.75) return 7.5625 * p * p;
|
|
193
|
+
if (p < 2 / 2.75) {
|
|
194
|
+
p -= 1.5 / 2.75;
|
|
195
|
+
return 7.5625 * p * p + 0.75;
|
|
196
|
+
}
|
|
197
|
+
if (p < 2.5 / 2.75) {
|
|
198
|
+
p -= 2.25 / 2.75;
|
|
199
|
+
return 7.5625 * p * p + 0.9375;
|
|
200
|
+
}
|
|
201
|
+
p -= 2.625 / 2.75;
|
|
202
|
+
return 7.5625 * p * p + 0.984375;
|
|
203
|
+
};
|
|
204
|
+
var bounce = fromOut(bounceOut);
|
|
205
|
+
function back(s = 1.70158) {
|
|
206
|
+
const out = (p) => p ? (p -= 1, p * p * ((s + 1) * p + s) + 1) : 0;
|
|
207
|
+
return fromOut(out);
|
|
208
|
+
}
|
|
209
|
+
function elastic(amplitude, period) {
|
|
210
|
+
const make = (per0) => {
|
|
211
|
+
const amp = amplitude ?? 1;
|
|
212
|
+
const a = amp >= 1 ? amp : 1;
|
|
213
|
+
const per = per0 / (amp < 1 ? amp : 1);
|
|
214
|
+
const s = per / (2 * PI) * Math.asin(1 / a);
|
|
215
|
+
const k = 2 * PI / per;
|
|
216
|
+
return fromOut((p) => p === 0 ? 0 : p === 1 ? 1 : a * Math.pow(2, -10 * p) * Math.sin((p - s) * k) + 1);
|
|
217
|
+
};
|
|
218
|
+
const usual = make(period ?? 0.3);
|
|
219
|
+
return { in: usual.in, out: usual.out, inOut: period === void 0 ? make(0.45).inOut : usual.inOut };
|
|
220
|
+
}
|
|
221
|
+
function steps(n) {
|
|
222
|
+
const count = Math.max(1, Math.floor(n) || 1);
|
|
223
|
+
return (p) => p <= 0 ? 0 : p >= 1 ? 1 : Math.min(1, Math.floor(p * (count + 1)) / count);
|
|
224
|
+
}
|
|
225
|
+
var FAMILY = {
|
|
226
|
+
power1: () => power(2),
|
|
227
|
+
power2: () => power(3),
|
|
228
|
+
power3: () => power(4),
|
|
229
|
+
power4: () => power(5),
|
|
230
|
+
quad: () => power(2),
|
|
231
|
+
cubic: () => power(3),
|
|
232
|
+
quart: () => power(4),
|
|
233
|
+
quint: () => power(5),
|
|
234
|
+
strong: () => power(5),
|
|
235
|
+
sine: () => sine,
|
|
236
|
+
circ: () => circ,
|
|
237
|
+
expo: () => expo,
|
|
238
|
+
bounce: () => bounce,
|
|
239
|
+
back: (a) => back(a[0]),
|
|
240
|
+
elastic: (a) => elastic(a[0], a[1])
|
|
241
|
+
};
|
|
242
|
+
var LINEAR = (p) => p;
|
|
243
|
+
var DEFAULT = power(2).out;
|
|
244
|
+
var cache = /* @__PURE__ */ new Map();
|
|
245
|
+
function lookup(name) {
|
|
246
|
+
let hit = cache.get(name);
|
|
247
|
+
if (hit === void 0) {
|
|
248
|
+
hit = parse(name.trim());
|
|
249
|
+
cache.set(name, hit);
|
|
250
|
+
}
|
|
251
|
+
return hit;
|
|
252
|
+
}
|
|
253
|
+
function pureEase(name) {
|
|
254
|
+
return (typeof name === "string" ? lookup(name) : null) ?? DEFAULT;
|
|
255
|
+
}
|
|
256
|
+
function isEaseName(name) {
|
|
257
|
+
return typeof name === "string" && lookup(name) !== null;
|
|
258
|
+
}
|
|
259
|
+
function parse(raw) {
|
|
260
|
+
const s = raw.toLowerCase();
|
|
261
|
+
if (s === "none" || s === "linear" || s === "linear.easenone") return LINEAR;
|
|
262
|
+
if (/^spring/.test(s)) {
|
|
263
|
+
const sp = parseSpring(raw);
|
|
264
|
+
return sp ? springEase(sp) : null;
|
|
265
|
+
}
|
|
266
|
+
if (/^cubic-bezier/.test(s)) {
|
|
267
|
+
const c = parseCubicBezier(raw);
|
|
268
|
+
return c ? cubicBezierEase(...c) : LINEAR;
|
|
269
|
+
}
|
|
270
|
+
const st = /^steps\(\s*([^)]*)\)$/.exec(s);
|
|
271
|
+
if (st) return steps(Number(st[1]));
|
|
272
|
+
if (/^[a-z][a-z0-9]*$/.test(raw) && FAMILY[raw]) return FAMILY[raw]([]).out;
|
|
273
|
+
const m = /^([a-z0-9]+)\.(?:ease)?(in|out|inout)(?:\(([^)]*)\))?$/.exec(s);
|
|
274
|
+
if (!m) return null;
|
|
275
|
+
const make = FAMILY[m[1]];
|
|
276
|
+
if (!make) return null;
|
|
277
|
+
const args = (m[3] ?? "").split(",").map((x) => x.trim()).filter(Boolean).map(Number).filter((n) => Number.isFinite(n));
|
|
278
|
+
const trio = make(args);
|
|
279
|
+
return m[2] === "in" ? trio.in : m[2] === "out" ? trio.out : trio.inOut;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/core/pure/colorLerp.ts
|
|
283
|
+
function parseCssColor(s) {
|
|
284
|
+
const v = s.trim();
|
|
285
|
+
let m = /^#([0-9a-f]{3,4})$/i.exec(v);
|
|
286
|
+
if (m) {
|
|
287
|
+
const h = m[1];
|
|
288
|
+
const d = (i) => parseInt(h[i] + h[i], 16);
|
|
289
|
+
return [d(0), d(1), d(2), h.length === 4 ? d(3) / 255 : 1];
|
|
290
|
+
}
|
|
291
|
+
m = /^#([0-9a-f]{6})([0-9a-f]{2})?$/i.exec(v);
|
|
292
|
+
if (m) {
|
|
293
|
+
const n = parseInt(m[1], 16);
|
|
294
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255, m[2] ? parseInt(m[2], 16) / 255 : 1];
|
|
295
|
+
}
|
|
296
|
+
m = /^rgba?\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*(?:,\s*(-?[\d.]+)\s*)?\)$/i.exec(v);
|
|
297
|
+
if (m) return [Number(m[1]), Number(m[2]), Number(m[3]), m[4] === void 0 ? 1 : Number(m[4])];
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
function rgbInterp(a, b, fallback = () => null) {
|
|
301
|
+
const ca = parseCssColor(a) ?? fallback(a), cb = parseCssColor(b) ?? fallback(b);
|
|
302
|
+
if (!ca || !cb) return (p) => p >= 1 ? b : a;
|
|
303
|
+
return (p) => {
|
|
304
|
+
if (p === 0) return a;
|
|
305
|
+
if (p === 1) return b;
|
|
306
|
+
const ch = (i) => Math.round(ca[i] + (cb[i] - ca[i]) * p);
|
|
307
|
+
const al = Math.round((ca[3] + (cb[3] - ca[3]) * p) * 1e4) / 1e4;
|
|
308
|
+
return `rgba(${ch(0)},${ch(1)},${ch(2)},${al})`;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/core/pure/props.ts
|
|
313
|
+
var DEG = Math.PI / 180;
|
|
314
|
+
var num = (obj, key, id, unit = 1) => ({
|
|
315
|
+
id,
|
|
316
|
+
kind: "num",
|
|
317
|
+
unit,
|
|
318
|
+
round: 1e6,
|
|
319
|
+
get: () => Number(obj()?.[key]),
|
|
320
|
+
set: (v) => {
|
|
321
|
+
const o = obj();
|
|
322
|
+
if (o) o[key] = v;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
function xy(target, base, which, unit = 1) {
|
|
326
|
+
const o = () => target[base];
|
|
327
|
+
const ax = num(o, "x", `${base}.x`, unit), ay = num(o, "y", `${base}.y`, unit);
|
|
328
|
+
return which === "x" ? [ax] : which === "y" ? [ay] : [ax, ay];
|
|
329
|
+
}
|
|
330
|
+
var VEC = [
|
|
331
|
+
["scale", "scale", 1],
|
|
332
|
+
["anchor", "anchor", 1],
|
|
333
|
+
["pivot", "pivot", 1],
|
|
334
|
+
["skew", "skew", DEG],
|
|
335
|
+
["position", "position", 1],
|
|
336
|
+
["tilePosition", "tilePosition", 1],
|
|
337
|
+
["tileScale", "tileScale", 1]
|
|
338
|
+
];
|
|
339
|
+
var PIXI_INERT = /* @__PURE__ */ new Set(["fillColor", "fillAlpha"]);
|
|
340
|
+
function pixiAccessors(target, key) {
|
|
341
|
+
for (const [name, base, unit] of VEC) {
|
|
342
|
+
if (key === name) return xy(target, base, "both", unit);
|
|
343
|
+
if (key === `${name}X`) return xy(target, base, "x", unit);
|
|
344
|
+
if (key === `${name}Y`) return xy(target, base, "y", unit);
|
|
345
|
+
}
|
|
346
|
+
switch (key) {
|
|
347
|
+
case "rotation":
|
|
348
|
+
return [{ id: "rotation", kind: "num", unit: DEG, round: 1e5, exactEnd: true, get: () => Number(target.rotation), set: (v) => {
|
|
349
|
+
target.rotation = v;
|
|
350
|
+
} }];
|
|
351
|
+
case "tint":
|
|
352
|
+
return [{ id: "tint", kind: "color", unit: 1, round: 1, get: () => Number(target.tint), set: (v) => {
|
|
353
|
+
target.tint = v;
|
|
354
|
+
} }];
|
|
355
|
+
case "autoAlpha":
|
|
356
|
+
return [
|
|
357
|
+
{ id: "alpha", kind: "num", unit: 1, round: 1e6, get: () => Number(target.alpha), set: (v) => {
|
|
358
|
+
target.alpha = v;
|
|
359
|
+
} },
|
|
360
|
+
// `visible` follows the autoAlpha tweens only, not a plain `alpha` tween on the same layer: a channel of its own
|
|
361
|
+
{ id: "visible#auto", kind: "num", unit: 1, round: 1e6, always: true, get: () => Number(target.alpha), set: (v) => {
|
|
362
|
+
target.visible = v !== 0;
|
|
363
|
+
} }
|
|
364
|
+
];
|
|
365
|
+
default:
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function rawAccessor(target, key) {
|
|
370
|
+
return { id: key, kind: "raw", unit: 1, round: 1, get: () => target[key], set: (v) => {
|
|
371
|
+
target[key] = v;
|
|
372
|
+
} };
|
|
373
|
+
}
|
|
374
|
+
function cssAccessor(target, key) {
|
|
375
|
+
return { id: key, kind: "css", unit: 1, round: 1, get: () => target[key], set: (v) => {
|
|
376
|
+
target[key] = v;
|
|
377
|
+
} };
|
|
378
|
+
}
|
|
379
|
+
function plainAccessor(target, key) {
|
|
380
|
+
return { id: key, kind: "num", unit: 1, round: 1e6, get: () => Number(target[key]), set: (v) => {
|
|
381
|
+
target[key] = v;
|
|
382
|
+
} };
|
|
383
|
+
}
|
|
384
|
+
function parseColor(v) {
|
|
385
|
+
if (typeof v === "number") return v;
|
|
386
|
+
if (typeof v !== "string") return null;
|
|
387
|
+
const s = v.trim();
|
|
388
|
+
let m = /^#([0-9a-f]{3})$/i.exec(s);
|
|
389
|
+
if (m) {
|
|
390
|
+
const h = m[1];
|
|
391
|
+
return parseInt(h[0] + h[0] + h[1] + h[1] + h[2] + h[2], 16);
|
|
392
|
+
}
|
|
393
|
+
m = /^#([0-9a-f]{6})(?:[0-9a-f]{2})?$/i.exec(s);
|
|
394
|
+
if (m) return parseInt(m[1], 16);
|
|
395
|
+
m = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(s);
|
|
396
|
+
if (m) return Number(m[1]) << 16 | Number(m[2]) << 8 | Number(m[3]);
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
function lerpColor(from, to, p) {
|
|
400
|
+
const r = lerpByte(from >> 16 & 255, to >> 16 & 255, p);
|
|
401
|
+
const g = lerpByte(from >> 8 & 255, to >> 8 & 255, p);
|
|
402
|
+
const b = lerpByte(from & 255, to & 255, p);
|
|
403
|
+
return r << 16 | g << 8 | b;
|
|
404
|
+
}
|
|
405
|
+
function lerpByte(a, b, p) {
|
|
406
|
+
return Math.trunc(a + (b - a) * p);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// src/core/pure/PureTimeline.ts
|
|
410
|
+
var quantize = (x) => Math.round(x * 1e7) / 1e7 || 0;
|
|
411
|
+
var TINY = 1e-8;
|
|
412
|
+
var spacer = (duration) => ({ spacer: true, duration });
|
|
413
|
+
var parseRel = (v) => {
|
|
414
|
+
if (typeof v === "number") return { rel: false, n: v };
|
|
415
|
+
if (typeof v === "string") {
|
|
416
|
+
const m = /^([+-])=\s*(-?\d*\.?\d+(?:e[+-]?\d+)?)$/i.exec(v.trim());
|
|
417
|
+
if (m) return { rel: true, n: (m[1] === "-" ? -1 : 1) * parseFloat(m[2]) };
|
|
418
|
+
const n = parseFloat(v);
|
|
419
|
+
if (Number.isFinite(n) && String(n) === v.trim()) return { rel: false, n };
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
};
|
|
423
|
+
var RESERVED = /* @__PURE__ */ new Set(["duration", "ease", "repeat", "yoyo", "repeatDelay", "onUpdate", "delay"]);
|
|
424
|
+
var CALLBACKS = ["onStart", "onComplete", "onRepeat", "onReverseComplete"];
|
|
425
|
+
var saidCallbacks = false;
|
|
426
|
+
var PureTimeline = class _PureTimeline {
|
|
427
|
+
defaultEase;
|
|
428
|
+
channels = /* @__PURE__ */ new Map();
|
|
429
|
+
channelList = [];
|
|
430
|
+
children = [];
|
|
431
|
+
spans = 0;
|
|
432
|
+
now = 0;
|
|
433
|
+
order = 0;
|
|
434
|
+
killed = false;
|
|
435
|
+
prepared = false;
|
|
436
|
+
constructor(opts = {}) {
|
|
437
|
+
this.defaultEase = opts.defaults?.ease ?? "none";
|
|
438
|
+
}
|
|
439
|
+
// --- building ------------------------------------------------------------------------------------------
|
|
440
|
+
/** Adds a child timeline (played with its local time) or a spacer that lengthens this one. */
|
|
441
|
+
add(child, at) {
|
|
442
|
+
const start = at ?? this.spans;
|
|
443
|
+
if ("spacer" in child) {
|
|
444
|
+
this.spans = Math.max(this.spans, start + child.duration);
|
|
445
|
+
} else if (!(child instanceof _PureTimeline)) {
|
|
446
|
+
this.spans = Math.max(this.spans, start + child.duration());
|
|
447
|
+
} else {
|
|
448
|
+
this.children.push({ child, start: quantize(start), order: this.order++, exclusive: false, last: NaN });
|
|
449
|
+
this.prepared = false;
|
|
450
|
+
this.spans = Math.max(this.spans, start + child.duration());
|
|
451
|
+
}
|
|
452
|
+
return this;
|
|
453
|
+
}
|
|
454
|
+
set(target, vars, at) {
|
|
455
|
+
return this.build(target, null, { ...vars, duration: 0 }, at, "set");
|
|
456
|
+
}
|
|
457
|
+
to(target, vars, at) {
|
|
458
|
+
return this.build(target, null, vars, at, "to");
|
|
459
|
+
}
|
|
460
|
+
from(target, vars, at) {
|
|
461
|
+
return this.build(target, null, vars, at, "from");
|
|
462
|
+
}
|
|
463
|
+
fromTo(target, fromVars, toVars, at) {
|
|
464
|
+
return this.build(target, fromVars, toVars, at, "fromTo");
|
|
465
|
+
}
|
|
466
|
+
build(target, fromVars, vars, at, kind) {
|
|
467
|
+
const t = target;
|
|
468
|
+
const start = quantize((at ?? this.spans) + (Number(vars.delay) || 0));
|
|
469
|
+
const dur = quantize(Math.max(0, vars.duration ?? 0));
|
|
470
|
+
for (const cb of CALLBACKS) if (cb in vars) {
|
|
471
|
+
if (!saidCallbacks) {
|
|
472
|
+
saidCallbacks = true;
|
|
473
|
+
console.warn(`pixi-effects: the timeline does not run ${cb}: what a tween does must be a value of the time (use onUpdate for a redraw); it is ignored`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const repeat = Math.max(0, Math.floor(vars.repeat ?? 0));
|
|
477
|
+
const yoyo = !!vars.yoyo;
|
|
478
|
+
const repeatDelay = Math.max(0, vars.repeatDelay ?? 0);
|
|
479
|
+
const easeName = vars.ease ?? this.defaultEase;
|
|
480
|
+
const ease = typeof easeName === "function" ? easeName : pureEase(easeName);
|
|
481
|
+
const given = (v) => {
|
|
482
|
+
const out = /* @__PURE__ */ new Map();
|
|
483
|
+
for (const key of Object.keys(v)) {
|
|
484
|
+
if (RESERVED.has(key) || key === "pixi" || CALLBACKS.includes(key)) continue;
|
|
485
|
+
const value = v[key];
|
|
486
|
+
const acc = parseRel(value) ? plainAccessor(t, key) : typeof value === "string" && parseCssColor(value) ? cssAccessor(t, key) : rawAccessor(t, key);
|
|
487
|
+
out.set(acc.id, { acc, value });
|
|
488
|
+
}
|
|
489
|
+
if (v.pixi) for (const key of Object.keys(v.pixi)) {
|
|
490
|
+
const accs = pixiAccessors(t, key);
|
|
491
|
+
if (!accs) {
|
|
492
|
+
if (!PIXI_INERT.has(key)) console.warn(`pixi-effects: the timeline has no "${key}" shorthand yet; it is ignored`);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
for (const acc of accs) out.set(acc.id, { acc, value: v.pixi[key] });
|
|
496
|
+
}
|
|
497
|
+
return out;
|
|
498
|
+
};
|
|
499
|
+
const ends = given(vars);
|
|
500
|
+
const starts = fromVars ? given(fromVars) : /* @__PURE__ */ new Map();
|
|
501
|
+
const ids = kind === "fromTo" ? [.../* @__PURE__ */ new Set([...starts.keys(), ...ends.keys()])] : [...ends.keys()];
|
|
502
|
+
let lastAlpha;
|
|
503
|
+
for (const id of ids) {
|
|
504
|
+
const e = ends.get(id), f = starts.get(id);
|
|
505
|
+
const acc = (e ?? f).acc;
|
|
506
|
+
const ch = this.channel(t, acc);
|
|
507
|
+
const cur = acc.get();
|
|
508
|
+
const color = acc.kind === "color";
|
|
509
|
+
const endSpec = e ? read(e.value, acc) : null;
|
|
510
|
+
if (e && !endSpec && acc.kind === "color") console.warn(`pixi-effects: the timeline cannot read the colour ${JSON.stringify(e.value)} (use #rgb, #rrggbb, rgb(...) or a number); this tween is skipped`);
|
|
511
|
+
const fromSpec = f ? read(f.value, acc) : null;
|
|
512
|
+
let from = null, to, toRel = false;
|
|
513
|
+
if (kind === "from") {
|
|
514
|
+
const g = endSpec ?? { rel: false, n: cur };
|
|
515
|
+
from = g.rel ? cur + g.n : g.n;
|
|
516
|
+
to = cur;
|
|
517
|
+
acc.set(from);
|
|
518
|
+
} else if (kind === "fromTo") {
|
|
519
|
+
if (fromSpec) from = fromSpec.rel ? cur + fromSpec.n : fromSpec.n;
|
|
520
|
+
if (endSpec) {
|
|
521
|
+
to = endSpec.n;
|
|
522
|
+
toRel = endSpec.rel;
|
|
523
|
+
} else to = cur;
|
|
524
|
+
if (from !== null) acc.set(from);
|
|
525
|
+
} else {
|
|
526
|
+
if (!endSpec) continue;
|
|
527
|
+
to = endSpec.n;
|
|
528
|
+
toRel = endSpec.rel;
|
|
529
|
+
}
|
|
530
|
+
if (color && toRel) toRel = false;
|
|
531
|
+
const seg = {
|
|
532
|
+
channel: ch,
|
|
533
|
+
kind,
|
|
534
|
+
createCur: cur,
|
|
535
|
+
start,
|
|
536
|
+
dur,
|
|
537
|
+
ease,
|
|
538
|
+
repeat,
|
|
539
|
+
yoyo,
|
|
540
|
+
repeatDelay,
|
|
541
|
+
from,
|
|
542
|
+
to,
|
|
543
|
+
toRel,
|
|
544
|
+
from0: from,
|
|
545
|
+
to0: to,
|
|
546
|
+
toRel0: toRel,
|
|
547
|
+
onUpdate: vars.onUpdate,
|
|
548
|
+
order: this.order++
|
|
549
|
+
};
|
|
550
|
+
if (id === "visible#auto") seg.partner = lastAlpha;
|
|
551
|
+
else if (id === "alpha") lastAlpha = seg;
|
|
552
|
+
ch.segs.push(seg);
|
|
553
|
+
ch.dirty = true;
|
|
554
|
+
this.prepared = false;
|
|
555
|
+
}
|
|
556
|
+
const total = dur * (repeat + 1) + repeatDelay * repeat;
|
|
557
|
+
this.spans = Math.max(this.spans, start + total);
|
|
558
|
+
return this;
|
|
559
|
+
}
|
|
560
|
+
channel(target, acc) {
|
|
561
|
+
let m = this.channels.get(target);
|
|
562
|
+
if (!m) this.channels.set(target, m = /* @__PURE__ */ new Map());
|
|
563
|
+
let ch = m.get(acc.id);
|
|
564
|
+
if (!ch) {
|
|
565
|
+
ch = { target, acc, pre: NaN, last: NaN, segs: [], dirty: false };
|
|
566
|
+
m.set(acc.id, ch);
|
|
567
|
+
this.channelList.push(ch);
|
|
568
|
+
}
|
|
569
|
+
return ch;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* A property moved by a function of the caller (a colour in OKLab, a gradient): `to` and `from` say how to get the two ends from
|
|
573
|
+
* the value before the segment, `make` the interpolator between them. The value is only written while the segment is the last
|
|
574
|
+
* one that has started, so nothing is read or kept between two frames.
|
|
575
|
+
*/
|
|
576
|
+
tweenValue(spec) {
|
|
577
|
+
const acc = { id: spec.id, kind: "fn", unit: 1, round: 1, get: spec.get, set: spec.set, make: spec.make };
|
|
578
|
+
const ch = this.channel(spec.holder, acc);
|
|
579
|
+
const start = quantize(spec.at);
|
|
580
|
+
const dur = quantize(Math.max(0, spec.duration));
|
|
581
|
+
const repeat = Math.max(0, Math.floor(spec.repeat ?? 0));
|
|
582
|
+
const repeatDelay = Math.max(0, spec.repeatDelay ?? 0);
|
|
583
|
+
const ease = typeof spec.ease === "function" ? spec.ease : pureEase(spec.ease);
|
|
584
|
+
ch.segs.push({
|
|
585
|
+
channel: ch,
|
|
586
|
+
kind: "to",
|
|
587
|
+
createCur: null,
|
|
588
|
+
start,
|
|
589
|
+
dur,
|
|
590
|
+
ease,
|
|
591
|
+
repeat,
|
|
592
|
+
yoyo: !!spec.yoyo,
|
|
593
|
+
repeatDelay,
|
|
594
|
+
from: null,
|
|
595
|
+
to: null,
|
|
596
|
+
toRel: false,
|
|
597
|
+
from0: null,
|
|
598
|
+
to0: null,
|
|
599
|
+
toRel0: false,
|
|
600
|
+
order: this.order++,
|
|
601
|
+
fnFrom: spec.from,
|
|
602
|
+
fnTo: spec.to,
|
|
603
|
+
fnMake: spec.make,
|
|
604
|
+
write: spec.set
|
|
605
|
+
});
|
|
606
|
+
ch.dirty = true;
|
|
607
|
+
this.prepared = false;
|
|
608
|
+
this.spans = Math.max(this.spans, start + dur * (repeat + 1) + repeatDelay * repeat);
|
|
609
|
+
return this;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* A write that is undone when time goes back before it: the property is `value` from `at` on, and what it was before otherwise.
|
|
613
|
+
* `holder` and `id` name the property, so a set and the tweens of the same property are one channel; `write` is the way the caller
|
|
614
|
+
* writes it (it may do more than assign: redraw), and runs again whenever this set is what the property shows.
|
|
615
|
+
*/
|
|
616
|
+
setValue(holder, id, at, read2, write2, value) {
|
|
617
|
+
const acc = { id, kind: typeof value === "number" ? "num" : "raw", unit: 1, round: 1e6, get: read2, set: write2 };
|
|
618
|
+
const ch = this.channel(holder, acc);
|
|
619
|
+
ch.segs.push({
|
|
620
|
+
channel: ch,
|
|
621
|
+
kind: "set",
|
|
622
|
+
createCur: null,
|
|
623
|
+
start: quantize(at),
|
|
624
|
+
dur: 0,
|
|
625
|
+
ease: pureEase("none"),
|
|
626
|
+
repeat: 0,
|
|
627
|
+
yoyo: false,
|
|
628
|
+
repeatDelay: 0,
|
|
629
|
+
from: null,
|
|
630
|
+
to: value,
|
|
631
|
+
toRel: false,
|
|
632
|
+
from0: null,
|
|
633
|
+
to0: value,
|
|
634
|
+
toRel0: false,
|
|
635
|
+
order: this.order++,
|
|
636
|
+
step: true,
|
|
637
|
+
write: write2,
|
|
638
|
+
onUpdate: () => write2(read2())
|
|
639
|
+
});
|
|
640
|
+
ch.dirty = true;
|
|
641
|
+
this.prepared = false;
|
|
642
|
+
this.spans = Math.max(this.spans, quantize(at));
|
|
643
|
+
return this;
|
|
644
|
+
}
|
|
645
|
+
// --- reading -------------------------------------------------------------------------------------------
|
|
646
|
+
/** What the timeline will write, for tools and tests: every segment of this timeline and of the ones under it, starts in this timeline's time. */
|
|
647
|
+
segments(offset = 0) {
|
|
648
|
+
const out = [];
|
|
649
|
+
for (const ch of this.channelList) {
|
|
650
|
+
for (const s of ch.segs) {
|
|
651
|
+
out.push({ target: ch.target, id: ch.acc.id, start: s.start + offset, duration: s.dur, repeat: s.repeat, yoyo: s.yoyo, repeatDelay: s.repeatDelay, kind: s.step ? "set" : s.kind });
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
for (const c of this.children) out.push(...c.child.segments(offset + c.start));
|
|
655
|
+
return out;
|
|
656
|
+
}
|
|
657
|
+
/** How many timelines are directly under this one. */
|
|
658
|
+
timelines() {
|
|
659
|
+
return this.children.length;
|
|
660
|
+
}
|
|
661
|
+
duration() {
|
|
662
|
+
return this.spans;
|
|
663
|
+
}
|
|
664
|
+
time(value) {
|
|
665
|
+
if (value === void 0) return this.now;
|
|
666
|
+
if (this.killed) return this;
|
|
667
|
+
this.now = value;
|
|
668
|
+
if (!this.prepared) {
|
|
669
|
+
this.prepareDeep();
|
|
670
|
+
const counts = /* @__PURE__ */ new Map();
|
|
671
|
+
this.countChannels(counts);
|
|
672
|
+
this.markExclusive(counts);
|
|
673
|
+
}
|
|
674
|
+
this.evaluate(quantize(value));
|
|
675
|
+
return this;
|
|
676
|
+
}
|
|
677
|
+
/** GSAP's name for `time(t)`. */
|
|
678
|
+
seek(t) {
|
|
679
|
+
return this.time(t);
|
|
680
|
+
}
|
|
681
|
+
progress(p) {
|
|
682
|
+
if (p === void 0) return this.spans > 0 ? this.now / this.spans : 0;
|
|
683
|
+
return this.time(p * this.spans);
|
|
684
|
+
}
|
|
685
|
+
kill() {
|
|
686
|
+
this.killed = true;
|
|
687
|
+
this.channels.clear();
|
|
688
|
+
this.channelList.length = 0;
|
|
689
|
+
this.children.length = 0;
|
|
690
|
+
}
|
|
691
|
+
// --- evaluation ----------------------------------------------------------------------------------------
|
|
692
|
+
/**
|
|
693
|
+
* What GSAP ended up with once it had been played to the end and back (what Movie used to do at build), as rules that depend
|
|
694
|
+
* on the segments of a property only:
|
|
695
|
+
* - a `from` / `fromTo` shows its start from the moment it is built, so a `to` that comes first starts at the start of the
|
|
696
|
+
* `from` built last, else at the property's own value;
|
|
697
|
+
* - a `to` (and a `set`) starts where the segment before it ended;
|
|
698
|
+
* - a `from` ends where the segment before it ended, or, with none before, where the property was when it was built;
|
|
699
|
+
* - before the first segment the property shows that segment's start.
|
|
700
|
+
*/
|
|
701
|
+
prepare(ch) {
|
|
702
|
+
if (!ch.dirty) return;
|
|
703
|
+
ch.segs.sort((a, b) => a.start - b.start || a.order - b.order);
|
|
704
|
+
ch.dirty = false;
|
|
705
|
+
let latest = null;
|
|
706
|
+
for (const s of ch.segs) if ((s.kind === "from" || s.kind === "fromTo") && s.from0 !== null && (!latest || s.order > latest.order)) latest = s;
|
|
707
|
+
ch.base0 ??= { v: ch.acc.get() };
|
|
708
|
+
let cur = latest ? latest.from0 : ch.base0.v;
|
|
709
|
+
const base = cur;
|
|
710
|
+
let first = true;
|
|
711
|
+
for (const s of ch.segs) {
|
|
712
|
+
const before = cur;
|
|
713
|
+
s.from = s.from0;
|
|
714
|
+
s.to = s.to0;
|
|
715
|
+
s.toRel = s.toRel0;
|
|
716
|
+
if (s.fnTo) {
|
|
717
|
+
s.from = s.fnFrom ? s.fnFrom(cur) : cur;
|
|
718
|
+
s.to = s.fnTo(s.from, before, base);
|
|
719
|
+
s.interp = void 0;
|
|
720
|
+
} else {
|
|
721
|
+
if (s.partner) {
|
|
722
|
+
s.from = s.partner.from;
|
|
723
|
+
s.to = s.partner.to;
|
|
724
|
+
}
|
|
725
|
+
if (s.from === null) s.from = cur;
|
|
726
|
+
if (s.kind === "from") s.to = first ? s.createCur : cur;
|
|
727
|
+
if (s.toRel) {
|
|
728
|
+
s.to = s.from + s.to;
|
|
729
|
+
s.toRel = false;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
if (first) ch.pre = s.fnTo ? before : s.from;
|
|
733
|
+
cur = endValue(s);
|
|
734
|
+
first = false;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
/** Every channel of this timeline and of its children reads the property it starts from before any of them writes. */
|
|
738
|
+
prepareDeep() {
|
|
739
|
+
if (this.prepared) return;
|
|
740
|
+
this.prepared = true;
|
|
741
|
+
for (const ch of this.channelList) this.prepare(ch);
|
|
742
|
+
this.children.sort((a, b) => a.start - b.start || a.order - b.order);
|
|
743
|
+
for (const c of this.children) {
|
|
744
|
+
c.last = NaN;
|
|
745
|
+
c.child.prepareDeep();
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/** How many channels write each (target, property) in this timeline and everything under it. */
|
|
749
|
+
countChannels(into) {
|
|
750
|
+
for (const ch of this.channelList) {
|
|
751
|
+
let m = into.get(ch.target);
|
|
752
|
+
if (!m) into.set(ch.target, m = /* @__PURE__ */ new Map());
|
|
753
|
+
m.set(ch.acc.id, (m.get(ch.acc.id) ?? 0) + 1);
|
|
754
|
+
}
|
|
755
|
+
for (const c of this.children) c.child.countChannels(into);
|
|
756
|
+
}
|
|
757
|
+
isExclusive(counts) {
|
|
758
|
+
for (const ch of this.channelList) if ((counts.get(ch.target)?.get(ch.acc.id) ?? 0) > 1) return false;
|
|
759
|
+
return this.children.every((c) => c.child.isExclusive(counts));
|
|
760
|
+
}
|
|
761
|
+
markExclusive(counts) {
|
|
762
|
+
for (const c of this.children) {
|
|
763
|
+
c.exclusive = c.child.isExclusive(counts);
|
|
764
|
+
c.child.markExclusive(counts);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
evaluate(t) {
|
|
768
|
+
this.prepareDeep();
|
|
769
|
+
for (const ch of this.channelList) {
|
|
770
|
+
const segs = ch.segs;
|
|
771
|
+
let lo = 0, hi = segs.length;
|
|
772
|
+
while (lo < hi) {
|
|
773
|
+
const mid = lo + hi >> 1;
|
|
774
|
+
if (segs[mid].start <= t + TINY) lo = mid + 1;
|
|
775
|
+
else hi = mid;
|
|
776
|
+
}
|
|
777
|
+
let k = lo - 1;
|
|
778
|
+
while (k >= 0 && segs[k].repeat > 0 && t - segs[k].start <= TINY) k--;
|
|
779
|
+
const seg = k >= 0 ? segs[k] : null;
|
|
780
|
+
if (!seg) {
|
|
781
|
+
const pre = settle(ch.acc, ch.pre);
|
|
782
|
+
write(ch, segs[0], pre);
|
|
783
|
+
const head = segs[0];
|
|
784
|
+
if (pre !== ch.last) {
|
|
785
|
+
ch.last = pre;
|
|
786
|
+
head?.onUpdate?.();
|
|
787
|
+
}
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
const v = mix(seg, ratioAt(seg, t), over);
|
|
791
|
+
write(ch, seg, v);
|
|
792
|
+
if (v !== ch.last) {
|
|
793
|
+
ch.last = v;
|
|
794
|
+
seg.onUpdate?.();
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
for (const c of this.children) {
|
|
798
|
+
const local = Math.min(Math.max(t - c.start, 0), c.child.duration());
|
|
799
|
+
if (c.exclusive && local === c.last) continue;
|
|
800
|
+
c.last = local;
|
|
801
|
+
c.child.now = local;
|
|
802
|
+
c.child.evaluate(quantize(local));
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
function write(ch, seg, v) {
|
|
807
|
+
if (!ch.acc.always && ch.acc.get() === v) return;
|
|
808
|
+
(seg?.write ?? ch.acc.set)(v);
|
|
809
|
+
}
|
|
810
|
+
function endValue(s) {
|
|
811
|
+
if (s.dur === 0 && s.repeat === 0) return s.to;
|
|
812
|
+
return s.yoyo && s.repeat % 2 === 1 ? s.from : s.to;
|
|
813
|
+
}
|
|
814
|
+
function read(value, acc) {
|
|
815
|
+
if (acc.kind === "raw" || acc.kind === "css") return { rel: false, n: value };
|
|
816
|
+
if (acc.kind === "color") {
|
|
817
|
+
const c = parseColor(value);
|
|
818
|
+
return c === null ? null : { rel: false, n: c };
|
|
819
|
+
}
|
|
820
|
+
const r = parseRel(value);
|
|
821
|
+
return r ? { rel: r.rel, n: r.n * acc.unit } : null;
|
|
822
|
+
}
|
|
823
|
+
function settle(acc, v) {
|
|
824
|
+
return acc.kind !== "num" ? v : Math.round(v * acc.round) / acc.round;
|
|
825
|
+
}
|
|
826
|
+
var over = false;
|
|
827
|
+
function mix(s, r, ended) {
|
|
828
|
+
const acc = s.channel.acc;
|
|
829
|
+
if (s.step) return s.to;
|
|
830
|
+
if (s.fnMake) {
|
|
831
|
+
const interp = s.interp ??= s.fnMake(s.from, s.to);
|
|
832
|
+
return interp(Math.round(r * 1e6) / 1e6);
|
|
833
|
+
}
|
|
834
|
+
if (acc.kind === "raw") return s.to;
|
|
835
|
+
if (acc.kind === "css") return (s.interp ??= rgbInterp(String(s.from), String(s.to)))(r);
|
|
836
|
+
if (acc.kind === "color") return ended ? endValue(s) : lerpColor(s.from, s.to, r);
|
|
837
|
+
if ((ended || r === 1) && acc.exactEnd) return endValue(s);
|
|
838
|
+
const k = acc.round;
|
|
839
|
+
return Math.round((s.from + (s.to - s.from) * r) * k) / k;
|
|
840
|
+
}
|
|
841
|
+
function ratioAt(s, t) {
|
|
842
|
+
const lt = t - s.start;
|
|
843
|
+
over = true;
|
|
844
|
+
if (s.dur === 0) return 1;
|
|
845
|
+
const total = s.dur * (s.repeat + 1) + s.repeatDelay * s.repeat;
|
|
846
|
+
if (quantize(lt) >= quantize(total) - TINY) return endRatio(s);
|
|
847
|
+
over = false;
|
|
848
|
+
let i = 0;
|
|
849
|
+
let within = lt;
|
|
850
|
+
if (s.repeat > 0) {
|
|
851
|
+
const period = s.dur + s.repeatDelay;
|
|
852
|
+
const q = quantize(lt);
|
|
853
|
+
i = Math.min(s.repeat, Math.max(0, Math.floor(lt / period)));
|
|
854
|
+
while (i > 0 && q <= quantize(i * period)) i--;
|
|
855
|
+
while (i < s.repeat && q > quantize((i + 1) * period)) i++;
|
|
856
|
+
within = quantize(lt - i * period);
|
|
857
|
+
}
|
|
858
|
+
let p = within >= s.dur ? 1 : within <= 0 ? 0 : within / s.dur;
|
|
859
|
+
if (s.yoyo && i % 2 === 1) p = 1 - p;
|
|
860
|
+
return s.ease(p);
|
|
861
|
+
}
|
|
862
|
+
function endRatio(s) {
|
|
863
|
+
return s.yoyo && s.repeat % 2 === 1 ? 0 : 1;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// src/core/timelineEngine.ts
|
|
867
|
+
function createTimeline(opts = {}) {
|
|
868
|
+
return new PureTimeline({ paused: opts.paused, defaults: { ease: opts.defaults?.ease ?? "power1.out" } });
|
|
869
|
+
}
|
|
870
|
+
function lengthen(timeline, duration) {
|
|
871
|
+
timeline.add(spacer(duration));
|
|
872
|
+
}
|
|
873
|
+
function parseEase(name) {
|
|
874
|
+
return pureEase(name);
|
|
875
|
+
}
|
|
876
|
+
function setNow(target, vars) {
|
|
877
|
+
const t = target;
|
|
878
|
+
for (const key of Object.keys(vars)) {
|
|
879
|
+
if (key === "pixi") {
|
|
880
|
+
for (const k of Object.keys(vars.pixi)) {
|
|
881
|
+
const accs = pixiAccessors(t, k);
|
|
882
|
+
if (!accs) {
|
|
883
|
+
if (!PIXI_INERT.has(k)) console.warn(`pixi-effects: "${k}" is not a property a keyframe or initial can set; it is ignored`);
|
|
884
|
+
continue;
|
|
885
|
+
}
|
|
886
|
+
const raw = vars.pixi[k];
|
|
887
|
+
for (const acc of accs) {
|
|
888
|
+
const n = acc.kind === "color" ? colorNumber(raw) : Number(raw) * acc.unit;
|
|
889
|
+
if (!Number.isNaN(n)) acc.set(n);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
} else {
|
|
893
|
+
const v = vars[key];
|
|
894
|
+
plainAccessor(t, key).set(typeof v === "number" ? Math.round(v * 1e6) / 1e6 : v);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
function colorNumber(v) {
|
|
899
|
+
const c = parseColor(v);
|
|
900
|
+
if (c === null) {
|
|
901
|
+
console.warn(`pixi-effects: cannot read the colour ${JSON.stringify(v)} (use #rgb, #rrggbb, rgb(...) or a number); it is left as it was`);
|
|
902
|
+
return NaN;
|
|
903
|
+
}
|
|
904
|
+
return c;
|
|
905
|
+
}
|
|
906
|
+
function viaPixi(s) {
|
|
907
|
+
try {
|
|
908
|
+
const [r, g, b, a] = new PIXI.Color(s).toArray();
|
|
909
|
+
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
|
|
910
|
+
} catch {
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
function interpolateColors(a, b) {
|
|
915
|
+
return rgbInterp(a, b, viaPixi);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// src/expr/random.ts
|
|
919
|
+
function mix2(h) {
|
|
920
|
+
h = Math.imul(h ^ h >>> 16, 2246822507);
|
|
921
|
+
h = Math.imul(h ^ h >>> 13, 3266489909);
|
|
922
|
+
return (h ^ h >>> 16) >>> 0;
|
|
923
|
+
}
|
|
924
|
+
function fold(n) {
|
|
925
|
+
if (!Number.isFinite(n)) return 0;
|
|
926
|
+
const i = Math.floor(n);
|
|
927
|
+
const f = n - i;
|
|
928
|
+
return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
|
|
929
|
+
}
|
|
930
|
+
function rand(seed) {
|
|
931
|
+
return mix2(fold(seed) + 2654435769) / 4294967296;
|
|
932
|
+
}
|
|
933
|
+
function random(seed) {
|
|
934
|
+
let a = fold(seed) + 1831565813 | 0;
|
|
935
|
+
return () => {
|
|
936
|
+
a = a + 1831565813 | 0;
|
|
937
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
938
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
939
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
function noise(x, seed = 0) {
|
|
943
|
+
if (!Number.isFinite(x)) return 0;
|
|
944
|
+
const i = Math.floor(x);
|
|
945
|
+
const f = x - i;
|
|
946
|
+
const s = fold(seed) * 668265261;
|
|
947
|
+
const a = mix2((i | 0) + s) / 2147483648 - 1;
|
|
948
|
+
const b = mix2((i + 1 | 0) + s) / 2147483648 - 1;
|
|
949
|
+
const u = f * f * f * (f * (f * 6 - 15) + 10);
|
|
950
|
+
return a + (b - a) * u;
|
|
951
|
+
}
|
|
169
952
|
|
|
170
953
|
// src/expr/Parser.ts
|
|
171
954
|
var FUNCS = {
|
|
@@ -326,7 +1109,7 @@ function parsePrimary(c) {
|
|
|
326
1109
|
}
|
|
327
1110
|
throw new Error(`unexpected token "${t.type}"`);
|
|
328
1111
|
}
|
|
329
|
-
function
|
|
1112
|
+
function parse2(src) {
|
|
330
1113
|
const c = new Cursor(tokenize(src));
|
|
331
1114
|
const node = parseExpr(c);
|
|
332
1115
|
if (c.peek()) throw new Error("trailing input");
|
|
@@ -376,7 +1159,7 @@ function evaluateExpr(source, scope) {
|
|
|
376
1159
|
let ast = astCache.get(source);
|
|
377
1160
|
if (ast === void 0) {
|
|
378
1161
|
try {
|
|
379
|
-
ast =
|
|
1162
|
+
ast = parse2(source);
|
|
380
1163
|
} catch (e) {
|
|
381
1164
|
console.warn(`pixi-effects: expression failed: ${source}`, e);
|
|
382
1165
|
ast = ZERO_NODE;
|
|
@@ -394,19 +1177,29 @@ function evaluateExpr(source, scope) {
|
|
|
394
1177
|
// src/expr/normalizeProps.ts
|
|
395
1178
|
function normalizeProps(input, scope, options = {}) {
|
|
396
1179
|
const skip = new Set(options.skipKeys ?? []);
|
|
397
|
-
return walk(input, scope, skip, null);
|
|
1180
|
+
return walk(input, scope, skip, null, options);
|
|
398
1181
|
}
|
|
399
|
-
|
|
1182
|
+
var RELATIVE = /^\s*([+-])=([\s\S]*)$/;
|
|
1183
|
+
function walk(value, scope, skip, currentKey, options) {
|
|
400
1184
|
if (Array.isArray(value)) {
|
|
401
|
-
return value.map((v) => walk(v, scope, skip, currentKey));
|
|
1185
|
+
return value.map((v) => walk(v, scope, skip, currentKey, options));
|
|
402
1186
|
}
|
|
403
1187
|
if (value !== null && typeof value === "object") {
|
|
404
1188
|
const out = {};
|
|
405
1189
|
for (const k of Object.keys(value)) {
|
|
406
|
-
out[k] = walk(value[k], scope, skip, k);
|
|
1190
|
+
out[k] = walk(value[k], scope, skip, k, options);
|
|
407
1191
|
}
|
|
408
1192
|
return out;
|
|
409
1193
|
}
|
|
1194
|
+
if (typeof value === "string" && !(currentKey !== null && skip.has(currentKey))) {
|
|
1195
|
+
const rel = RELATIVE.exec(value);
|
|
1196
|
+
if (rel) {
|
|
1197
|
+
const n = evaluateExpr(rel[2].trim(), scope);
|
|
1198
|
+
if (options.relative === "allow") return `${rel[1]}=${n}`;
|
|
1199
|
+
console.warn(`pixi-effects: "${value.trim()}"${currentKey ? ` (${currentKey})` : ""} is a relative value (measured from where the layer is): it works in a keyframe's to / from / set, not in ${options.where ?? "an initial or a style"}; it is read as the number ${rel[1] === "-" ? -n : n}`);
|
|
1200
|
+
return rel[1] === "-" ? -n : n;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
410
1203
|
if (isExpr(value) && !(currentKey !== null && skip.has(currentKey))) {
|
|
411
1204
|
if (looksLikeColorString(value)) return value;
|
|
412
1205
|
return evaluateExpr(value, scope);
|
|
@@ -418,56 +1211,6 @@ function looksLikeColorString(s) {
|
|
|
418
1211
|
if (s.charCodeAt(0) === 35) return true;
|
|
419
1212
|
return /^(rgb|hsl|oklab|oklch|lab|lch)\b/i.test(s);
|
|
420
1213
|
}
|
|
421
|
-
function cubicBezierEase(x1, y1, x2, y2) {
|
|
422
|
-
const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;
|
|
423
|
-
const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;
|
|
424
|
-
const X = (t) => ((ax * t + bx) * t + cx) * t;
|
|
425
|
-
const Y = (t) => ((ay * t + by) * t + cy) * t;
|
|
426
|
-
const dX = (t) => (3 * ax * t + 2 * bx) * t + cx;
|
|
427
|
-
return (p) => {
|
|
428
|
-
if (p <= 0) return 0;
|
|
429
|
-
if (p >= 1) return 1;
|
|
430
|
-
let t = p;
|
|
431
|
-
for (let i = 0; i < 8; i++) {
|
|
432
|
-
const err = X(t) - p;
|
|
433
|
-
if (Math.abs(err) < 1e-9) return Y(t);
|
|
434
|
-
const d = dX(t);
|
|
435
|
-
if (Math.abs(d) < 1e-6) break;
|
|
436
|
-
t -= err / d;
|
|
437
|
-
}
|
|
438
|
-
let lo = 0, hi = 1;
|
|
439
|
-
t = p;
|
|
440
|
-
for (let i = 0; i < 60; i++) {
|
|
441
|
-
const x = X(t);
|
|
442
|
-
if (Math.abs(x - p) < 1e-10) break;
|
|
443
|
-
if (x < p) lo = t;
|
|
444
|
-
else hi = t;
|
|
445
|
-
t = (lo + hi) / 2;
|
|
446
|
-
}
|
|
447
|
-
return Y(t);
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
var NUM = String.raw`\s*(-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)\s*`;
|
|
451
|
-
var RE = new RegExp(`^\\s*cubic-bezier\\(${NUM},${NUM},${NUM},${NUM}\\)\\s*$`, "i");
|
|
452
|
-
function cubicBezierProblem(name) {
|
|
453
|
-
const m = RE.exec(name);
|
|
454
|
-
if (!m) return 'expected "cubic-bezier(x1, y1, x2, y2)" with four numbers, like CSS';
|
|
455
|
-
const x1 = Number(m[1]), x2 = Number(m[3]);
|
|
456
|
-
if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) return "x1 and x2 must be between 0 and 1 (y1 and y2 may overshoot)";
|
|
457
|
-
return null;
|
|
458
|
-
}
|
|
459
|
-
var registered2 = false;
|
|
460
|
-
function registerCubicBezierEase() {
|
|
461
|
-
if (registered2) return;
|
|
462
|
-
registered2 = true;
|
|
463
|
-
const base = ((p) => p);
|
|
464
|
-
base.config = (x1, y1, x2, y2) => {
|
|
465
|
-
const bad = [x1, y1, x2, y2].some((v) => typeof v !== "number" || !Number.isFinite(v)) || x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1;
|
|
466
|
-
return bad ? (p) => p : cubicBezierEase(x1, y1, x2, y2);
|
|
467
|
-
};
|
|
468
|
-
gsap.gsap.registerEase("cubic-bezier", base);
|
|
469
|
-
}
|
|
470
|
-
registerCubicBezierEase();
|
|
471
1214
|
|
|
472
1215
|
// src/core/ease.ts
|
|
473
1216
|
var FAMILIES = ["power1", "power2", "power3", "power4", "back", "elastic", "bounce", "circ", "expo", "sine"];
|
|
@@ -479,7 +1222,7 @@ function checkEase(ease, where) {
|
|
|
479
1222
|
const problem = springProblem(ease);
|
|
480
1223
|
if (!problem || warned.has(ease)) return;
|
|
481
1224
|
warned.add(ease);
|
|
482
|
-
console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}.
|
|
1225
|
+
console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. It runs as its default ease, power1.out.`);
|
|
483
1226
|
return;
|
|
484
1227
|
}
|
|
485
1228
|
if (/^\s*cubic-bezier/i.test(ease)) {
|
|
@@ -489,20 +1232,19 @@ function checkEase(ease, where) {
|
|
|
489
1232
|
console.warn(`pixi-effects: ${where}: unknown ease "${ease}" \u2014 ${problem}. It runs as 'none' (a straight line).`);
|
|
490
1233
|
return;
|
|
491
1234
|
}
|
|
492
|
-
|
|
493
|
-
if (typeof found === "function") return;
|
|
1235
|
+
if (isEaseName(ease)) return;
|
|
494
1236
|
if (warned.has(ease)) return;
|
|
495
1237
|
warned.add(ease);
|
|
496
1238
|
if (ease === "") {
|
|
497
|
-
console.warn(`pixi-effects: ${where}: an empty ease (
|
|
1239
|
+
console.warn(`pixi-effects: ${where}: an empty ease (it would run as power1.out): write 'none' for no easing, or a name such as 'power2.out'`);
|
|
498
1240
|
return;
|
|
499
1241
|
}
|
|
500
|
-
if (
|
|
1242
|
+
if (/^(power[1-4]|quad|cubic|quart|quint|strong|back|elastic|bounce|circ|expo|sine)$/i.test(ease)) {
|
|
501
1243
|
console.warn(`pixi-effects: ${where}: "${ease}" is a family, not an ease \u2014 write ${ease.toLowerCase()}.out, ${ease.toLowerCase()}.in or ${ease.toLowerCase()}.inOut`);
|
|
502
1244
|
return;
|
|
503
1245
|
}
|
|
504
1246
|
const guess = chunkTWZNOUM7_cjs.suggestName(ease, EASE_NAMES);
|
|
505
|
-
console.warn(`pixi-effects: ${where}: unknown ease "${ease}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (
|
|
1247
|
+
console.warn(`pixi-effects: ${where}: unknown ease "${ease}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (it runs as its default ease, power1.out). Examples: ${EASE_NAMES.slice(0, 7).join(", ")}, back.out(1.7), elastic.out(1, 0.3), steps(8)`);
|
|
506
1248
|
}
|
|
507
1249
|
|
|
508
1250
|
// src/core/Timeline.ts
|
|
@@ -604,16 +1346,7 @@ var PIXI_SHORTHANDS = /* @__PURE__ */ new Set([
|
|
|
604
1346
|
"tileScaleX",
|
|
605
1347
|
"tileScaleY",
|
|
606
1348
|
"tint",
|
|
607
|
-
"colorize",
|
|
608
|
-
"colorizeAmount",
|
|
609
|
-
"colorMatrixFilter",
|
|
610
|
-
"blur",
|
|
611
|
-
"blurX",
|
|
612
|
-
"blurY",
|
|
613
|
-
"blurPadding",
|
|
614
1349
|
"autoAlpha",
|
|
615
|
-
"lineColor",
|
|
616
|
-
"lineAlpha",
|
|
617
1350
|
"fillColor",
|
|
618
1351
|
"fillAlpha"
|
|
619
1352
|
]);
|
|
@@ -637,7 +1370,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
637
1370
|
const kf = normalizeKeyframe(raw, parentDuration);
|
|
638
1371
|
const at = offset + kf.at;
|
|
639
1372
|
if (kf.kind === "set") {
|
|
640
|
-
const resolved = normalizeProps(kf.set, scope, { skipKeys });
|
|
1373
|
+
const resolved = normalizeProps(kf.set, scope, { skipKeys, relative: "allow" });
|
|
641
1374
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
642
1375
|
for (const r of routed) timeline.set(r.target, { [r.prop]: r.value }, at);
|
|
643
1376
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
@@ -648,7 +1381,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
648
1381
|
timeline.set(f, props, at);
|
|
649
1382
|
}
|
|
650
1383
|
} else if (kf.kind === "to") {
|
|
651
|
-
const resolved = normalizeProps(kf.to, scope, { skipKeys });
|
|
1384
|
+
const resolved = normalizeProps(kf.to, scope, { skipKeys, relative: "allow" });
|
|
652
1385
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
653
1386
|
for (const r of routed)
|
|
654
1387
|
timeline.to(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
@@ -661,7 +1394,7 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
661
1394
|
timeline.to(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
662
1395
|
}
|
|
663
1396
|
} else if (kf.kind === "from") {
|
|
664
|
-
const resolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
1397
|
+
const resolved = normalizeProps(kf.from, scope, { skipKeys, relative: "allow" });
|
|
665
1398
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
666
1399
|
for (const r of routed)
|
|
667
1400
|
timeline.from(r.target, { [r.prop]: r.value, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
@@ -674,8 +1407,8 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
674
1407
|
timeline.from(f, { ...props, duration: kf.duration, ease: kf.ease, ...kf.loop }, at);
|
|
675
1408
|
}
|
|
676
1409
|
} else {
|
|
677
|
-
const fromResolved = normalizeProps(kf.from, scope, { skipKeys });
|
|
678
|
-
const toResolved = normalizeProps(kf.to, scope, { skipKeys });
|
|
1410
|
+
const fromResolved = normalizeProps(kf.from, scope, { skipKeys, where: "the from side of a from + to keyframe" });
|
|
1411
|
+
const toResolved = normalizeProps(kf.to, scope, { skipKeys, relative: "allow" });
|
|
679
1412
|
const fromRouted = splitRouted(fromResolved, routers);
|
|
680
1413
|
const toRouted = splitRouted(toResolved, routers);
|
|
681
1414
|
const fromByKey = new Map(fromRouted.routed.map((r) => [r.key, r]));
|
|
@@ -725,15 +1458,15 @@ function applyKeyframes(timeline, target, keyframes, parentDuration, scope, skip
|
|
|
725
1458
|
}
|
|
726
1459
|
function applyInitial(target, initial, scope, skipKeys = [], routers) {
|
|
727
1460
|
if (!initial) return;
|
|
728
|
-
const resolved = normalizeProps(initial, scope, { skipKeys });
|
|
1461
|
+
const resolved = normalizeProps(initial, scope, { skipKeys, where: "initial" });
|
|
729
1462
|
const { rest, routed } = splitRouted(resolved, routers);
|
|
730
|
-
for (const r of routed)
|
|
1463
|
+
for (const r of routed) setNow(r.target, { [r.prop]: r.value });
|
|
731
1464
|
const { ownProps, filterProps } = partitionProps(rest);
|
|
732
|
-
if (Object.keys(ownProps).length > 0)
|
|
1465
|
+
if (Object.keys(ownProps).length > 0) setNow(target, pixiwrap(ownProps));
|
|
733
1466
|
for (const [name, props] of Object.entries(filterProps)) {
|
|
734
1467
|
const f = findFilter(target, name);
|
|
735
1468
|
if (!f) continue;
|
|
736
|
-
|
|
1469
|
+
setNow(f, props);
|
|
737
1470
|
}
|
|
738
1471
|
}
|
|
739
1472
|
|
|
@@ -1168,7 +1901,7 @@ var GrainFilter = class extends PIXI.Filter {
|
|
|
1168
1901
|
};
|
|
1169
1902
|
var WARP_KINDS = ["wave", "haze"];
|
|
1170
1903
|
var OPTION_KEYS = ["kind", "strength", "scale", "speed", "angle", "seed"];
|
|
1171
|
-
var
|
|
1904
|
+
var DEG2 = Math.PI / 180;
|
|
1172
1905
|
var HASH_GL2 = `
|
|
1173
1906
|
uint hash(uint x) { x ^= x >> 16; x *= 0x7feb352du; x ^= x >> 15; x *= 0x846ca68bu; x ^= x >> 16; return x; }
|
|
1174
1907
|
float lattice(ivec2 p, uint k) {
|
|
@@ -1340,7 +2073,7 @@ var WarpFilter = class extends PIXI.Filter {
|
|
|
1340
2073
|
uStrength: { value: strength, type: "f32" },
|
|
1341
2074
|
uScale: { value: scale, type: "f32" },
|
|
1342
2075
|
uSpeed: { value: speed, type: "f32" },
|
|
1343
|
-
uAngle: { value: angle *
|
|
2076
|
+
uAngle: { value: angle * DEG2, type: "f32" },
|
|
1344
2077
|
uSeed: { value: Math.floor(seed), type: "f32" },
|
|
1345
2078
|
uMode: { value: kind === "haze" ? 1 : 0, type: "f32" },
|
|
1346
2079
|
uTime: { value: 0, type: "f32" }
|
|
@@ -1378,10 +2111,10 @@ var WarpFilter = class extends PIXI.Filter {
|
|
|
1378
2111
|
this.u.uSpeed = v;
|
|
1379
2112
|
}
|
|
1380
2113
|
get angle() {
|
|
1381
|
-
return this.u.uAngle /
|
|
2114
|
+
return this.u.uAngle / DEG2;
|
|
1382
2115
|
}
|
|
1383
2116
|
set angle(v) {
|
|
1384
|
-
this.u.uAngle = v *
|
|
2117
|
+
this.u.uAngle = v * DEG2;
|
|
1385
2118
|
}
|
|
1386
2119
|
get seed() {
|
|
1387
2120
|
return this.u.uSeed;
|
|
@@ -1659,6 +2392,8 @@ var NullSequence = class extends Sequence {
|
|
|
1659
2392
|
this.buildFilters();
|
|
1660
2393
|
}
|
|
1661
2394
|
};
|
|
2395
|
+
|
|
2396
|
+
// src/core/remap.ts
|
|
1662
2397
|
var BAGS = ["set", "to", "from"];
|
|
1663
2398
|
function timeRemapOf(spec, prop = "time") {
|
|
1664
2399
|
const hasInitial = !!spec.initial && "time" in spec.initial;
|
|
@@ -1739,7 +2474,7 @@ function bindClock(timeline, clock, prop, remap, duration, at, scope) {
|
|
|
1739
2474
|
timeline.fromTo(clock, { [prop]: from }, { [prop]: from + s * duration, duration, ease: "none" }, at);
|
|
1740
2475
|
}
|
|
1741
2476
|
function clockTable(remap, prop, duration, at, scope, to) {
|
|
1742
|
-
const probe =
|
|
2477
|
+
const probe = createTimeline({ paused: true });
|
|
1743
2478
|
const clock = { [prop]: remap.start ?? 0 };
|
|
1744
2479
|
bindClock(probe, clock, prop, remap, duration, at, scope);
|
|
1745
2480
|
probe.time(probe.duration());
|
|
@@ -1771,7 +2506,7 @@ function clockTable(remap, prop, duration, at, scope, to) {
|
|
|
1771
2506
|
}
|
|
1772
2507
|
|
|
1773
2508
|
// src/space/math.ts
|
|
1774
|
-
var
|
|
2509
|
+
var DEG3 = Math.PI / 180;
|
|
1775
2510
|
var DEFAULT_FOV = 40;
|
|
1776
2511
|
var MIN_FOV = 1;
|
|
1777
2512
|
var MAX_FOV = 179;
|
|
@@ -1781,7 +2516,7 @@ function clampFov(fov) {
|
|
|
1781
2516
|
return Math.min(MAX_FOV, Math.max(MIN_FOV, fov));
|
|
1782
2517
|
}
|
|
1783
2518
|
function homeDistance(compHeight, fovDeg) {
|
|
1784
|
-
return compHeight / 2 / Math.tan(clampFov(fovDeg) *
|
|
2519
|
+
return compHeight / 2 / Math.tan(clampFov(fovDeg) * DEG3 / 2);
|
|
1785
2520
|
}
|
|
1786
2521
|
function homeCamera(compW, compH, fov = DEFAULT_FOV) {
|
|
1787
2522
|
return {
|
|
@@ -1835,7 +2570,7 @@ function cameraBasis(cam, compW, compH) {
|
|
|
1835
2570
|
fx,
|
|
1836
2571
|
fy,
|
|
1837
2572
|
fz,
|
|
1838
|
-
focal: compH / 2 / Math.tan(clampFov(cam.fov) *
|
|
2573
|
+
focal: compH / 2 / Math.tan(clampFov(cam.fov) * DEG3 / 2),
|
|
1839
2574
|
halfW: compW / 2,
|
|
1840
2575
|
halfH: compH / 2
|
|
1841
2576
|
};
|
|
@@ -1899,12 +2634,12 @@ function looksLikeLayerName(s) {
|
|
|
1899
2634
|
var isName = (v, known) => typeof v === "string" && (known.has(v) || looksLikeLayerName(v));
|
|
1900
2635
|
function focusNames(props, known) {
|
|
1901
2636
|
const out = [];
|
|
1902
|
-
const
|
|
2637
|
+
const read2 = (bag) => {
|
|
1903
2638
|
const v = bag?.focus;
|
|
1904
2639
|
if (isName(v, known)) out.push(v);
|
|
1905
2640
|
};
|
|
1906
|
-
|
|
1907
|
-
for (const kf of props.keyframes ?? []) for (const bag of [kf.set, kf.to, kf.from])
|
|
2641
|
+
read2(props.initial);
|
|
2642
|
+
for (const kf of props.keyframes ?? []) for (const bag of [kf.set, kf.to, kf.from]) read2(bag);
|
|
1908
2643
|
return out;
|
|
1909
2644
|
}
|
|
1910
2645
|
function withFocusResolved(props, zOf, known = /* @__PURE__ */ new Set()) {
|
|
@@ -1984,7 +2719,7 @@ var CameraSequence = class extends Sequence {
|
|
|
1984
2719
|
carrier.fogColor = "#000000";
|
|
1985
2720
|
carrier.fogAmount = 1;
|
|
1986
2721
|
this.target = carrier;
|
|
1987
|
-
const keys =
|
|
2722
|
+
const keys = chunkZMAD3KJU_cjs.collectPropKeys(this.spec);
|
|
1988
2723
|
this.autoZ = !keys.has("z");
|
|
1989
2724
|
this.dof = keys.has("focus") || keys.has("aperture");
|
|
1990
2725
|
this.fog = keys.has("fogNear") || keys.has("fogFar") || keys.has("fogColor") || keys.has("fogAmount");
|
|
@@ -2069,7 +2804,7 @@ function smoothstep(e0, e1, x) {
|
|
|
2069
2804
|
const t = Math.min(1, Math.max(0, (x - e0) / (e1 - e0)));
|
|
2070
2805
|
return t * t * (3 - 2 * t);
|
|
2071
2806
|
}
|
|
2072
|
-
var
|
|
2807
|
+
var DEG4 = Math.PI / 180;
|
|
2073
2808
|
function norm(v) {
|
|
2074
2809
|
const l = Math.hypot(v.x, v.y, v.z) || 1;
|
|
2075
2810
|
return { x: v.x / l, y: v.y / l, z: v.z / l };
|
|
@@ -2077,7 +2812,7 @@ function norm(v) {
|
|
|
2077
2812
|
var dot = (a, b) => a.x * b.x + a.y * b.y + a.z * b.z;
|
|
2078
2813
|
var sub = (a, b) => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z });
|
|
2079
2814
|
function coneCos(l) {
|
|
2080
|
-
const half = Math.min(179, Math.max(0, l.coneAngle)) *
|
|
2815
|
+
const half = Math.min(179, Math.max(0, l.coneAngle)) * DEG4 / 2;
|
|
2081
2816
|
const inner = half * (1 - Math.min(1, Math.max(0, l.coneFeather)));
|
|
2082
2817
|
const cosOuter = Math.cos(half);
|
|
2083
2818
|
const cosInner = Math.max(Math.cos(inner), cosOuter + 1e-4);
|
|
@@ -2211,24 +2946,8 @@ var LightSequence = class extends Sequence {
|
|
|
2211
2946
|
};
|
|
2212
2947
|
|
|
2213
2948
|
// src/core/revertibleSet.ts
|
|
2214
|
-
function revertibleSet(timeline, at,
|
|
2215
|
-
|
|
2216
|
-
let before;
|
|
2217
|
-
const proxy = {
|
|
2218
|
-
get p() {
|
|
2219
|
-
return p;
|
|
2220
|
-
},
|
|
2221
|
-
set p(next) {
|
|
2222
|
-
if (next >= 1 && p < 1) {
|
|
2223
|
-
before = read();
|
|
2224
|
-
write(value);
|
|
2225
|
-
} else if (next < 1 && p >= 1) {
|
|
2226
|
-
write(before);
|
|
2227
|
-
}
|
|
2228
|
-
p = next;
|
|
2229
|
-
}
|
|
2230
|
-
};
|
|
2231
|
-
timeline.set(proxy, { p: 1 }, at);
|
|
2949
|
+
function revertibleSet(timeline, at, read2, write2, value, property) {
|
|
2950
|
+
timeline.setValue(property?.[0] ?? read2, property?.[1] ?? "set", at, read2, write2, value);
|
|
2232
2951
|
}
|
|
2233
2952
|
|
|
2234
2953
|
// src/expr/colorInterp.ts
|
|
@@ -2367,30 +3086,26 @@ function shortestHueDelta(from, to) {
|
|
|
2367
3086
|
// src/expr/colorTween.ts
|
|
2368
3087
|
var css = (c) => typeof c === "number" ? "#" + c.toString(16).padStart(6, "0") : c;
|
|
2369
3088
|
function tweenColor(timeline, target, key, fromValue, toValue, duration, ease, at, colorSpace, onUpdate, loop = {}) {
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
{
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
...loop,
|
|
2380
|
-
onStart: () => {
|
|
2381
|
-
const start = fromValue !== void 0 ? fromValue : target[key];
|
|
2382
|
-
if (start === void 0) return;
|
|
2383
|
-
interp = colorSpace === "rgb" ? gsap.gsap.utils.interpolate(css(start), css(toValue)) : buildColorInterp(start, toValue, colorSpace);
|
|
2384
|
-
},
|
|
2385
|
-
onUpdate: () => {
|
|
2386
|
-
if (interp) {
|
|
2387
|
-
target[key] = interp(proxy.p);
|
|
2388
|
-
if (onUpdate) onUpdate();
|
|
2389
|
-
}
|
|
2390
|
-
}
|
|
3089
|
+
const none = () => void 0;
|
|
3090
|
+
timeline.tweenValue({
|
|
3091
|
+
holder: target,
|
|
3092
|
+
id: key,
|
|
3093
|
+
get: () => target[key],
|
|
3094
|
+
set: (v) => {
|
|
3095
|
+
if (v === void 0) return;
|
|
3096
|
+
target[key] = v;
|
|
3097
|
+
if (onUpdate) onUpdate();
|
|
2391
3098
|
},
|
|
2392
|
-
|
|
2393
|
-
|
|
3099
|
+
from: fromValue !== void 0 ? () => fromValue : void 0,
|
|
3100
|
+
to: () => toValue,
|
|
3101
|
+
make: (a, b) => a === void 0 ? none : colorSpace === "rgb" ? interpolateColors(css(a), css(b)) : buildColorInterp(a, b, colorSpace),
|
|
3102
|
+
duration,
|
|
3103
|
+
ease,
|
|
3104
|
+
at,
|
|
3105
|
+
repeat: loop.repeat,
|
|
3106
|
+
yoyo: loop.yoyo,
|
|
3107
|
+
repeatDelay: loop.repeatDelay
|
|
3108
|
+
});
|
|
2394
3109
|
}
|
|
2395
3110
|
|
|
2396
3111
|
// src/sequences/Image.ts
|
|
@@ -2433,7 +3148,7 @@ var ImageSequence = class extends Sequence {
|
|
|
2433
3148
|
const sprite = this.target;
|
|
2434
3149
|
revertibleSet(timeline, at, () => sprite.tint, (c) => {
|
|
2435
3150
|
sprite.tint = c;
|
|
2436
|
-
}, setTint);
|
|
3151
|
+
}, setTint, [sprite, "tint"]);
|
|
2437
3152
|
}
|
|
2438
3153
|
if (toTint !== void 0) {
|
|
2439
3154
|
tweenColor(
|
|
@@ -2588,37 +3303,37 @@ function validateGradientKeyframes(spec, who, warn = (m) => console.warn(m), kin
|
|
|
2588
3303
|
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)");
|
|
2589
3304
|
}
|
|
2590
3305
|
function tweenGradient(timeline, holder, fromPatch, toPatch, duration, ease, at, colorSpace, onChange, loop = {}) {
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
ease,
|
|
2599
|
-
...loop,
|
|
2600
|
-
onStart: () => {
|
|
2601
|
-
const live = holder.grad;
|
|
2602
|
-
a = fromPatch !== void 0 ? mergeGrad(live, fromPatch) : live;
|
|
2603
|
-
if (toPatch === void 0) resting ??= live;
|
|
2604
|
-
b = toPatch !== void 0 ? mergeGrad(a, toPatch) : resting;
|
|
2605
|
-
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));
|
|
3306
|
+
timeline.tweenValue({
|
|
3307
|
+
holder,
|
|
3308
|
+
id: "grad",
|
|
3309
|
+
get: () => holder.grad,
|
|
3310
|
+
set: (g) => {
|
|
3311
|
+
holder.grad = g;
|
|
3312
|
+
onChange();
|
|
2606
3313
|
},
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
const
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
3314
|
+
from: fromPatch !== void 0 ? (prev) => mergeGrad(prev, fromPatch) : void 0,
|
|
3315
|
+
to: (start, prev) => toPatch !== void 0 ? mergeGrad(start, toPatch) : prev,
|
|
3316
|
+
make: (a, b) => {
|
|
3317
|
+
const colors = a.stops.map((s, i) => colorSpace === "rgb" ? interpolateColors(s.color, b.stops[i].color) : buildColorInterp(s.color, b.stops[i].color, colorSpace));
|
|
3318
|
+
return (t) => {
|
|
3319
|
+
const l = (x, y) => x + (y - x) * t;
|
|
3320
|
+
return {
|
|
3321
|
+
type: a.type,
|
|
3322
|
+
angle: l(a.angle, b.angle),
|
|
3323
|
+
center: [l(a.center[0], b.center[0]), l(a.center[1], b.center[1])],
|
|
3324
|
+
innerRadius: l(a.innerRadius, b.innerRadius),
|
|
3325
|
+
radius: l(a.radius, b.radius),
|
|
3326
|
+
stops: a.stops.map((s, i) => ({ offset: l(s.offset, b.stops[i].offset), color: colors[i](t) }))
|
|
3327
|
+
};
|
|
2618
3328
|
};
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
3329
|
+
},
|
|
3330
|
+
duration,
|
|
3331
|
+
ease,
|
|
3332
|
+
at,
|
|
3333
|
+
repeat: loop.repeat,
|
|
3334
|
+
yoyo: loop.yoyo,
|
|
3335
|
+
repeatDelay: loop.repeatDelay
|
|
3336
|
+
});
|
|
2622
3337
|
}
|
|
2623
3338
|
var PAINT_SIZE = 512;
|
|
2624
3339
|
var GradientPainter = class {
|
|
@@ -2663,16 +3378,20 @@ function bindGradientKeyframes(timeline, holder, keyframes, duration, offset, co
|
|
|
2663
3378
|
const at = offset + resolveAt(kf.at, duration);
|
|
2664
3379
|
const setV = bag(kf.set), fromV = bag(kf.from), toV = bag(kf.to);
|
|
2665
3380
|
if (setV !== void 0) {
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
() =>
|
|
2670
|
-
(
|
|
2671
|
-
holder.grad =
|
|
3381
|
+
timeline.tweenValue({
|
|
3382
|
+
holder,
|
|
3383
|
+
id: "grad",
|
|
3384
|
+
get: () => holder.grad,
|
|
3385
|
+
set: (g) => {
|
|
3386
|
+
holder.grad = g;
|
|
2672
3387
|
onChange();
|
|
2673
3388
|
},
|
|
2674
|
-
|
|
2675
|
-
|
|
3389
|
+
to: (start) => mergeGrad(start, setV),
|
|
3390
|
+
make: (_a, b) => () => b,
|
|
3391
|
+
duration: 0,
|
|
3392
|
+
ease: "none",
|
|
3393
|
+
at
|
|
3394
|
+
});
|
|
2676
3395
|
}
|
|
2677
3396
|
if (fromV !== void 0 || toV !== void 0) {
|
|
2678
3397
|
tweenGradient(timeline, holder, fromV, toV, kfDuration(kf), kf.ease ?? "none", at, colorSpace, onChange, loopVars(kf));
|
|
@@ -2777,7 +3496,7 @@ var TextSequence = class extends Sequence {
|
|
|
2777
3496
|
this.intrinsicWidth = text.width;
|
|
2778
3497
|
this.intrinsicHeight = text.height;
|
|
2779
3498
|
}
|
|
2780
|
-
validateGradientKeyframes(this.spec,
|
|
3499
|
+
validateGradientKeyframes(this.spec, chunkZMAD3KJU_cjs.describeLayer(this.spec), void 0, "text");
|
|
2781
3500
|
const gradientSpec = this.spec.fillGradient ?? initialProps.fillGradient;
|
|
2782
3501
|
if (gradientSpec) {
|
|
2783
3502
|
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
@@ -2813,7 +3532,7 @@ var TextSequence = class extends Sequence {
|
|
|
2813
3532
|
bindTextKeyframes(timeline, keyframes, this.duration, origin, () => this._template, (t) => {
|
|
2814
3533
|
this._template = t;
|
|
2815
3534
|
refresh();
|
|
2816
|
-
},
|
|
3535
|
+
}, chunkZMAD3KJU_cjs.describeLayer(this.spec));
|
|
2817
3536
|
}
|
|
2818
3537
|
};
|
|
2819
3538
|
function runSuperWithStrippedSpec(inst, strippedSpec, timeline, offset) {
|
|
@@ -2864,7 +3583,7 @@ function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDu
|
|
|
2864
3583
|
revertibleSet(timeline, at, () => state[key], (n) => {
|
|
2865
3584
|
state[key] = n;
|
|
2866
3585
|
refresh();
|
|
2867
|
-
}, v);
|
|
3586
|
+
}, v, [state, key]);
|
|
2868
3587
|
}
|
|
2869
3588
|
if (toV !== void 0 && fromV !== void 0) {
|
|
2870
3589
|
timeline.fromTo(
|
|
@@ -2880,7 +3599,7 @@ function bindCounterKeyframes(timeline, state, key, refresh, keyframes, parentDu
|
|
|
2880
3599
|
}
|
|
2881
3600
|
}
|
|
2882
3601
|
}
|
|
2883
|
-
function bindTextKeyframes(timeline, keyframes, parentDuration, origin,
|
|
3602
|
+
function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read2, write2, who) {
|
|
2884
3603
|
for (const kf of keyframes) {
|
|
2885
3604
|
for (const [what, props] of [["to", kf.to], ["from", kf.from]]) {
|
|
2886
3605
|
if (props && props.text !== void 0) {
|
|
@@ -2889,7 +3608,7 @@ function bindTextKeyframes(timeline, keyframes, parentDuration, origin, read, wr
|
|
|
2889
3608
|
}
|
|
2890
3609
|
const t = kf.set?.text;
|
|
2891
3610
|
if (t === void 0) continue;
|
|
2892
|
-
revertibleSet(timeline, origin + resolveAt(kf.at, parentDuration),
|
|
3611
|
+
revertibleSet(timeline, origin + resolveAt(kf.at, parentDuration), read2, write2, String(t));
|
|
2893
3612
|
}
|
|
2894
3613
|
}
|
|
2895
3614
|
function animates(keyframes, key) {
|
|
@@ -2911,7 +3630,7 @@ function bindFillKeyframes(timeline, text, keyframes, parentDuration, offset, co
|
|
|
2911
3630
|
revertibleSet(timeline, at, () => state.fill, (c) => {
|
|
2912
3631
|
state.fill = c;
|
|
2913
3632
|
writeFill();
|
|
2914
|
-
}, setFill);
|
|
3633
|
+
}, setFill, [state, "fill"]);
|
|
2915
3634
|
}
|
|
2916
3635
|
if (toFill !== void 0) {
|
|
2917
3636
|
tweenColor(
|
|
@@ -2958,12 +3677,12 @@ var AudioSequence = class extends Sequence {
|
|
|
2958
3677
|
const playable = this._remap && this._remap.timeKfs.length > 0 ? Infinity : (data.duration ?? Infinity) / constant;
|
|
2959
3678
|
if (!spec.loop && Number.isFinite(playable) && this.duration > playable + 0.05) {
|
|
2960
3679
|
console.warn(
|
|
2961
|
-
`pixi-effects: ${
|
|
3680
|
+
`pixi-effects: ${chunkZMAD3KJU_cjs.describeLayer(spec)}: audio asset "${spec.asset}" plays for ${playable.toFixed(1)}s (${data.duration.toFixed(1)}s at speed ${constant}) but the layer lasts ${this.duration.toFixed(1)}s, so it goes silent after ${playable.toFixed(1)}s. Add loop: true, or shorten the layer's duration.`
|
|
2962
3681
|
);
|
|
2963
3682
|
}
|
|
2964
3683
|
}
|
|
2965
3684
|
async _buildSfx(spec) {
|
|
2966
|
-
const who =
|
|
3685
|
+
const who = chunkZMAD3KJU_cjs.describeLayer(spec);
|
|
2967
3686
|
const raw = spec;
|
|
2968
3687
|
if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and sfx \u2014 the sfx plays; remove one`);
|
|
2969
3688
|
if (raw.loop) console.warn(`pixi-effects: ${who}: loop has no effect on an sfx \u2014 to repeat it, add one audio layer per hit (a JS loop)`);
|
|
@@ -2982,7 +3701,7 @@ var AudioSequence = class extends Sequence {
|
|
|
2982
3701
|
});
|
|
2983
3702
|
}
|
|
2984
3703
|
async _buildMusic(spec) {
|
|
2985
|
-
const who =
|
|
3704
|
+
const who = chunkZMAD3KJU_cjs.describeLayer(spec);
|
|
2986
3705
|
const raw = spec;
|
|
2987
3706
|
if (raw.asset !== void 0) console.warn(`pixi-effects: ${who}: has both asset and music \u2014 the music plays; remove one`);
|
|
2988
3707
|
if (raw.sfx !== void 0) console.warn(`pixi-effects: ${who}: has both sfx and music \u2014 the music plays; remove one`);
|
|
@@ -3016,7 +3735,7 @@ var AudioSequence = class extends Sequence {
|
|
|
3016
3735
|
out.push({
|
|
3017
3736
|
...sourceMap ? { sourceMap } : {},
|
|
3018
3737
|
...this._audioBuffer ? { buffer: this._audioBuffer } : { synth: this._synth },
|
|
3019
|
-
layer:
|
|
3738
|
+
layer: chunkZMAD3KJU_cjs.describeLayer(this.spec),
|
|
3020
3739
|
source: this._source,
|
|
3021
3740
|
loop: !this._synth && !!this.spec.loop,
|
|
3022
3741
|
start: t0,
|
|
@@ -3067,6 +3786,9 @@ var BUDGET_BYTES = 96 * 1024 * 1024;
|
|
|
3067
3786
|
var MIN_HELD = 3;
|
|
3068
3787
|
var JUMP_SECONDS = 1;
|
|
3069
3788
|
var EPS = 1e-6;
|
|
3789
|
+
var LOW_BEHIND = 14;
|
|
3790
|
+
var MIN_HELD_TO_READ_BACK = 20;
|
|
3791
|
+
var MIN_HELD_TO_READ_START = 9;
|
|
3070
3792
|
function reportDecodeError(err, time) {
|
|
3071
3793
|
const isTransient = err instanceof DOMException && (err.name === "EncodingError" || err.name === "NotSupportedError");
|
|
3072
3794
|
if (isTransient) console.debug("pixi-effects: transient video decode failure at", time, "s \u2014", err.name);
|
|
@@ -3085,9 +3807,22 @@ var FrameCache = class {
|
|
|
3085
3807
|
_held = 0;
|
|
3086
3808
|
_lock = Promise.resolve();
|
|
3087
3809
|
_lastTime = null;
|
|
3810
|
+
_dir = 0;
|
|
3811
|
+
_gen = 0;
|
|
3812
|
+
_backBusy = false;
|
|
3813
|
+
_backGen = 0;
|
|
3814
|
+
_standbyBusy = false;
|
|
3815
|
+
/** A second pass at the start of the file, ready for the moment a looping video comes round. */
|
|
3816
|
+
_standby = null;
|
|
3817
|
+
_duration;
|
|
3818
|
+
_loop;
|
|
3819
|
+
/** How often it had to wait for a decoder (`restarts`, `singles`) and how many reads ahead it made: for tests and for `check`. */
|
|
3820
|
+
stats = { restarts: 0, singles: 0, prefetches: 0 };
|
|
3088
3821
|
constructor(sink, options = {}) {
|
|
3089
3822
|
this.sink = sink;
|
|
3090
3823
|
this.capacity = options.capacity ?? 30;
|
|
3824
|
+
this._duration = options.duration ?? null;
|
|
3825
|
+
this._loop = !!options.loop;
|
|
3091
3826
|
}
|
|
3092
3827
|
/** How many decoded frames are held right now (the sequential reader's own list, plus the exact-time cache of the old path). */
|
|
3093
3828
|
get heldFrames() {
|
|
@@ -3157,24 +3892,157 @@ var FrameCache = class {
|
|
|
3157
3892
|
return null;
|
|
3158
3893
|
}
|
|
3159
3894
|
async _sequentialAt(time) {
|
|
3895
|
+
const last = this._lastTime;
|
|
3896
|
+
this._lastTime = time;
|
|
3897
|
+
if (last !== null && Math.abs(time - last) <= JUMP_SECONDS) this._dir = time > last + EPS ? 1 : time < last - EPS ? -1 : this._dir;
|
|
3898
|
+
let frame;
|
|
3160
3899
|
try {
|
|
3161
|
-
|
|
3162
|
-
this._lastTime = time;
|
|
3163
|
-
const hit = this._covering(time);
|
|
3164
|
-
if (hit) return hit.frame;
|
|
3165
|
-
if (last === null || Math.abs(time - last) > JUMP_SECONDS) return await this._single(time);
|
|
3166
|
-
const cur = this._cur;
|
|
3167
|
-
if (this._iter && cur && time >= cur.ts && time - cur.ts <= JUMP_SECONDS) return await this._advance(time);
|
|
3168
|
-
const backwards = !!cur && time < cur.ts;
|
|
3169
|
-
return await this._restart(time, backwards ? Math.max(0, time - this._held / 30) : time);
|
|
3900
|
+
frame = await this._serve(time, last);
|
|
3170
3901
|
} catch (err) {
|
|
3171
3902
|
reportDecodeError(err, time);
|
|
3172
3903
|
await this._closeIter();
|
|
3173
3904
|
return null;
|
|
3174
3905
|
}
|
|
3906
|
+
this._maybeReadAhead(time);
|
|
3907
|
+
return frame;
|
|
3908
|
+
}
|
|
3909
|
+
async _serve(time, last) {
|
|
3910
|
+
const hit = this._covering(time);
|
|
3911
|
+
if (hit) return hit.frame;
|
|
3912
|
+
const sb = this._standby;
|
|
3913
|
+
if (sb && time >= sb.cur.ts - EPS && time - sb.cur.ts <= JUMP_SECONDS && (!this._iter || !this._cur || this._cur.ts > time + JUMP_SECONDS)) return await this._adoptStandby(time);
|
|
3914
|
+
if (last === null || Math.abs(time - last) > JUMP_SECONDS) return await this._single(time);
|
|
3915
|
+
const cur = this._cur;
|
|
3916
|
+
if (this._iter && cur && time >= cur.ts && time - cur.ts <= JUMP_SECONDS) return await this._advance(time);
|
|
3917
|
+
const backwards = !!cur && time < cur.ts;
|
|
3918
|
+
return await this._restart(time, backwards ? Math.max(0, time - Math.max(1, this._held - 1) / 30) : time);
|
|
3919
|
+
}
|
|
3920
|
+
// ── reading ahead ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
3921
|
+
_maybeReadAhead(time) {
|
|
3922
|
+
if (this._held === 0) return;
|
|
3923
|
+
if (this._dir === -1) {
|
|
3924
|
+
this._dropStandby();
|
|
3925
|
+
let behind = 0, passed = 0, earliest = Infinity;
|
|
3926
|
+
for (const e of this._frames) {
|
|
3927
|
+
if (e.ts < time - EPS) behind++;
|
|
3928
|
+
else if (e.ts > time + EPS) passed++;
|
|
3929
|
+
if (e.ts < earliest) earliest = e.ts;
|
|
3930
|
+
}
|
|
3931
|
+
if (this._held >= MIN_HELD_TO_READ_BACK && behind < LOW_BEHIND && passed >= 3 && earliest > EPS && !this._backBusy) void this._readBack(earliest, passed);
|
|
3932
|
+
} else if (this._held >= MIN_HELD_TO_READ_START && this._dir === 1 && this._loop && this._duration !== null && time >= this._duration - JUMP_SECONDS && !this._standby && !this._standbyBusy) {
|
|
3933
|
+
void this._readStart();
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
/** In the background: the window of frames before the earliest one held (reverse play comes to it next). */
|
|
3937
|
+
async _readBack(earliest, room) {
|
|
3938
|
+
this._backBusy = true;
|
|
3939
|
+
this.stats.prefetches++;
|
|
3940
|
+
const gen = this._gen, bg = this._backGen;
|
|
3941
|
+
const want = Math.max(3, Math.min(Math.floor(this._held * 0.6), room));
|
|
3942
|
+
let iter = null;
|
|
3943
|
+
const got = [];
|
|
3944
|
+
try {
|
|
3945
|
+
iter = this.sink.samples(Math.max(0, earliest - want / 30));
|
|
3946
|
+
for (; ; ) {
|
|
3947
|
+
const r = await iter.next();
|
|
3948
|
+
if (r.done) break;
|
|
3949
|
+
if (gen !== this._gen || r.value.timestamp >= earliest - EPS) {
|
|
3950
|
+
r.value.close?.();
|
|
3951
|
+
break;
|
|
3952
|
+
}
|
|
3953
|
+
got.push(r.value);
|
|
3954
|
+
if (bg !== this._backGen) break;
|
|
3955
|
+
}
|
|
3956
|
+
if (gen === this._gen && bg === this._backGen) {
|
|
3957
|
+
for (let k = 0; k < got.length; k++) {
|
|
3958
|
+
const s = got[k];
|
|
3959
|
+
const frame = s.toVideoFrame();
|
|
3960
|
+
this._keep({ ts: s.timestamp, end: got[k + 1]?.timestamp ?? earliest, frame }, frame);
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
} catch (err) {
|
|
3964
|
+
reportDecodeError(err, earliest);
|
|
3965
|
+
} finally {
|
|
3966
|
+
for (const s of got) s.close?.();
|
|
3967
|
+
this._backBusy = false;
|
|
3968
|
+
try {
|
|
3969
|
+
await iter?.return?.(void 0);
|
|
3970
|
+
} catch {
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
/** In the background: the first frames of the file and a pass that stands behind them; held (pinned) until the loop comes round. */
|
|
3975
|
+
async _readStart() {
|
|
3976
|
+
this._standbyBusy = true;
|
|
3977
|
+
this.stats.prefetches++;
|
|
3978
|
+
const gen = this._gen;
|
|
3979
|
+
const want = Math.max(3, Math.min(10, Math.floor(this._held / 3)));
|
|
3980
|
+
let iter = null;
|
|
3981
|
+
const got = [];
|
|
3982
|
+
let keep = false;
|
|
3983
|
+
try {
|
|
3984
|
+
iter = this.sink.samples(0);
|
|
3985
|
+
for (; got.length < want + 1; ) {
|
|
3986
|
+
const r = await iter.next();
|
|
3987
|
+
if (r.done) break;
|
|
3988
|
+
if (gen !== this._gen) {
|
|
3989
|
+
r.value.close?.();
|
|
3990
|
+
break;
|
|
3991
|
+
}
|
|
3992
|
+
got.push(r.value);
|
|
3993
|
+
}
|
|
3994
|
+
if (gen === this._gen && got.length >= 2) {
|
|
3995
|
+
const next = got.pop();
|
|
3996
|
+
let cur = null;
|
|
3997
|
+
got.forEach((s, k) => {
|
|
3998
|
+
const frame = s.toVideoFrame();
|
|
3999
|
+
s.close?.();
|
|
4000
|
+
const entry = { ts: s.timestamp, end: (got[k + 1] ?? next).timestamp, frame, pinned: true };
|
|
4001
|
+
this._keep(entry, frame);
|
|
4002
|
+
cur = entry;
|
|
4003
|
+
});
|
|
4004
|
+
got.length = 0;
|
|
4005
|
+
if (cur) {
|
|
4006
|
+
this._standby = { iter, cur, next };
|
|
4007
|
+
keep = true;
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
} catch (err) {
|
|
4011
|
+
reportDecodeError(err, 0);
|
|
4012
|
+
} finally {
|
|
4013
|
+
for (const s of got) s.close?.();
|
|
4014
|
+
this._standbyBusy = false;
|
|
4015
|
+
if (!keep) {
|
|
4016
|
+
try {
|
|
4017
|
+
await iter?.return?.(void 0);
|
|
4018
|
+
} catch {
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
async _adoptStandby(time) {
|
|
4024
|
+
const sb = this._standby;
|
|
4025
|
+
this._standby = null;
|
|
4026
|
+
await this._closeIter();
|
|
4027
|
+
for (const e of this._frames) e.pinned = false;
|
|
4028
|
+
this._iter = sb.iter;
|
|
4029
|
+
this._next = sb.next;
|
|
4030
|
+
this._cur = sb.cur;
|
|
4031
|
+
return this._advance(time);
|
|
4032
|
+
}
|
|
4033
|
+
_dropStandby() {
|
|
4034
|
+
const sb = this._standby;
|
|
4035
|
+
if (!sb) return;
|
|
4036
|
+
this._standby = null;
|
|
4037
|
+
sb.next?.close?.();
|
|
4038
|
+
for (const e of this._frames.filter((x) => x.pinned)) {
|
|
4039
|
+
e.pinned = false;
|
|
4040
|
+
}
|
|
4041
|
+
void sb.iter.return?.(void 0);
|
|
3175
4042
|
}
|
|
3176
4043
|
/** One frame by itself (a seek): getSample, kept so that asking again for the same time costs nothing. The running pass, if any, is closed: it no longer follows the playhead. */
|
|
3177
4044
|
async _single(time) {
|
|
4045
|
+
this.stats.singles++;
|
|
3178
4046
|
await this._closeIter();
|
|
3179
4047
|
this._cur = null;
|
|
3180
4048
|
const sample = await this.sink.getSample(time);
|
|
@@ -3186,6 +4054,8 @@ var FrameCache = class {
|
|
|
3186
4054
|
}
|
|
3187
4055
|
/** Start a pass at `time` (a seek and the frames of one group of pictures), keeping what is still held for a step back. */
|
|
3188
4056
|
async _restart(time, from = time) {
|
|
4057
|
+
this.stats.restarts++;
|
|
4058
|
+
this._backGen++;
|
|
3189
4059
|
await this._closeIter();
|
|
3190
4060
|
this._cur = null;
|
|
3191
4061
|
const iter = this.sink.samples(from);
|
|
@@ -3249,12 +4119,27 @@ var FrameCache = class {
|
|
|
3249
4119
|
}
|
|
3250
4120
|
this._frames.push(entry);
|
|
3251
4121
|
while (this._frames.length > this._held) {
|
|
3252
|
-
const
|
|
3253
|
-
if (!
|
|
3254
|
-
this._frames.splice(this._frames.indexOf(
|
|
3255
|
-
|
|
4122
|
+
const victim = this._victim(entry);
|
|
4123
|
+
if (!victim) break;
|
|
4124
|
+
this._frames.splice(this._frames.indexOf(victim), 1);
|
|
4125
|
+
victim.frame.close?.();
|
|
3256
4126
|
}
|
|
3257
4127
|
}
|
|
4128
|
+
/**
|
|
4129
|
+
* The frame to let go: one the playhead has already passed (going forward those before it, going back those after it), the furthest
|
|
4130
|
+
* behind first; when there is none, the one furthest ahead of the playhead (the last to be needed). Least recently used when the
|
|
4131
|
+
* direction is not known. Frames of the standby (pinned) and the frame the pass stands on are never chosen.
|
|
4132
|
+
*/
|
|
4133
|
+
_victim(except) {
|
|
4134
|
+
const cand = this._frames.filter((e) => e !== this._cur && e !== except && !e.pinned);
|
|
4135
|
+
if (cand.length === 0) return null;
|
|
4136
|
+
if (this._dir === 0) return cand[0];
|
|
4137
|
+
const at = this._lastTime ?? 0;
|
|
4138
|
+
const passed = cand.filter((e) => this._dir === 1 ? e.ts < at - EPS : e.ts > at + EPS);
|
|
4139
|
+
const farthest = (list, sign) => list.reduce((a, b) => sign * (b.ts - a.ts) > 0 ? b : a);
|
|
4140
|
+
if (passed.length) return farthest(passed, this._dir === 1 ? -1 : 1);
|
|
4141
|
+
return farthest(cand, this._dir === 1 ? 1 : -1);
|
|
4142
|
+
}
|
|
3258
4143
|
async _closeIter() {
|
|
3259
4144
|
const iter = this._iter;
|
|
3260
4145
|
this._iter = null;
|
|
@@ -3277,6 +4162,8 @@ var FrameCache = class {
|
|
|
3277
4162
|
}
|
|
3278
4163
|
}
|
|
3279
4164
|
dispose() {
|
|
4165
|
+
this._gen++;
|
|
4166
|
+
this._dropStandby();
|
|
3280
4167
|
for (const f of this.cache.values()) f?.close?.();
|
|
3281
4168
|
this.cache.clear();
|
|
3282
4169
|
this._pending.clear();
|
|
@@ -3318,7 +4205,7 @@ var VideoSequence = class extends Sequence {
|
|
|
3318
4205
|
this._sourceDuration = data.duration;
|
|
3319
4206
|
this._remap = remapOf(this.spec, "currentTime", this._sourceDuration);
|
|
3320
4207
|
this._audioBuffer = this.spec.audio !== false ? data.audioBuffer : null;
|
|
3321
|
-
this._cache = new FrameCache(data.sink, { capacity: 30 });
|
|
4208
|
+
this._cache = new FrameCache(data.sink, { capacity: 30, duration: data.duration, loop: !!this.spec.loop });
|
|
3322
4209
|
const probeFrame = await this._cache.getFrameAt(0);
|
|
3323
4210
|
const w = probeFrame?.displayWidth ?? 1920;
|
|
3324
4211
|
const h = probeFrame?.displayHeight ?? 1080;
|
|
@@ -3348,8 +4235,8 @@ var VideoSequence = class extends Sequence {
|
|
|
3348
4235
|
currentTime = v;
|
|
3349
4236
|
seq._cur = v;
|
|
3350
4237
|
const mySeq = ++seq._drawSeq;
|
|
3351
|
-
const
|
|
3352
|
-
seq._cache.getFrameAt(
|
|
4238
|
+
const lookup2 = sourceLookup(v, seq._sourceDuration, !!seq.spec.loop);
|
|
4239
|
+
seq._cache.getFrameAt(lookup2).then((frame) => {
|
|
3353
4240
|
if (mySeq !== seq._drawSeq) return;
|
|
3354
4241
|
if (!frame || !seq._ctx) return;
|
|
3355
4242
|
seq._ctx.drawImage(frame, 0, 0);
|
|
@@ -3389,7 +4276,7 @@ var VideoSequence = class extends Sequence {
|
|
|
3389
4276
|
out.push({
|
|
3390
4277
|
...sourceMap ? { sourceMap } : {},
|
|
3391
4278
|
buffer: this._audioBuffer,
|
|
3392
|
-
layer:
|
|
4279
|
+
layer: chunkZMAD3KJU_cjs.describeLayer(this.spec),
|
|
3393
4280
|
source: `video "${this.spec.asset}"`,
|
|
3394
4281
|
loop: !!this.spec.loop,
|
|
3395
4282
|
start: baseTime + this.at,
|
|
@@ -3403,10 +4290,10 @@ var VideoSequence = class extends Sequence {
|
|
|
3403
4290
|
const time = this._cur;
|
|
3404
4291
|
if (!this.keepHidden && !this.target?.renderable) return;
|
|
3405
4292
|
const mySeq = ++this._drawSeq;
|
|
3406
|
-
const
|
|
4293
|
+
const lookup2 = sourceLookup(time, this._sourceDuration, !!this.spec.loop);
|
|
3407
4294
|
let frame = null;
|
|
3408
4295
|
try {
|
|
3409
|
-
frame = await this._cache.getFrameAt(
|
|
4296
|
+
frame = await this._cache.getFrameAt(lookup2);
|
|
3410
4297
|
} catch (err) {
|
|
3411
4298
|
console.warn("pixi-effects: awaitFrameAt failed at", time, "s \u2014", err);
|
|
3412
4299
|
return;
|
|
@@ -3657,20 +4544,20 @@ var ShapeSequence = class extends Sequence {
|
|
|
3657
4544
|
for (const k of geomKeys) this._liveKeys.add(k);
|
|
3658
4545
|
seedGeometry(this._state, this.spec, scope);
|
|
3659
4546
|
seedStyle(this._state, this.spec.initial ?? {}, scope);
|
|
3660
|
-
seedStrokeStyle(this._state, this.spec, this.spec.initial ?? {},
|
|
4547
|
+
seedStrokeStyle(this._state, this.spec, this.spec.initial ?? {}, chunkZMAD3KJU_cjs.describeLayer(this.spec));
|
|
3661
4548
|
if (this.spec.shape === "arc") {
|
|
3662
4549
|
this._state.startAngle ??= 0;
|
|
3663
4550
|
this._state.endAngle ??= 360;
|
|
3664
4551
|
const top = this.spec, ini = this.spec.initial ?? {};
|
|
3665
4552
|
if ("trimStart" in top || "trimEnd" in top || "trimStart" in ini || "trimEnd" in ini) {
|
|
3666
|
-
console.warn(`pixi-effects: ${
|
|
4553
|
+
console.warn(`pixi-effects: ${chunkZMAD3KJU_cjs.describeLayer(this.spec)}: trimStart / trimEnd do not apply to an arc: animate its endAngle (and startAngle) instead`);
|
|
3667
4554
|
}
|
|
3668
4555
|
} else {
|
|
3669
4556
|
this._state.trimStart ??= 0;
|
|
3670
4557
|
this._state.trimEnd ??= 1;
|
|
3671
4558
|
}
|
|
3672
4559
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
3673
|
-
validateGradientKeyframes(this.spec,
|
|
4560
|
+
validateGradientKeyframes(this.spec, chunkZMAD3KJU_cjs.describeLayer(this.spec));
|
|
3674
4561
|
if (gradientSpec) {
|
|
3675
4562
|
if (hasGradientKeys(this.spec.keyframes)) {
|
|
3676
4563
|
this._grad = { grad: gradStateFrom(gradientSpec) };
|
|
@@ -3712,9 +4599,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
3712
4599
|
}
|
|
3713
4600
|
/** The prepared morph between `d` and `morphTo`, or null (and a warning when the spec asked for one that cannot work). */
|
|
3714
4601
|
_setupMorph() {
|
|
3715
|
-
const who =
|
|
4602
|
+
const who = chunkZMAD3KJU_cjs.describeLayer(this.spec);
|
|
3716
4603
|
const top = this.spec;
|
|
3717
|
-
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 ||
|
|
4604
|
+
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 || chunkZMAD3KJU_cjs.collectPropKeys(this.spec).has("morph"));
|
|
3718
4605
|
if (this.spec.shape !== "path") {
|
|
3719
4606
|
if ("morphTo" in top) console.warn(`pixi-effects: ${who}: morphTo only works on a path shape (shape: 'path'); ignored`);
|
|
3720
4607
|
return null;
|
|
@@ -3814,7 +4701,7 @@ function seedGeometry(state, spec, scope) {
|
|
|
3814
4701
|
const initial = spec.initial ?? {};
|
|
3815
4702
|
for (const k of keys) {
|
|
3816
4703
|
const v = spec[k] ?? initial[k];
|
|
3817
|
-
if (v !== void 0) state[k] =
|
|
4704
|
+
if (v !== void 0) state[k] = num2(v, scope);
|
|
3818
4705
|
}
|
|
3819
4706
|
}
|
|
3820
4707
|
var STROKE_CAPS = ["butt", "round", "square"];
|
|
@@ -3932,7 +4819,7 @@ function drawEllipseFromState(g, s) {
|
|
|
3932
4819
|
const ay = s.anchorY ?? 0.5;
|
|
3933
4820
|
g.ellipse((0.5 - ax) * 2 * rx, (0.5 - ay) * 2 * ry, rx, ry);
|
|
3934
4821
|
}
|
|
3935
|
-
var
|
|
4822
|
+
var DEG5 = Math.PI / 180;
|
|
3936
4823
|
function drawArcFromState(g, s) {
|
|
3937
4824
|
const r = s.radius ?? 0;
|
|
3938
4825
|
const ri = Math.max(0, Math.min(s.innerRadius ?? 0, r));
|
|
@@ -3947,7 +4834,7 @@ function drawArcFromState(g, s) {
|
|
|
3947
4834
|
}
|
|
3948
4835
|
endDeg = startDeg + Math.sign(endDeg - startDeg) * 359.999;
|
|
3949
4836
|
}
|
|
3950
|
-
const a0 = startDeg *
|
|
4837
|
+
const a0 = startDeg * DEG5, a1 = endDeg * DEG5;
|
|
3951
4838
|
const ccw = a1 < a0;
|
|
3952
4839
|
if (filled) g.moveTo(r * Math.cos(a0), r * Math.sin(a0));
|
|
3953
4840
|
g.arc(0, 0, r, a0, a1, ccw);
|
|
@@ -3961,10 +4848,10 @@ function drawArcFromState(g, s) {
|
|
|
3961
4848
|
g.closePath();
|
|
3962
4849
|
}
|
|
3963
4850
|
function makeLineDraw(spec, scope) {
|
|
3964
|
-
const fx =
|
|
3965
|
-
const fy =
|
|
3966
|
-
const tx =
|
|
3967
|
-
const ty =
|
|
4851
|
+
const fx = num2(spec.from[0], scope);
|
|
4852
|
+
const fy = num2(spec.from[1], scope);
|
|
4853
|
+
const tx = num2(spec.to[0], scope);
|
|
4854
|
+
const ty = num2(spec.to[1], scope);
|
|
3968
4855
|
return (g) => {
|
|
3969
4856
|
g.moveTo(fx, fy);
|
|
3970
4857
|
g.lineTo(tx, ty);
|
|
@@ -3974,7 +4861,7 @@ function makePolygonDraw(spec, scope) {
|
|
|
3974
4861
|
if (spec.points.length === 0) return () => {
|
|
3975
4862
|
};
|
|
3976
4863
|
const flat = [];
|
|
3977
|
-
for (const [x, y] of spec.points) flat.push(
|
|
4864
|
+
for (const [x, y] of spec.points) flat.push(num2(x, scope), num2(y, scope));
|
|
3978
4865
|
const closed = !spec.open;
|
|
3979
4866
|
return (g) => {
|
|
3980
4867
|
g.poly(flat, closed);
|
|
@@ -4040,12 +4927,12 @@ function makeOutline(spec, scope, s, morph) {
|
|
|
4040
4927
|
return [ellipseOutline((0.5 - (s.anchorX ?? 0.5)) * 2 * rx, (0.5 - (s.anchorY ?? 0.5)) * 2 * ry, rx, ry)];
|
|
4041
4928
|
};
|
|
4042
4929
|
case "line": {
|
|
4043
|
-
const lines = [{ pts: [
|
|
4930
|
+
const lines = [{ pts: [num2(spec.from[0], scope), num2(spec.from[1], scope), num2(spec.to[0], scope), num2(spec.to[1], scope)], closed: false }];
|
|
4044
4931
|
return () => lines;
|
|
4045
4932
|
}
|
|
4046
4933
|
case "polygon": {
|
|
4047
4934
|
const pts = [];
|
|
4048
|
-
for (const [x, y] of spec.points) pts.push(
|
|
4935
|
+
for (const [x, y] of spec.points) pts.push(num2(x, scope), num2(y, scope));
|
|
4049
4936
|
const lines = pts.length >= 4 ? [{ pts, closed: !spec.open }] : [];
|
|
4050
4937
|
return () => lines;
|
|
4051
4938
|
}
|
|
@@ -4073,7 +4960,7 @@ function bindLiveKeyframes(timeline, state, liveKeys, keyframes, parentDuration,
|
|
|
4073
4960
|
const live2 = state;
|
|
4074
4961
|
revertibleSet(timeline, at, () => live2[k], (v2) => {
|
|
4075
4962
|
live2[k] = v2;
|
|
4076
|
-
}, resolved);
|
|
4963
|
+
}, resolved, [live2, k]);
|
|
4077
4964
|
}
|
|
4078
4965
|
}
|
|
4079
4966
|
}
|
|
@@ -4117,7 +5004,7 @@ function tweenLiveKey(timeline, state, key, fromValue, toValue, duration, ease,
|
|
|
4117
5004
|
}
|
|
4118
5005
|
}
|
|
4119
5006
|
}
|
|
4120
|
-
function
|
|
5007
|
+
function num2(v, scope) {
|
|
4121
5008
|
if (typeof v === "number") return v;
|
|
4122
5009
|
if (isExpr(v)) return evaluateExpr(v, scope);
|
|
4123
5010
|
const parsed = parseFloat(v);
|
|
@@ -4125,7 +5012,7 @@ function num(v, scope) {
|
|
|
4125
5012
|
}
|
|
4126
5013
|
function numOrZero(v, scope) {
|
|
4127
5014
|
if (typeof v === "number") return v;
|
|
4128
|
-
if (typeof v === "string") return
|
|
5015
|
+
if (typeof v === "string") return num2(v, scope);
|
|
4129
5016
|
return 0;
|
|
4130
5017
|
}
|
|
4131
5018
|
|
|
@@ -4174,13 +5061,13 @@ var SHADER_BUILTINS = ["iResolution", "iTime", "iFrame"];
|
|
|
4174
5061
|
var SHADER_MISSING = ["iMouse", "iChannel0", "iChannel1", "iChannel2", "iChannel3", "iDate", "iTimeDelta", "iSampleRate"];
|
|
4175
5062
|
var IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
4176
5063
|
var HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
4177
|
-
var
|
|
5064
|
+
var RESERVED2 = new Set(`attribute const uniform varying break continue do for while if else in out inout float int void bool true false discard return
|
|
4178
5065
|
mat2 mat3 mat4 mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4 vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 uvec2 uvec3 uvec4 uint
|
|
4179
5066
|
sampler2D sampler3D samplerCube sampler2DShadow samplerCubeShadow sampler2DArray sampler2DArrayShadow isampler2D isampler3D isamplerCube isampler2DArray
|
|
4180
5067
|
usampler2D usampler3D usamplerCube usampler2DArray struct layout centroid flat smooth precision invariant highp mediump lowp
|
|
4181
5068
|
sample patch subroutine common partition active asm class union enum typedef template this resource goto inline noinline public static extern external
|
|
4182
5069
|
interface long short double half fixed unsigned superp input output hvec2 hvec3 hvec4 fvec2 fvec3 fvec4 dvec2 dvec3 dvec4 filter sizeof cast namespace using`.split(/\s+/));
|
|
4183
|
-
var isIdent = (name) => IDENT.test(name) && !name.startsWith("gl_") && !name.includes("__") && !
|
|
5070
|
+
var isIdent = (name) => IDENT.test(name) && !name.startsWith("gl_") && !name.includes("__") && !RESERVED2.has(name) && !SHADER_BUILTINS.includes(name);
|
|
4184
5071
|
function uniformType(v) {
|
|
4185
5072
|
if (typeof v === "number") return Number.isFinite(v) ? "float" : null;
|
|
4186
5073
|
if (typeof v === "string") return HEX.test(v) ? "vec3" : null;
|
|
@@ -4324,7 +5211,7 @@ var ShaderSequence = class extends Sequence {
|
|
|
4324
5211
|
}
|
|
4325
5212
|
async build() {
|
|
4326
5213
|
const spec = this.shaderSpec;
|
|
4327
|
-
const who =
|
|
5214
|
+
const who = chunkZMAD3KJU_cjs.describeLayer(spec);
|
|
4328
5215
|
for (const m of shaderProblems(spec)) console.warn(`pixi-effects: ${who}: ${m}`);
|
|
4329
5216
|
if (this.duration === void 0) this.duration = this.parent?.duration ?? this.root.duration;
|
|
4330
5217
|
const scope = buildScope(this, this.parent, this.root);
|
|
@@ -4368,7 +5255,7 @@ var ShaderSequence = class extends Sequence {
|
|
|
4368
5255
|
const warn = (why) => {
|
|
4369
5256
|
if (this.warnedPaths.has(path)) return;
|
|
4370
5257
|
this.warnedPaths.add(path);
|
|
4371
|
-
console.warn(`pixi-effects: ${
|
|
5258
|
+
console.warn(`pixi-effects: ${chunkZMAD3KJU_cjs.describeLayer(this.spec)}: keyframe path uniforms.${path} ${why}; skipped`);
|
|
4372
5259
|
};
|
|
4373
5260
|
if (slot === void 0) {
|
|
4374
5261
|
const guess = chunkTWZNOUM7_cjs.suggestName(name, Object.keys(this.carrier));
|
|
@@ -4403,7 +5290,7 @@ var ShaderSequence = class extends Sequence {
|
|
|
4403
5290
|
this.failed = true;
|
|
4404
5291
|
if (!this.warnedNoGl) {
|
|
4405
5292
|
this.warnedNoGl = true;
|
|
4406
|
-
console.warn(`pixi-effects: ${
|
|
5293
|
+
console.warn(`pixi-effects: ${chunkZMAD3KJU_cjs.describeLayer(this.spec)}: this browser has no WebGL2, so the shader cannot run; the layer is drawn as a checkerboard`);
|
|
4407
5294
|
}
|
|
4408
5295
|
}
|
|
4409
5296
|
compile() {
|
|
@@ -4434,7 +5321,7 @@ var ShaderSequence = class extends Sequence {
|
|
|
4434
5321
|
gl.deleteProgram(p);
|
|
4435
5322
|
this.failed = true;
|
|
4436
5323
|
this.prog = null;
|
|
4437
|
-
console.warn(`pixi-effects: ${
|
|
5324
|
+
console.warn(`pixi-effects: ${chunkZMAD3KJU_cjs.describeLayer(this.spec)}: the fragment shader did not compile (the line numbers are the lines of your code):
|
|
4438
5325
|
${glslErrors(log).join("\n")}
|
|
4439
5326
|
The layer is drawn as a checkerboard until it is fixed.`);
|
|
4440
5327
|
return;
|
|
@@ -4518,7 +5405,7 @@ function resolveDim(v, scope) {
|
|
|
4518
5405
|
var _CompositionSequence = null;
|
|
4519
5406
|
async function getCompositionSequence() {
|
|
4520
5407
|
if (!_CompositionSequence) {
|
|
4521
|
-
_CompositionSequence = (await import('./Composition-
|
|
5408
|
+
_CompositionSequence = (await import('./Composition-QCOWQSDB.cjs')).CompositionSequence;
|
|
4522
5409
|
}
|
|
4523
5410
|
return _CompositionSequence;
|
|
4524
5411
|
}
|
|
@@ -4562,7 +5449,7 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
4562
5449
|
|
|
4563
5450
|
exports.CameraSequence = CameraSequence;
|
|
4564
5451
|
exports.DEFAULT_FOV = DEFAULT_FOV;
|
|
4565
|
-
exports.DEG =
|
|
5452
|
+
exports.DEG = DEG3;
|
|
4566
5453
|
exports.FALLOFFS = FALLOFFS;
|
|
4567
5454
|
exports.LIGHT_KINDS = LIGHT_KINDS;
|
|
4568
5455
|
exports.LIGHT_PROPS = LIGHT_PROPS;
|
|
@@ -4584,6 +5471,7 @@ exports.cameraBasis = cameraBasis;
|
|
|
4584
5471
|
exports.checkEase = checkEase;
|
|
4585
5472
|
exports.clockTable = clockTable;
|
|
4586
5473
|
exports.contentLength = contentLength;
|
|
5474
|
+
exports.createTimeline = createTimeline;
|
|
4587
5475
|
exports.ensureFilterLibrary = ensureFilterLibrary;
|
|
4588
5476
|
exports.evaluateExpr = evaluateExpr;
|
|
4589
5477
|
exports.flattenSvgPath = flattenSvgPath;
|
|
@@ -4592,9 +5480,11 @@ exports.homeCamera = homeCamera;
|
|
|
4592
5480
|
exports.homeDistance = homeDistance;
|
|
4593
5481
|
exports.layerInitialZ = layerInitialZ;
|
|
4594
5482
|
exports.layerToWorld = layerToWorld;
|
|
5483
|
+
exports.lengthen = lengthen;
|
|
4595
5484
|
exports.lightLevel = lightLevel;
|
|
4596
5485
|
exports.noise = noise;
|
|
4597
5486
|
exports.packLights = packLights;
|
|
5487
|
+
exports.parseEase = parseEase;
|
|
4598
5488
|
exports.projectLayer = projectLayer;
|
|
4599
5489
|
exports.projectPoint = projectPoint;
|
|
4600
5490
|
exports.rand = rand;
|
|
@@ -4603,5 +5493,5 @@ exports.registerSequenceType = registerSequenceType;
|
|
|
4603
5493
|
exports.remapOf = remapOf;
|
|
4604
5494
|
exports.resolveAt = resolveAt;
|
|
4605
5495
|
exports.timeRemapOf = timeRemapOf;
|
|
4606
|
-
//# sourceMappingURL=chunk-
|
|
4607
|
-
//# sourceMappingURL=chunk-
|
|
5496
|
+
//# sourceMappingURL=chunk-RQMI7EJT.cjs.map
|
|
5497
|
+
//# sourceMappingURL=chunk-RQMI7EJT.cjs.map
|