pixi-effects 0.9.0 → 0.10.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 +15 -0
- package/README.md +6 -6
- package/ai/SKILL.md +2 -1
- package/ai/reference/cheatsheet.md +13 -5
- package/ai/reference/pitfalls.md +2 -2
- package/ai/reference/recipes.md +123 -2
- package/ai/template.html +3 -3
- package/dist/{Base-CSIulyIq.d.cts → Base-CwUxTfja.d.cts} +1 -1
- package/dist/{Base-DVgwyIUj.d.ts → Base-CyvSLoCP.d.ts} +1 -1
- package/dist/Composition-EKVTUYCI.cjs +14 -0
- package/dist/{Composition-CM62XJKT.cjs.map → Composition-EKVTUYCI.cjs.map} +1 -1
- package/dist/Composition-NJCOMGD7.js +5 -0
- package/dist/{Composition-RJDSQYTV.js.map → Composition-NJCOMGD7.js.map} +1 -1
- package/dist/Controller.cjs +34 -0
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +12 -2
- package/dist/Controller.d.ts +12 -2
- package/dist/Controller.js +34 -0
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-QMlFyHkf.d.ts → Movie-puD9oZPg.d.ts} +1 -1
- package/dist/{Movie-qGHp15c_.d.cts → Movie-w3GliuP3.d.cts} +1 -1
- package/dist/{chunk-PDBDDGG5.cjs → chunk-4WJUSDJJ.cjs} +103 -30
- package/dist/chunk-4WJUSDJJ.cjs.map +1 -0
- package/dist/{chunk-FNKSXBKB.js → chunk-JAMNDBXW.js} +193 -14
- package/dist/chunk-JAMNDBXW.js.map +1 -0
- package/dist/{chunk-AGMNSJJH.cjs → chunk-S3ZI4MKS.cjs} +196 -12
- package/dist/chunk-S3ZI4MKS.cjs.map +1 -0
- package/dist/{chunk-O4AJYUPK.js → chunk-WDGAVOMS.js} +85 -12
- package/dist/chunk-WDGAVOMS.js.map +1 -0
- package/dist/index.cjs +309 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +231 -5
- package/dist/index.d.ts +231 -5
- package/dist/index.js +282 -11
- package/dist/index.js.map +1 -1
- package/dist/three.cjs +5 -5
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +1 -1
- package/dist/{types-oJijbn-K.d.ts → types-BXu28nJj.d.cts} +26 -2
- package/dist/{types-oJijbn-K.d.cts → types-BXu28nJj.d.ts} +26 -2
- package/docs/api.md +1 -0
- package/docs/dsl.md +108 -2
- package/llms-full.txt +249 -12
- package/package.json +1 -1
- package/dist/Composition-CM62XJKT.cjs +0 -14
- package/dist/Composition-RJDSQYTV.js +0 -5
- package/dist/chunk-AGMNSJJH.cjs.map +0 -1
- package/dist/chunk-FNKSXBKB.js.map +0 -1
- package/dist/chunk-O4AJYUPK.js.map +0 -1
- package/dist/chunk-PDBDDGG5.cjs.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkS3ZI4MKS_cjs = require('./chunk-S3ZI4MKS.cjs');
|
|
4
|
+
var chunkUQBGW5DO_cjs = require('./chunk-UQBGW5DO.cjs');
|
|
4
5
|
var pixi_js = require('pixi.js');
|
|
5
6
|
|
|
6
7
|
// src/space/camera.ts
|
|
@@ -63,8 +64,8 @@ function readLayerTransform(target) {
|
|
|
63
64
|
x: c.x,
|
|
64
65
|
y: c.y,
|
|
65
66
|
z: c.z ?? 0,
|
|
66
|
-
rotationX: (c.rotationX ?? 0) *
|
|
67
|
-
rotationY: (c.rotationY ?? 0) *
|
|
67
|
+
rotationX: (c.rotationX ?? 0) * chunkS3ZI4MKS_cjs.DEG,
|
|
68
|
+
rotationY: (c.rotationY ?? 0) * chunkS3ZI4MKS_cjs.DEG,
|
|
68
69
|
rotationZ: c.rotation,
|
|
69
70
|
scaleX: c.scale.x,
|
|
70
71
|
scaleY: c.scale.y,
|
|
@@ -109,18 +110,18 @@ var Layer3D = class {
|
|
|
109
110
|
if (!(needW >= 1 && needH >= 1) || !Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) return this.hide();
|
|
110
111
|
const size = this.sizeFor(needW, needH);
|
|
111
112
|
const frame = { x: bounds.x - pad, y: bounds.y - pad, width: size.w, height: size.h };
|
|
112
|
-
const projected =
|
|
113
|
+
const projected = chunkS3ZI4MKS_cjs.projectLayer(readLayerTransform(target), frame, basis);
|
|
113
114
|
this.depth = projected.depth;
|
|
114
115
|
if (!projected.visible) {
|
|
115
116
|
if (!this.warnedBehind) {
|
|
116
117
|
this.warnedBehind = true;
|
|
117
|
-
if (projected.depth >
|
|
118
|
+
if (projected.depth > chunkS3ZI4MKS_cjs.NEAR) {
|
|
118
119
|
console.warn(
|
|
119
|
-
`pixi-effects: ${
|
|
120
|
+
`pixi-effects: ${chunkS3ZI4MKS_cjs.describeLayer(this.seq.spec)}: part of it (a corner) reaches the camera plane (z = ${(target.z ?? 0).toFixed(0)}, rotationX ${(target.rotationX ?? 0).toFixed(0)}\xB0, rotationY ${(target.rotationY ?? 0).toFixed(0)}\xB0), and a layer is hidden whole when any corner is at or behind it. Tilt it less (rotationX / rotationY), make it smaller, or keep the camera further away from it (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`
|
|
120
121
|
);
|
|
121
122
|
} else {
|
|
122
123
|
console.warn(
|
|
123
|
-
`pixi-effects: ${
|
|
124
|
+
`pixi-effects: ${chunkS3ZI4MKS_cjs.describeLayer(this.seq.spec)} is at or behind the camera plane (z = ${(target.z ?? 0).toFixed(0)}) and is hidden. If that is unintended, lower its z or move the camera back (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`
|
|
124
125
|
);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
@@ -208,8 +209,8 @@ var CAMERA_PROPS = ["x", "y", "z", "fov", "lookAtX", "lookAtY", "lookAtZ"];
|
|
|
208
209
|
var NEEDS_THREE_D = ["z", "rotationX", "rotationY"];
|
|
209
210
|
var SKEW_KEYS = ["skew", "skewX", "skewY"];
|
|
210
211
|
function lintSequence(spec, warn = defaultWarn) {
|
|
211
|
-
const who =
|
|
212
|
-
const keys =
|
|
212
|
+
const who = chunkS3ZI4MKS_cjs.describeLayer(spec);
|
|
213
|
+
const keys = chunkS3ZI4MKS_cjs.collectPropKeys(spec);
|
|
213
214
|
const explained = /* @__PURE__ */ new Set();
|
|
214
215
|
for (const k of keys) {
|
|
215
216
|
const hint = LAYER_ALIASES[k] ?? (spec.type === "camera" ? CAMERA_ALIASES[k] : void 0);
|
|
@@ -255,7 +256,7 @@ function applyBlendMode(spec, display) {
|
|
|
255
256
|
const mode = spec.blendMode;
|
|
256
257
|
if (mode === void 0) return;
|
|
257
258
|
if (!MODES.includes(mode)) {
|
|
258
|
-
console.warn(`pixi-effects: ${
|
|
259
|
+
console.warn(`pixi-effects: ${chunkS3ZI4MKS_cjs.describeLayer(spec)}: blendMode "${mode}" is not supported (use ${MODES.join(", ")})`);
|
|
259
260
|
return;
|
|
260
261
|
}
|
|
261
262
|
const filters = display.filters;
|
|
@@ -267,7 +268,7 @@ function applyBlendMode(spec, display) {
|
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
// src/sequences/Composition.ts
|
|
270
|
-
var CompositionSequence = class extends
|
|
271
|
+
var CompositionSequence = class extends chunkS3ZI4MKS_cjs.Sequence {
|
|
271
272
|
_innerContainer = null;
|
|
272
273
|
_compositionShape = null;
|
|
273
274
|
_children = [];
|
|
@@ -275,6 +276,10 @@ var CompositionSequence = class extends chunkAGMNSJJH_cjs.Sequence {
|
|
|
275
276
|
_layers3d = [];
|
|
276
277
|
/** Drawn children in stack order (cameras and target-less sequences excluded). */
|
|
277
278
|
_visual = [];
|
|
279
|
+
/** Layers drawn inside a null layer (`parent`): they are not in the composition's own stack. */
|
|
280
|
+
_nested = [];
|
|
281
|
+
/** The null layer each parented layer is drawn inside. */
|
|
282
|
+
_parentOf = /* @__PURE__ */ new Map();
|
|
278
283
|
async build() {
|
|
279
284
|
const width = this.spec.width ?? this.parent?.width ?? this.root.width;
|
|
280
285
|
const height = this.spec.height ?? this.parent?.height ?? this.root.height;
|
|
@@ -297,21 +302,24 @@ var CompositionSequence = class extends chunkAGMNSJJH_cjs.Sequence {
|
|
|
297
302
|
const lateKeyframes = [];
|
|
298
303
|
for (const s of this.spec.sequences ?? []) {
|
|
299
304
|
lintSequence(s);
|
|
300
|
-
|
|
301
|
-
|
|
305
|
+
chunkS3ZI4MKS_cjs.lintTiming(s, this.duration, (message, kind) => kind === "late-keyframe" ? lateKeyframes.push(message) : console.warn(message));
|
|
306
|
+
chunkS3ZI4MKS_cjs.lintText(s);
|
|
302
307
|
}
|
|
303
|
-
for (const message of
|
|
304
|
-
this._children = await
|
|
308
|
+
for (const message of chunkS3ZI4MKS_cjs.summarizeWarnings(lateKeyframes)) console.warn(message);
|
|
309
|
+
this._children = await chunkS3ZI4MKS_cjs.buildSequenceTree(
|
|
305
310
|
this.spec.sequences ?? [],
|
|
306
311
|
this._compositionShape,
|
|
307
312
|
this.root
|
|
308
313
|
);
|
|
314
|
+
this._resolveParents();
|
|
309
315
|
for (const child of this._children) {
|
|
310
|
-
if (child instanceof
|
|
316
|
+
if (child instanceof chunkS3ZI4MKS_cjs.CameraSequence) {
|
|
311
317
|
this._cameras.push(child);
|
|
312
318
|
continue;
|
|
313
319
|
}
|
|
314
320
|
if (!child.target) continue;
|
|
321
|
+
const holder = this._parentOf.get(child);
|
|
322
|
+
const into = holder?.target ?? inner;
|
|
315
323
|
const maskSpec = child.spec.mask;
|
|
316
324
|
if (child.spec.threeD) {
|
|
317
325
|
const layer = new Layer3D(child, frameOf(child));
|
|
@@ -320,19 +328,20 @@ var CompositionSequence = class extends chunkAGMNSJJH_cjs.Sequence {
|
|
|
320
328
|
this._visual.push({ seq: child, layer });
|
|
321
329
|
applyBlendMode(child.spec, layer.display);
|
|
322
330
|
if (maskSpec) {
|
|
323
|
-
console.warn(`pixi-effects: ${
|
|
331
|
+
console.warn(`pixi-effects: ${chunkS3ZI4MKS_cjs.describeLayer(child.spec)}: mask is not supported on threeD layers yet; ignored`);
|
|
324
332
|
}
|
|
325
333
|
continue;
|
|
326
334
|
}
|
|
327
|
-
|
|
328
|
-
this.
|
|
335
|
+
into.addChild(child.target);
|
|
336
|
+
if (holder) this._nested.push(child);
|
|
337
|
+
else this._visual.push({ seq: child, layer: null });
|
|
329
338
|
applyBlendMode(child.spec, child.target);
|
|
330
339
|
if (maskSpec) {
|
|
331
340
|
const lifetime = maskSpec.at === void 0 ? { at: child.at, duration: maskSpec.duration ?? child.duration } : {};
|
|
332
|
-
const built = await
|
|
341
|
+
const built = await chunkS3ZI4MKS_cjs.buildSequenceTree([{ ...maskSpec, ...lifetime }], this._compositionShape, this.root);
|
|
333
342
|
const maskSeq = built[0];
|
|
334
343
|
if (maskSeq?.target) {
|
|
335
|
-
|
|
344
|
+
into.addChild(maskSeq.target);
|
|
336
345
|
const inverse = child.spec.maskInverted ?? false;
|
|
337
346
|
const t = child.target;
|
|
338
347
|
if (typeof t.setMask === "function") {
|
|
@@ -367,13 +376,77 @@ var CompositionSequence = class extends chunkAGMNSJJH_cjs.Sequence {
|
|
|
367
376
|
console.warn(`pixi-effects: cameras #${overlap[0] + 1} and #${overlap[1] + 1} overlap in time; the top-most one wins`);
|
|
368
377
|
}
|
|
369
378
|
}
|
|
370
|
-
/**
|
|
379
|
+
/**
|
|
380
|
+
* Drawn children in stack order, with the display object that stands in for each (the mesh for a threeD layer).
|
|
381
|
+
* Null layers draw nothing and are left out; the layers inside them follow, with the null layers that carry them.
|
|
382
|
+
*/
|
|
371
383
|
layers() {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
384
|
+
const carriersOf = (seq) => {
|
|
385
|
+
const out = [];
|
|
386
|
+
for (let p = this._parentOf.get(seq); p; p = this._parentOf.get(p)) out.push(p);
|
|
387
|
+
return out;
|
|
388
|
+
};
|
|
389
|
+
return [...this._visual.map((v) => v.seq), ...this._nested].filter((seq) => !(seq instanceof chunkS3ZI4MKS_cjs.NullSequence)).map((seq) => {
|
|
390
|
+
const layer = this._visual.find((v) => v.seq === seq)?.layer ?? null;
|
|
391
|
+
return {
|
|
392
|
+
seq,
|
|
393
|
+
display: layer?.display ?? seq.target,
|
|
394
|
+
threeD: layer !== null,
|
|
395
|
+
carriers: carriersOf(seq)
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
/** Match every `parent: 'name'` to a null layer; anything that cannot work is said out loud and drawn unparented. */
|
|
400
|
+
_resolveParents() {
|
|
401
|
+
const nulls = this._children.filter((c) => c instanceof chunkS3ZI4MKS_cjs.NullSequence);
|
|
402
|
+
const nullNames = nulls.map((n) => n.spec.name).filter((n) => !!n);
|
|
403
|
+
const warned = /* @__PURE__ */ new Set();
|
|
404
|
+
for (const child of this._children) {
|
|
405
|
+
const want = child.spec.parent;
|
|
406
|
+
if (want === void 0) continue;
|
|
407
|
+
const who = chunkS3ZI4MKS_cjs.describeLayer(child.spec);
|
|
408
|
+
if (child instanceof chunkS3ZI4MKS_cjs.CameraSequence) {
|
|
409
|
+
console.warn(`pixi-effects: ${who}: a camera cannot have a parent; ignored`);
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (child.spec.threeD) {
|
|
413
|
+
console.warn(`pixi-effects: ${who}: a threeD layer cannot have a parent (parent "${want}" ignored)`);
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
const same = this._children.filter((c) => c.spec.name === want);
|
|
417
|
+
if (same.length === 0) {
|
|
418
|
+
const hint = chunkUQBGW5DO_cjs.suggestName(want, nullNames);
|
|
419
|
+
console.warn(`pixi-effects: ${who}: parent "${want}": no layer with that name${hint ? `; did you mean "${hint}"?` : ""} (the layer is drawn without a parent)`);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const holder = same.find((c) => c instanceof chunkS3ZI4MKS_cjs.NullSequence);
|
|
423
|
+
if (!holder) {
|
|
424
|
+
console.warn(`pixi-effects: ${who}: parent "${want}" is a ${same[0].spec.type} layer; only { type: 'null' } layers can be parents (the layer is drawn without a parent)`);
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
if (same.length > 1 && !warned.has(want)) {
|
|
428
|
+
warned.add(want);
|
|
429
|
+
console.warn(`pixi-effects: ${same.length} layers are named "${want}"; parent "${want}" uses the first null layer with that name`);
|
|
430
|
+
}
|
|
431
|
+
if (holder === child) {
|
|
432
|
+
console.warn(`pixi-effects: ${who} is its own parent; ignored`);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
this._parentOf.set(child, holder);
|
|
436
|
+
}
|
|
437
|
+
for (const start of this._children) {
|
|
438
|
+
const seen = /* @__PURE__ */ new Set([start]);
|
|
439
|
+
for (let p = this._parentOf.get(start); p; p = this._parentOf.get(p)) {
|
|
440
|
+
if (p === start) {
|
|
441
|
+
const names = [...seen].map((s) => s.spec.name ?? s.spec.type).join(" \u2192 ");
|
|
442
|
+
console.warn(`pixi-effects: parent cycle: ${names} \u2192 ${start.spec.name ?? start.spec.type}; the parent of "${start.spec.name ?? start.spec.type}" is ignored`);
|
|
443
|
+
this._parentOf.delete(start);
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
if (seen.has(p)) break;
|
|
447
|
+
seen.add(p);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
377
450
|
}
|
|
378
451
|
syncFrame() {
|
|
379
452
|
super.syncFrame();
|
|
@@ -389,7 +462,7 @@ var CompositionSequence = class extends chunkAGMNSJJH_cjs.Sequence {
|
|
|
389
462
|
t,
|
|
390
463
|
compEnd
|
|
391
464
|
);
|
|
392
|
-
const basis =
|
|
465
|
+
const basis = chunkS3ZI4MKS_cjs.cameraBasis(active ? active.cam.state() : chunkS3ZI4MKS_cjs.homeCamera(width, height), width, height);
|
|
393
466
|
for (const layer of this._layers3d) layer.update(host, basis);
|
|
394
467
|
const order = assignDepthOrder(
|
|
395
468
|
this._visual.map((v, i) => ({ stackIndex: i, threeD: v.layer !== null, depth: v.layer?.depth ?? 0 }))
|
|
@@ -418,5 +491,5 @@ function frameOf(child) {
|
|
|
418
491
|
}
|
|
419
492
|
|
|
420
493
|
exports.CompositionSequence = CompositionSequence;
|
|
421
|
-
//# sourceMappingURL=chunk-
|
|
422
|
-
//# sourceMappingURL=chunk-
|
|
494
|
+
//# sourceMappingURL=chunk-4WJUSDJJ.cjs.map
|
|
495
|
+
//# sourceMappingURL=chunk-4WJUSDJJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/space/camera.ts","../src/space/depth.ts","../src/space/Layer3D.ts","../src/space/lint.ts","../src/core/blend.ts","../src/sequences/Composition.ts"],"names":["i","DEG","frameOf","PerspectiveMesh","Texture","projectLayer","NEAR","describeLayer","Matrix","RenderTexture","collectPropKeys","Sequence","Container","Rectangle","lintTiming","lintText","summarizeWarnings","buildSequenceTree","CameraSequence","NullSequence","suggestName","cameraBasis","homeCamera"],"mappings":"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","file":"chunk-4WJUSDJJ.cjs","sourcesContent":["/** A camera layer's lifespan on the global timeline, seconds. */\nexport interface CameraWindow { start: number; end: number }\n\n/**\n * The active camera at time `t`: the last-listed (top-most) camera whose\n * lifespan covers `t`. Windows are [start, end), except that a camera running\n * to the end of its composition also covers the final instant `t === compEnd`.\n */\nexport function pickActiveCamera<T extends CameraWindow>(\n cams: readonly T[],\n t: number,\n compEnd: number,\n): T | null {\n for (let i = cams.length - 1; i >= 0; i--) {\n const c = cams[i]!;\n const inside = t >= c.start && (t < c.end || (c.end >= compEnd && t <= compEnd));\n if (inside) return c;\n }\n return null;\n}\n\n/** First pair of camera indices whose lifespans strictly overlap, or null. */\nexport function findOverlap(cams: readonly CameraWindow[]): [number, number] | null {\n for (let i = 0; i < cams.length; i++) {\n for (let j = i + 1; j < cams.length; j++) {\n const a = cams[i]!;\n const b = cams[j]!;\n if (a.start < b.end && b.start < a.end) return [i, j];\n }\n }\n return null;\n}\n","export interface DepthItem {\n /** Position in the composition's stack (monotonic; gaps allowed). */\n stackIndex: number;\n threeD: boolean;\n /** Camera-space depth (larger = farther). Only read for threeD items. */\n depth: number;\n}\n\nconst finite = (n: number): number => (Number.isFinite(n) ? n : 0);\n\n/**\n * zIndex per item. Non-3D items keep their stack index. Each run of\n * consecutive threeD items is redistributed over the same index slots,\n * farthest first (drawn first), ties in stack order.\n */\nexport function assignDepthOrder(items: readonly DepthItem[]): number[] {\n const out = items.map(i => i.stackIndex);\n let i = 0;\n while (i < items.length) {\n if (!items[i]!.threeD) { i++; continue; }\n let j = i;\n while (j + 1 < items.length && items[j + 1]!.threeD) j++;\n const run = items.slice(i, j + 1).map((it, k) => ({ it, pos: i + k }));\n const slots = run.map(r => r.it.stackIndex);\n const farthestFirst = [...run].sort((a, b) => finite(b.it.depth) - finite(a.it.depth));\n farthestFirst.forEach((r, k) => { out[r.pos] = slots[k]!; });\n i = j + 1;\n }\n return out;\n}\n","import { Container, Matrix, PerspectiveMesh, RenderTexture, Texture } from 'pixi.js';\nimport type { Sequence } from '../sequences/Base';\nimport { describeLayer } from '../core/lint';\nimport { DEG, NEAR, projectLayer, type CameraBasis, type LayerTransform, type Rect } from './math';\n\n/** Render textures are capped at this many pixels on the long side; larger layers are downscaled. */\nexport const MAX_TEXTURE_SIZE = 4096;\n/**\n * Render textures are drawn at this multiple of the layer size (until the caps),\n * so a layer enlarged by perspective (z > 0) stays sharp instead of showing\n * jagged edges and soft text.\n */\nexport const SUPERSAMPLE = 2;\n/** Total texture pixels per layer are capped here (≈ one 2048² target); resolution drops to fit. */\nexport const MAX_TEXTURE_PIXELS = 2048 * 2048;\n/** MSAA multiplies target memory ~4x, so only small textures get it (supersampling covers the rest). */\nexport const ANTIALIAS_MAX_PIXELS = 1024 * 1024;\n/** Mesh grid per side. 20 keeps steeply tilted planes free of visible affine warping. */\nexport const MESH_GRID = 20;\n\n/** The slice of a Pixi renderer Layer3D needs (also what tests fake). */\nexport interface SpaceHost {\n render(options: {\n container: Container;\n target: RenderTexture;\n transform: Matrix;\n clear: boolean;\n clearColor: number[];\n }): void;\n}\n\ntype Carrier = Container & { z?: number; rotationX?: number; rotationY?: number };\n\ninterface TextureSize { w: number; h: number; resolution: number; antialias: boolean }\n\n/** Sum of the target's filter paddings: the texture must be this much larger on every side or filter output is clipped. */\nfunction filterPadding(target: Container): number {\n const filters = (target as unknown as { filters?: ReadonlyArray<{ padding?: number }> | null }).filters;\n if (!Array.isArray(filters)) return 0;\n let pad = 0;\n for (const f of filters) pad += f?.padding ?? 0;\n return Number.isFinite(pad) && pad > 0 ? Math.ceil(pad) : 0;\n}\n\nexport function readLayerTransform(target: Container): LayerTransform {\n const c = target as Carrier;\n return {\n x: c.x, y: c.y, z: c.z ?? 0,\n rotationX: (c.rotationX ?? 0) * DEG,\n rotationY: (c.rotationY ?? 0) * DEG,\n rotationZ: c.rotation,\n scaleX: c.scale.x, scaleY: c.scale.y,\n pivotX: c.pivot.x, pivotY: c.pivot.y,\n };\n}\n\n/**\n * Draws one `threeD` sequence: its display object is rendered into a\n * RenderTexture (with its own 2D transform replaced, so layer-local content\n * lands at the texture origin) and shown on a PerspectiveMesh whose four\n * corners come from projecting the layer through the active camera.\n *\n * The sequence's `target` is never in the scene graph; the composition adds\n * `display` instead. `z`, `rotationX`, `rotationY` live on `target` as plain\n * numeric props so GSAP tweens them like any other prop.\n */\nexport class Layer3D {\n readonly display: PerspectiveMesh;\n /** Camera-space depth from the last update (larger = farther). */\n depth = 0;\n private rt: RenderTexture | null = null;\n /**\n * Textures replaced by a bigger / smaller one. Destroying one right away warns \"destroyed while still\n * bound\": the mesh's bind group still points at it until the next render. They go at the next update,\n * by which time a frame has been drawn with the new texture.\n */\n private retired: RenderTexture[] = [];\n private size: TextureSize | null = null;\n private warnedBehind = false;\n\n constructor(\n private readonly seq: Sequence,\n private readonly frameOf: () => Rect,\n ) {\n const target = seq.target as Carrier;\n target.z ??= 0;\n target.rotationX ??= 0;\n target.rotationY ??= 0;\n this.display = new PerspectiveMesh({ texture: Texture.WHITE, verticesX: MESH_GRID, verticesY: MESH_GRID });\n if (seq.spec.name) this.display.label = seq.spec.name;\n this.display.visible = false;\n }\n\n update(host: SpaceHost, basis: CameraBasis): void {\n this.flushRetired();\n const target = this.seq.target as Carrier | null;\n // Pixi skips rendering (and clearing) a container that is not `visible`\n // (e.g. PixiPlugin autoAlpha at alpha 0), which would leave a stale texture.\n if (!target || !target.renderable || !target.visible) return this.hide();\n\n const bounds = this.frameOf();\n const pad = filterPadding(target);\n const needW = Math.ceil(bounds.width + 2 * pad);\n const needH = Math.ceil(bounds.height + 2 * pad);\n if (!(needW >= 1 && needH >= 1) || !Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) return this.hide();\n\n const size = this.sizeFor(needW, needH);\n // The quad covers exactly the texture's pixel rect in layer space.\n const frame: Rect = { x: bounds.x - pad, y: bounds.y - pad, width: size.w, height: size.h };\n const projected = projectLayer(readLayerTransform(target), frame, basis);\n this.depth = projected.depth;\n if (!projected.visible) {\n if (!this.warnedBehind) {\n this.warnedBehind = true;\n if (projected.depth > NEAR) {\n // the layer's own origin is in front of the camera: a tilt or a large size swings a CORNER past the camera plane\n console.warn(\n `pixi-effects: ${describeLayer(this.seq.spec)}: part of it (a corner) reaches the camera plane (z = ${(target.z ?? 0).toFixed(0)}, rotationX ${(target.rotationX ?? 0).toFixed(0)}°, rotationY ${(target.rotationY ?? 0).toFixed(0)}°), ` +\n `and a layer is hidden whole when any corner is at or behind it. Tilt it less (rotationX / rotationY), make it smaller, or keep the camera further away from it ` +\n `(the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`,\n );\n } else {\n console.warn(\n `pixi-effects: ${describeLayer(this.seq.spec)} is at or behind the camera plane (z = ${(target.z ?? 0).toFixed(0)}) and is hidden. ` +\n `If that is unintended, lower its z or move the camera back (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`,\n );\n }\n }\n return this.hide();\n }\n\n this.ensureTexture(size);\n // `transform` replaces the container's own local transform for this render\n // (Pixi RenderGroupSystem), while `container.alpha` still applies — so the\n // texture carries the layer's alpha and the mesh alpha stays at 1.\n host.render({\n container: target,\n target: this.rt!,\n transform: new Matrix().translate(-frame.x, -frame.y),\n clear: true,\n clearColor: [0, 0, 0, 0],\n });\n this.display.geometry.setCorners(...projected.corners);\n this.display.visible = true;\n }\n\n destroy(): void {\n this.display.destroy();\n this.rt?.destroy(true);\n this.rt = null;\n this.flushRetired();\n }\n\n private flushRetired(): void {\n for (const t of this.retired) t.destroy(true);\n this.retired = [];\n }\n\n private hide(): void {\n this.display.visible = false;\n }\n\n /**\n * Texture size for content of w×h. An existing texture is kept while it is at\n * least that big and at most 2x too big, so content whose bounds change every\n * frame (typewriter text, growing shapes) does not reallocate each frame.\n */\n private sizeFor(w: number, h: number): TextureSize {\n const cur = this.size;\n if (cur && cur.w >= w && cur.h >= h && cur.w <= 2 * w && cur.h <= 2 * h) return cur;\n const resolution = Math.min(\n SUPERSAMPLE,\n MAX_TEXTURE_SIZE / Math.max(w, h),\n Math.sqrt(MAX_TEXTURE_PIXELS / (w * h)),\n );\n const antialias = w * h * resolution * resolution <= ANTIALIAS_MAX_PIXELS;\n return { w, h, resolution, antialias };\n }\n\n private ensureTexture(size: TextureSize): void {\n if (this.rt && this.size === size) return;\n // Same sampling: resize the texture where it is. Replacing it makes Pixi warn that the old one was\n // destroyed while still bound, because the mesh keeps pointing at it until the next render.\n if (this.rt && this.size && this.size.antialias === size.antialias) {\n this.rt.resize(size.w, size.h, size.resolution);\n this.size = size;\n return;\n }\n const next = RenderTexture.create({\n width: size.w, height: size.h, resolution: size.resolution, antialias: size.antialias,\n });\n this.display.texture = next;\n if (this.rt) this.retired.push(this.rt);\n this.rt = next;\n this.size = size;\n }\n}\n","import { collectPropKeys } from './specKeys';\nimport { describeLayer } from '../core/lint';\nimport type { SequenceSpec } from '../types';\n\ntype Warn = (message: string) => void;\nconst defaultWarn: Warn = m => console.warn(m);\n\nconst FOV_HINT = 'perspective is the camera\\'s \"fov\" — add a { type: \"camera\" } layer and set fov in its initial / keyframes';\n\n/** Keys that are never valid for any layer, with a hint at what the author probably meant. */\nconst LAYER_ALIASES: Record<string, string> = {\n rotateX: 'did you mean \"rotationX\"?',\n rotateY: 'did you mean \"rotationY\"?',\n rotateZ: 'did you mean \"rotation\"?',\n rotationZ: 'did you mean \"rotation\" (it is the Z rotation)?',\n translateZ: 'did you mean \"z\"?',\n depth: 'did you mean \"z\"?',\n posZ: 'did you mean \"z\"?',\n perspective: FOV_HINT,\n zoom: FOV_HINT,\n};\n\n/** Camera-only mistakes. */\nconst CAMERA_ALIASES: Record<string, string> = {\n pointOfInterest: 'did you mean \"lookAtX / lookAtY / lookAtZ\"?',\n lookAt: 'did you mean \"lookAtX / lookAtY / lookAtZ\"?',\n};\n\nconst CAMERA_PROPS = ['x', 'y', 'z', 'fov', 'lookAtX', 'lookAtY', 'lookAtZ'];\nconst NEEDS_THREE_D = ['z', 'rotationX', 'rotationY'];\nconst SKEW_KEYS = ['skew', 'skewX', 'skewY'];\n\n/**\n * Warn (never throw) about the inputs an AI author is most likely to get wrong,\n * with a message that says what to change. One call per layer, at build time.\n */\nexport function lintSequence(spec: SequenceSpec, warn: Warn = defaultWarn): void {\n const who = describeLayer(spec);\n const keys = collectPropKeys(spec);\n const explained = new Set<string>();\n\n for (const k of keys) {\n const hint = LAYER_ALIASES[k] ?? (spec.type === 'camera' ? CAMERA_ALIASES[k] : undefined);\n if (hint) {\n explained.add(k);\n warn(`pixi-effects: ${who}: \"${k}\" is not a property — ${hint}`);\n }\n }\n\n if (spec.type === 'camera') {\n const raw = spec as unknown as Record<string, unknown>;\n for (const p of CAMERA_PROPS) {\n if (p in raw) warn(`pixi-effects: ${who}: \"${p}\" must go inside initial / keyframes, not on the camera itself`);\n }\n for (const k of Object.keys(raw)) {\n const hint = CAMERA_ALIASES[k] ?? LAYER_ALIASES[k];\n if (hint) warn(`pixi-effects: ${who}: \"${k}\" is not a property — ${hint} (inside initial)`);\n }\n for (const k of keys) {\n if (!explained.has(k) && !CAMERA_PROPS.includes(k)) {\n warn(`pixi-effects: ${who}: \"${k}\" has no effect on a camera (use ${CAMERA_PROPS.join(', ')})`);\n }\n }\n return;\n }\n\n if (spec.type === 'audio') {\n if (spec.threeD) warn(`pixi-effects: ${who}: threeD has no effect on audio`);\n return;\n }\n\n if (!spec.threeD) {\n for (const k of NEEDS_THREE_D) {\n if (keys.has(k)) warn(`pixi-effects: ${who}: \"${k}\" needs threeD: true (it is ignored otherwise)`);\n }\n } else {\n for (const k of SKEW_KEYS) {\n if (keys.has(k)) warn(`pixi-effects: ${who}: \"${k}\" is ignored on threeD layers`);\n }\n }\n}\n","import { describeLayer } from './lint';\n\nconst MODES = ['normal', 'add', 'screen', 'multiply'];\n\n/** Apply a layer's `blendMode` to its display object; an unknown mode warns and is ignored. */\nexport function applyBlendMode(spec: { blendMode?: string; name?: string; type: string }, display: { blendMode?: unknown; filters?: unknown }): void {\n const mode = spec.blendMode;\n if (mode === undefined) return;\n if (!MODES.includes(mode)) {\n console.warn(`pixi-effects: ${describeLayer(spec)}: blendMode \"${mode}\" is not supported (use ${MODES.join(', ')})`);\n return;\n }\n // A container's blend mode applies INSIDE a filter's offscreen pass (against transparent black: multiply gave\n // solid black) and not to the filtered result. With filters, the pass that draws onto the backdrop is the last\n // filter's, so the mode goes there; the container stays normal.\n const filters = display.filters;\n if (Array.isArray(filters) && filters.length > 0) {\n (filters[filters.length - 1] as { blendMode?: unknown }).blendMode = mode;\n return;\n }\n display.blendMode = mode;\n}\n","import { Container, Rectangle } from 'pixi.js';\nimport { Sequence } from './Base';\nimport { NullSequence } from './Null';\nimport { suggestName } from '../core/options';\nimport { buildSequenceTree } from '../core/Composition';\nimport { CameraSequence } from '../space/CameraSequence';\nimport { findOverlap, pickActiveCamera } from '../space/camera';\nimport { assignDepthOrder } from '../space/depth';\nimport { Layer3D, type SpaceHost } from '../space/Layer3D';\nimport { lintSequence } from '../space/lint';\nimport { describeLayer, lintText, lintTiming, summarizeWarnings } from '../core/lint';\nimport { applyBlendMode } from '../core/blend';\nimport { cameraBasis, homeCamera } from '../space/math';\nimport type { CompositionSequenceSpec, AudioDescriptor, CompositionShape, SequenceSpec } from '../types';\n\nimport type { gsap } from 'gsap';\ntype Timeline = ReturnType<typeof gsap.timeline>;\n\nexport class CompositionSequence extends Sequence {\n declare spec: CompositionSequenceSpec;\n private _innerContainer: Container | null = null;\n private _compositionShape: CompositionShape | null = null;\n _children: Sequence[] = [];\n private _cameras: CameraSequence[] = [];\n private _layers3d: Layer3D[] = [];\n /** Drawn children in stack order (cameras and target-less sequences excluded). */\n private _visual: Array<{ seq: Sequence; layer: Layer3D | null }> = [];\n /** Layers drawn inside a null layer (`parent`): they are not in the composition's own stack. */\n private _nested: Sequence[] = [];\n /** The null layer each parented layer is drawn inside. */\n private _parentOf = new Map<Sequence, NullSequence>();\n\n async build(): Promise<void> {\n const width = this.spec.width ?? this.parent?.width ?? this.root.width;\n const height = this.spec.height ?? this.parent?.height ?? this.root.height;\n if (this.duration === undefined) {\n this.duration = this.spec.duration ?? this.parent?.duration ?? this.root.duration;\n }\n const wrapper = new Container();\n wrapper.cullable = true;\n wrapper.cullableChildren = true;\n wrapper.cullArea = new Rectangle(0, 0, width, height);\n\n const inner = new Container();\n inner.cullable = true;\n inner.cullableChildren = true;\n wrapper.addChild(inner);\n\n this.target = wrapper;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this._innerContainer = inner;\n this._compositionShape = { width, height, duration: this.duration };\n\n const lateKeyframes: string[] = [];\n for (const s of this.spec.sequences ?? []) {\n lintSequence(s);\n lintTiming(s, this.duration, (message, kind) => (kind === 'late-keyframe' ? lateKeyframes.push(message) : console.warn(message)));\n lintText(s);\n }\n for (const message of summarizeWarnings(lateKeyframes)) console.warn(message);\n\n this._children = await buildSequenceTree(\n this.spec.sequences ?? [],\n this._compositionShape,\n this.root,\n );\n this._resolveParents();\n for (const child of this._children) {\n // Cameras are display-less: they only feed the projection pass.\n if (child instanceof CameraSequence) {\n this._cameras.push(child);\n continue;\n }\n if (!child.target) continue;\n const holder = this._parentOf.get(child);\n const into = holder?.target ?? inner; // a layer with `parent` is drawn inside its null layer\n\n const maskSpec = (child.spec as { mask?: SequenceSpec }).mask;\n\n // threeD layers never enter the scene graph themselves: their display\n // object is rendered into a texture and a perspective mesh stands in.\n if (child.spec.threeD) {\n const layer = new Layer3D(child, frameOf(child));\n inner.addChild(layer.display);\n this._layers3d.push(layer);\n this._visual.push({ seq: child, layer });\n applyBlendMode(child.spec, layer.display);\n if (maskSpec) {\n console.warn(`pixi-effects: ${describeLayer(child.spec)}: mask is not supported on threeD layers yet; ignored`);\n }\n continue;\n }\n\n into.addChild(child.target);\n if (holder) this._nested.push(child);\n else this._visual.push({ seq: child, layer: null });\n applyBlendMode(child.spec, child.target);\n // If this child has a `mask` spec, build the mask sequence in the same\n // composition shape, add its target to the same parent (so its\n // transforms resolve in the same coord space), and wire PIXI's\n // mask channel. PIXI v8 renders mask containers into the stencil /\n // alpha buffer; they don't render as normal children.\n if (maskSpec) {\n // The mask lives and animates with the layer it masks: with no `at` of its own its `at` and\n // `duration` are the layer's, so its keyframes are measured from the layer's start too. An\n // explicit `at` is composition time, exactly like a layer's.\n const lifetime = maskSpec.at === undefined\n ? { at: child.at, duration: maskSpec.duration ?? child.duration }\n : {};\n const built = await buildSequenceTree([{ ...maskSpec, ...lifetime } as SequenceSpec], this._compositionShape, this.root);\n const maskSeq = built[0];\n if (maskSeq?.target) {\n into.addChild(maskSeq.target); // the mask shares the layer's space\n // PIXI v8 `setMask` accepts an `inverse` flag — that's how we\n // expose `maskInverted` from the spec. Falls back to plain\n // `target.mask = …` for runtimes that don't have setMask\n // (older PIXI builds).\n const inverse = (child.spec as { maskInverted?: boolean }).maskInverted ?? false;\n const t = child.target as Container & {\n setMask?: (opts: { mask: Container | null; inverse?: boolean }) => void;\n mask: Container | null;\n };\n if (typeof t.setMask === 'function') {\n t.setMask({ mask: maskSeq.target, inverse });\n } else {\n t.mask = maskSeq.target;\n }\n child.maskSequence = maskSeq;\n maskSeq.keepHidden = maskSpec.type === 'image' || maskSpec.type === 'video'; // PIXI: a Sprite mask is hidden by renderable = false\n }\n }\n }\n\n if (this._layers3d.length > 0) {\n // Stack order becomes explicit zIndex so threeD layers can be re-sorted\n // by depth each frame without reparenting.\n inner.sortableChildren = true;\n this._visual.forEach((v, i) => {\n (v.layer?.display ?? v.seq.target!).zIndex = i;\n });\n } else if (this._cameras.length > 0) {\n console.warn('pixi-effects: camera has no effect: this composition has no threeD layers');\n }\n\n this.buildFilters();\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n // Children's `at` is relative to this composition's start, so push them\n // forward by our absolute start time on the global timeline.\n const childOffset = offset + this.at;\n for (const child of this._children) {\n child.bindTimeline(timeline, childOffset);\n // The mask shares the maskee's offset — its `at` is interpreted\n // relative to the composition's start, just like the child itself,\n // so a reveal-from-zero animation lines up naturally.\n child.maskSequence?.bindTimeline(timeline, childOffset);\n }\n const overlap = findOverlap(this._cameras.map(c => c.window()));\n if (overlap) {\n console.warn(`pixi-effects: cameras #${overlap[0] + 1} and #${overlap[1] + 1} overlap in time; the top-most one wins`);\n }\n }\n\n /**\n * Drawn children in stack order, with the display object that stands in for each (the mesh for a threeD layer).\n * Null layers draw nothing and are left out; the layers inside them follow, with the null layers that carry them.\n */\n layers(): Array<{ seq: Sequence; display: Container; threeD: boolean; carriers: NullSequence[] }> {\n const carriersOf = (seq: Sequence): NullSequence[] => {\n const out: NullSequence[] = [];\n for (let p = this._parentOf.get(seq); p; p = this._parentOf.get(p)) out.push(p);\n return out;\n };\n return [...this._visual.map(v => v.seq), ...this._nested]\n .filter(seq => !(seq instanceof NullSequence))\n .map(seq => {\n const layer = this._visual.find(v => v.seq === seq)?.layer ?? null;\n return {\n seq,\n display: (layer?.display ?? seq.target!) as unknown as Container,\n threeD: layer !== null,\n carriers: carriersOf(seq),\n };\n });\n }\n\n /** Match every `parent: 'name'` to a null layer; anything that cannot work is said out loud and drawn unparented. */\n private _resolveParents(): void {\n const nulls = this._children.filter((c): c is NullSequence => c instanceof NullSequence);\n const nullNames = nulls.map(n => n.spec.name).filter((n): n is string => !!n);\n const warned = new Set<string>();\n for (const child of this._children) {\n const want = child.spec.parent;\n if (want === undefined) continue;\n const who = describeLayer(child.spec);\n if (child instanceof CameraSequence) { console.warn(`pixi-effects: ${who}: a camera cannot have a parent; ignored`); continue; }\n if (child.spec.threeD) { console.warn(`pixi-effects: ${who}: a threeD layer cannot have a parent (parent \"${want}\" ignored)`); continue; }\n const same = this._children.filter(c => c.spec.name === want);\n if (same.length === 0) {\n const hint = suggestName(want, nullNames);\n console.warn(`pixi-effects: ${who}: parent \"${want}\": no layer with that name${hint ? `; did you mean \"${hint}\"?` : ''} (the layer is drawn without a parent)`);\n continue;\n }\n const holder = same.find((c): c is NullSequence => c instanceof NullSequence);\n if (!holder) {\n console.warn(`pixi-effects: ${who}: parent \"${want}\" is a ${same[0]!.spec.type} layer; only { type: 'null' } layers can be parents (the layer is drawn without a parent)`);\n continue;\n }\n if (same.length > 1 && !warned.has(want)) {\n warned.add(want);\n console.warn(`pixi-effects: ${same.length} layers are named \"${want}\"; parent \"${want}\" uses the first null layer with that name`);\n }\n if (holder === child) { console.warn(`pixi-effects: ${who} is its own parent; ignored`); continue; }\n this._parentOf.set(child, holder);\n }\n // a chain that leads back to itself: break it where we find it\n for (const start of this._children) {\n const seen = new Set<Sequence>([start]);\n for (let p = this._parentOf.get(start); p; p = this._parentOf.get(p)) {\n if (p === start) {\n const names = [...seen].map(s => s.spec.name ?? s.spec.type).join(' → ');\n console.warn(`pixi-effects: parent cycle: ${names} → ${start.spec.name ?? start.spec.type}; the parent of \"${start.spec.name ?? start.spec.type}\" is ignored`);\n this._parentOf.delete(start);\n break;\n }\n if (seen.has(p)) break;\n seen.add(p);\n }\n }\n }\n\n override syncFrame(): void {\n super.syncFrame();\n for (const child of this._children) child.syncFrame();\n }\n\n override updateSpace(t: number, host: SpaceHost): void {\n // Inner compositions first: a threeD composition is rendered into its own\n // texture by this level, so its content must already be projected.\n for (const child of this._children) child.updateSpace(t, host);\n if (this._layers3d.length === 0 || !this._compositionShape) return;\n\n const { width, height } = this._compositionShape;\n const compEnd = (this.absoluteStart ?? 0) + (this.duration ?? 0);\n const active = pickActiveCamera(\n this._cameras.map(cam => ({ cam, ...cam.window() })),\n t,\n compEnd,\n );\n const basis = cameraBasis(active ? active.cam.state() : homeCamera(width, height), width, height);\n\n for (const layer of this._layers3d) layer.update(host, basis);\n\n const order = assignDepthOrder(\n this._visual.map((v, i) => ({ stackIndex: i, threeD: v.layer !== null, depth: v.layer?.depth ?? 0 })),\n );\n this._visual.forEach((v, i) => {\n if (v.layer) v.layer.display.zIndex = order[i]!;\n });\n }\n\n override collectAudio(out: AudioDescriptor[], baseTime: number): void {\n super.collectAudio(out, baseTime);\n const childBase = baseTime + this.at;\n for (const child of this._children) child.collectAudio(out, childBase);\n }\n\n override destroy(): void {\n for (const l of this._layers3d) l.destroy();\n this._layers3d = [];\n for (const c of this._children) c.destroy();\n super.destroy();\n }\n}\n\n/** Layer-space rectangle a threeD child projects: a composition's frame, otherwise its content bounds. */\nfunction frameOf(child: Sequence): () => { x: number; y: number; width: number; height: number } {\n if (child instanceof CompositionSequence) {\n return () => ({ x: 0, y: 0, width: child.intrinsicWidth, height: child.intrinsicHeight });\n }\n return () => child.target!.getLocalBounds();\n}\n"]}
|
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
import { suggestName } from './chunk-DKGG7WD4.js';
|
|
2
2
|
import * as PIXI from 'pixi.js';
|
|
3
|
-
import { Rectangle, Container, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, FillGradient, Color
|
|
3
|
+
import { Rectangle, Container, GraphicsPath, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, FillGradient, Color } from 'pixi.js';
|
|
4
4
|
import { gsap } from 'gsap';
|
|
5
5
|
|
|
6
|
+
// src/expr/random.ts
|
|
7
|
+
function mix(h) {
|
|
8
|
+
h = Math.imul(h ^ h >>> 16, 2246822507);
|
|
9
|
+
h = Math.imul(h ^ h >>> 13, 3266489909);
|
|
10
|
+
return (h ^ h >>> 16) >>> 0;
|
|
11
|
+
}
|
|
12
|
+
function fold(n) {
|
|
13
|
+
if (!Number.isFinite(n)) return 0;
|
|
14
|
+
const i = Math.floor(n);
|
|
15
|
+
const f = n - i;
|
|
16
|
+
return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
|
|
17
|
+
}
|
|
18
|
+
function rand(seed) {
|
|
19
|
+
return mix(fold(seed) + 2654435769) / 4294967296;
|
|
20
|
+
}
|
|
21
|
+
function random(seed) {
|
|
22
|
+
let a = fold(seed) + 1831565813 | 0;
|
|
23
|
+
return () => {
|
|
24
|
+
a = a + 1831565813 | 0;
|
|
25
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
26
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
27
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function noise(x, seed = 0) {
|
|
31
|
+
if (!Number.isFinite(x)) return 0;
|
|
32
|
+
const i = Math.floor(x);
|
|
33
|
+
const f = x - i;
|
|
34
|
+
const s = fold(seed) * 668265261;
|
|
35
|
+
const a = mix((i | 0) + s) / 2147483648 - 1;
|
|
36
|
+
const b = mix((i + 1 | 0) + s) / 2147483648 - 1;
|
|
37
|
+
const u = f * f * f * (f * (f * 6 - 15) + 10);
|
|
38
|
+
return a + (b - a) * u;
|
|
39
|
+
}
|
|
40
|
+
|
|
6
41
|
// src/expr/Parser.ts
|
|
7
42
|
var FUNCS = {
|
|
8
43
|
min: Math.min,
|
|
@@ -15,8 +50,19 @@ var FUNCS = {
|
|
|
15
50
|
pow: Math.pow,
|
|
16
51
|
sin: Math.sin,
|
|
17
52
|
cos: Math.cos,
|
|
18
|
-
tan: Math.tan
|
|
53
|
+
tan: Math.tan,
|
|
54
|
+
rand: (seed) => rand(seed),
|
|
55
|
+
noise: (x, seed = 0) => noise(x, seed),
|
|
56
|
+
lerp: (a, b, t) => a + (b - a) * t,
|
|
57
|
+
clamp: (x, lo, hi) => Math.min(Math.max(x, lo), hi),
|
|
58
|
+
smoothstep: (a, b, x) => {
|
|
59
|
+
const u = Math.min(Math.max((x - a) / (b - a), 0), 1);
|
|
60
|
+
return u * u * (3 - 2 * u);
|
|
61
|
+
},
|
|
62
|
+
mod: (a, b) => (a % b + b) % b,
|
|
63
|
+
step: (edge, x) => x >= edge ? 1 : 0
|
|
19
64
|
};
|
|
65
|
+
var CONSTS = { PI: Math.PI };
|
|
20
66
|
function isDigit(c) {
|
|
21
67
|
return c >= "0" && c <= "9";
|
|
22
68
|
}
|
|
@@ -162,6 +208,7 @@ function evalNode(node, scope) {
|
|
|
162
208
|
case "num":
|
|
163
209
|
return node.value;
|
|
164
210
|
case "var": {
|
|
211
|
+
if (node.name in CONSTS) return CONSTS[node.name];
|
|
165
212
|
const v = scope[node.name];
|
|
166
213
|
if (typeof v !== "number") throw new Error(`undefined variable: ${node.name}`);
|
|
167
214
|
return v;
|
|
@@ -943,6 +990,12 @@ var Sequence = class {
|
|
|
943
990
|
this.target = null;
|
|
944
991
|
}
|
|
945
992
|
};
|
|
993
|
+
var NullSequence = class extends Sequence {
|
|
994
|
+
async build() {
|
|
995
|
+
this.target = new Container();
|
|
996
|
+
this.buildFilters();
|
|
997
|
+
}
|
|
998
|
+
};
|
|
946
999
|
|
|
947
1000
|
// src/space/specKeys.ts
|
|
948
1001
|
function collectPropKeys(spec) {
|
|
@@ -2073,6 +2126,85 @@ function slice(line, a, b) {
|
|
|
2073
2126
|
return out;
|
|
2074
2127
|
}
|
|
2075
2128
|
|
|
2129
|
+
// src/sequences/morphPath.ts
|
|
2130
|
+
function resample(line, n) {
|
|
2131
|
+
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
2132
|
+
const cum = [0];
|
|
2133
|
+
for (let i = 2; i < p.length; i += 2) cum.push(cum[cum.length - 1] + Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]));
|
|
2134
|
+
const total = cum[cum.length - 1];
|
|
2135
|
+
const out = [];
|
|
2136
|
+
if (!(total > 0)) {
|
|
2137
|
+
for (let i = 0; i < n; i++) out.push(p[0], p[1]);
|
|
2138
|
+
return out;
|
|
2139
|
+
}
|
|
2140
|
+
let seg = 1;
|
|
2141
|
+
for (let i = 0; i < n; i++) {
|
|
2142
|
+
const s = line.closed ? i * total / n : n === 1 ? 0 : i * total / (n - 1);
|
|
2143
|
+
while (seg < cum.length - 1 && cum[seg] < s) seg++;
|
|
2144
|
+
const len = cum[seg] - cum[seg - 1];
|
|
2145
|
+
const t = len > 0 ? (s - cum[seg - 1]) / len : 0;
|
|
2146
|
+
const k = seg * 2;
|
|
2147
|
+
out.push(p[k - 2] + (p[k] - p[k - 2]) * t, p[k - 1] + (p[k + 1] - p[k - 1]) * t);
|
|
2148
|
+
}
|
|
2149
|
+
return out;
|
|
2150
|
+
}
|
|
2151
|
+
var centroid = (pts) => {
|
|
2152
|
+
let x = 0, y = 0;
|
|
2153
|
+
for (let i = 0; i < pts.length; i += 2) {
|
|
2154
|
+
x += pts[i];
|
|
2155
|
+
y += pts[i + 1];
|
|
2156
|
+
}
|
|
2157
|
+
const n = pts.length / 2;
|
|
2158
|
+
return [x / n, y / n];
|
|
2159
|
+
};
|
|
2160
|
+
function align(a, b) {
|
|
2161
|
+
const n = a.length / 2;
|
|
2162
|
+
let best = b, bestCost = Infinity;
|
|
2163
|
+
for (const reversed of [false, true]) {
|
|
2164
|
+
for (let k = 0; k < n; k++) {
|
|
2165
|
+
let cost = 0;
|
|
2166
|
+
for (let i = 0; i < n && cost < bestCost; i++) {
|
|
2167
|
+
const j = reversed ? ((k - i) % n + n) % n : (k + i) % n;
|
|
2168
|
+
cost += (a[2 * i] - b[2 * j]) ** 2 + (a[2 * i + 1] - b[2 * j + 1]) ** 2;
|
|
2169
|
+
}
|
|
2170
|
+
if (cost < bestCost) {
|
|
2171
|
+
bestCost = cost;
|
|
2172
|
+
const out = [];
|
|
2173
|
+
for (let i = 0; i < n; i++) {
|
|
2174
|
+
const j = reversed ? ((k - i) % n + n) % n : (k + i) % n;
|
|
2175
|
+
out.push(b[2 * j], b[2 * j + 1]);
|
|
2176
|
+
}
|
|
2177
|
+
best = out;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
return best;
|
|
2182
|
+
}
|
|
2183
|
+
function buildMorph(from, to, n = 128) {
|
|
2184
|
+
if (from.length === 0 || to.length === 0) return [];
|
|
2185
|
+
const pairs = [];
|
|
2186
|
+
const count = Math.max(from.length, to.length);
|
|
2187
|
+
for (let i = 0; i < count; i++) {
|
|
2188
|
+
const fa = from[i], fb = to[i];
|
|
2189
|
+
const closed = (fa?.closed ?? fb.closed) && (fb?.closed ?? fa.closed);
|
|
2190
|
+
const a = fa ? resample({ pts: fa.pts, closed }, n) : collapsed(resample({ pts: fb.pts, closed }, n));
|
|
2191
|
+
let b = fb ? resample({ pts: fb.pts, closed }, n) : collapsed(a);
|
|
2192
|
+
if (closed && fa && fb) b = align(a, b);
|
|
2193
|
+
pairs.push({ a, b, closed });
|
|
2194
|
+
}
|
|
2195
|
+
return pairs;
|
|
2196
|
+
}
|
|
2197
|
+
function collapsed(pts) {
|
|
2198
|
+
const [cx, cy] = centroid(pts);
|
|
2199
|
+
const out = [];
|
|
2200
|
+
for (let i = 0; i < pts.length; i += 2) out.push(cx, cy);
|
|
2201
|
+
return out;
|
|
2202
|
+
}
|
|
2203
|
+
function morphAt(pairs, t) {
|
|
2204
|
+
const u = Math.min(Math.max(t, 0), 1);
|
|
2205
|
+
return pairs.map(({ a, b, closed }) => ({ pts: a.map((v, i) => v + (b[i] - v) * u), closed }));
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2076
2208
|
// src/sequences/Shape.ts
|
|
2077
2209
|
var STYLE_KEYS = ["fillColor", "fillAlpha", "strokeColor", "strokeAlpha", "strokeWidth"];
|
|
2078
2210
|
var COLOR_KEYS = /* @__PURE__ */ new Set(["fillColor", "strokeColor"]);
|
|
@@ -2084,7 +2216,7 @@ var GEOMETRY_KEYS_BY_SHAPE = {
|
|
|
2084
2216
|
arc: ["radius", "innerRadius", "startAngle", "endAngle"],
|
|
2085
2217
|
line: [...TRIM_KEYS],
|
|
2086
2218
|
polygon: [...TRIM_KEYS],
|
|
2087
|
-
path: [...TRIM_KEYS]
|
|
2219
|
+
path: [...TRIM_KEYS, "morph"]
|
|
2088
2220
|
};
|
|
2089
2221
|
var ANCHORED_SHAPES = /* @__PURE__ */ new Set(["rect", "circle", "ellipse", "arc"]);
|
|
2090
2222
|
var ShapeSequence = class extends Sequence {
|
|
@@ -2127,8 +2259,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
2127
2259
|
}
|
|
2128
2260
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
2129
2261
|
if (gradientSpec) this._state.fillStyle = makeGradientFill(gradientSpec);
|
|
2130
|
-
|
|
2131
|
-
this.
|
|
2262
|
+
const morph = this._setupMorph();
|
|
2263
|
+
this._drawGeometry = makeDrawGeometry(this.spec, scope, this._state, morph);
|
|
2264
|
+
this._outline = makeOutline(this.spec, scope, this._state, morph);
|
|
2132
2265
|
const { trimStart, trimEnd } = this._state;
|
|
2133
2266
|
this._state.trimStart = 0;
|
|
2134
2267
|
this._state.trimEnd = 1;
|
|
@@ -2157,6 +2290,33 @@ var ShapeSequence = class extends Sequence {
|
|
|
2157
2290
|
this._redraw();
|
|
2158
2291
|
this.buildFilters();
|
|
2159
2292
|
}
|
|
2293
|
+
/** The prepared morph between `d` and `morphTo`, or null (and a warning when the spec asked for one that cannot work). */
|
|
2294
|
+
_setupMorph() {
|
|
2295
|
+
const who = describeLayer(this.spec);
|
|
2296
|
+
const top = this.spec;
|
|
2297
|
+
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 || collectPropKeys(this.spec).has("morph"));
|
|
2298
|
+
if (this.spec.shape !== "path") {
|
|
2299
|
+
if ("morphTo" in top) console.warn(`pixi-effects: ${who}: morphTo only works on a path shape (shape: 'path'); ignored`);
|
|
2300
|
+
return null;
|
|
2301
|
+
}
|
|
2302
|
+
if (top.morphTo === void 0) {
|
|
2303
|
+
if (wanted) console.warn(`pixi-effects: ${who}: morph needs morphTo (the outline to morph into); ignored`);
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
let points2 = 128;
|
|
2307
|
+
if (top.morphPoints !== void 0) {
|
|
2308
|
+
const n = Number(top.morphPoints);
|
|
2309
|
+
if (Number.isInteger(n) && n >= 8 && n <= 2048) points2 = n;
|
|
2310
|
+
else console.warn(`pixi-effects: ${who}: morphPoints must be a whole number from 8 to 2048, got ${String(top.morphPoints)}; using 128`);
|
|
2311
|
+
}
|
|
2312
|
+
const pairs = buildMorph(flattenSvgPath(this.spec.d), flattenSvgPath(String(top.morphTo)), points2);
|
|
2313
|
+
if (pairs.length === 0) {
|
|
2314
|
+
console.warn(`pixi-effects: ${who}: morphTo "${String(top.morphTo)}" (or d) draws nothing, so there is nothing to morph; ignored`);
|
|
2315
|
+
return null;
|
|
2316
|
+
}
|
|
2317
|
+
this._state.morph ??= 0;
|
|
2318
|
+
return { pairs, to: String(top.morphTo) };
|
|
2319
|
+
}
|
|
2160
2320
|
_fresh = false;
|
|
2161
2321
|
_outline = null;
|
|
2162
2322
|
_redraw() {
|
|
@@ -2391,7 +2551,7 @@ var STATE_DRAWERS = {
|
|
|
2391
2551
|
ellipse: drawEllipseFromState,
|
|
2392
2552
|
arc: drawArcFromState
|
|
2393
2553
|
};
|
|
2394
|
-
function makeDrawGeometry(spec, scope, state) {
|
|
2554
|
+
function makeDrawGeometry(spec, scope, state, morph) {
|
|
2395
2555
|
const stateDrawer = STATE_DRAWERS[spec.shape];
|
|
2396
2556
|
if (stateDrawer) return (g) => stateDrawer(g, state);
|
|
2397
2557
|
switch (spec.shape) {
|
|
@@ -2399,13 +2559,30 @@ function makeDrawGeometry(spec, scope, state) {
|
|
|
2399
2559
|
return makeLineDraw(spec, scope);
|
|
2400
2560
|
case "polygon":
|
|
2401
2561
|
return makePolygonDraw(spec, scope);
|
|
2402
|
-
case "path":
|
|
2403
|
-
|
|
2562
|
+
case "path": {
|
|
2563
|
+
const plain = makePathDraw(spec);
|
|
2564
|
+
if (!morph) return plain;
|
|
2565
|
+
const last = makePathDraw({ ...spec, d: morph.to });
|
|
2566
|
+
return (g) => {
|
|
2567
|
+
const t = state.morph ?? 0;
|
|
2568
|
+
if (t <= 0) plain(g);
|
|
2569
|
+
else if (t >= 1) last(g);
|
|
2570
|
+
else for (const part of morphAt(morph.pairs, t)) drawPolyline(g, part);
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2404
2573
|
}
|
|
2405
2574
|
return () => {
|
|
2406
2575
|
};
|
|
2407
2576
|
}
|
|
2408
|
-
function
|
|
2577
|
+
function drawPolyline(g, part) {
|
|
2578
|
+
if (part.closed) {
|
|
2579
|
+
g.poly(part.pts, true);
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
g.moveTo(part.pts[0], part.pts[1]);
|
|
2583
|
+
for (let i = 2; i < part.pts.length; i += 2) g.lineTo(part.pts[i], part.pts[i + 1]);
|
|
2584
|
+
}
|
|
2585
|
+
function makeOutline(spec, scope, s, morph) {
|
|
2409
2586
|
switch (spec.shape) {
|
|
2410
2587
|
case "rect":
|
|
2411
2588
|
return () => {
|
|
@@ -2433,6 +2610,7 @@ function makeOutline(spec, scope, s) {
|
|
|
2433
2610
|
return () => lines;
|
|
2434
2611
|
}
|
|
2435
2612
|
case "path": {
|
|
2613
|
+
if (morph) return () => morphAt(morph.pairs, s.morph ?? 0);
|
|
2436
2614
|
let lines = null;
|
|
2437
2615
|
return () => lines ??= flattenSvgPath(spec.d);
|
|
2438
2616
|
}
|
|
@@ -2513,7 +2691,7 @@ function numOrZero(v, scope) {
|
|
|
2513
2691
|
var _CompositionSequence = null;
|
|
2514
2692
|
async function getCompositionSequence() {
|
|
2515
2693
|
if (!_CompositionSequence) {
|
|
2516
|
-
_CompositionSequence = (await import('./Composition-
|
|
2694
|
+
_CompositionSequence = (await import('./Composition-NJCOMGD7.js')).CompositionSequence;
|
|
2517
2695
|
}
|
|
2518
2696
|
return _CompositionSequence;
|
|
2519
2697
|
}
|
|
@@ -2523,7 +2701,8 @@ var staticTypes = {
|
|
|
2523
2701
|
audio: AudioSequence,
|
|
2524
2702
|
video: VideoSequence,
|
|
2525
2703
|
shape: ShapeSequence,
|
|
2526
|
-
camera: CameraSequence
|
|
2704
|
+
camera: CameraSequence,
|
|
2705
|
+
null: NullSequence
|
|
2527
2706
|
};
|
|
2528
2707
|
var registry2 = {};
|
|
2529
2708
|
function registerSequenceType(type, ctor) {
|
|
@@ -2550,6 +2729,6 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
2550
2729
|
return out;
|
|
2551
2730
|
}
|
|
2552
2731
|
|
|
2553
|
-
export { CameraSequence, DEFAULT_FOV, DEG, NEAR, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, describeLayer, ensureFilterLibrary, evaluateExpr, homeCamera, homeDistance, lintText, lintTiming, projectLayer, registerSequenceType, resolveAt, summarizeWarnings };
|
|
2554
|
-
//# sourceMappingURL=chunk-
|
|
2555
|
-
//# sourceMappingURL=chunk-
|
|
2732
|
+
export { CameraSequence, DEFAULT_FOV, DEG, NEAR, NullSequence, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, describeLayer, ensureFilterLibrary, evaluateExpr, flattenSvgPath, homeCamera, homeDistance, lintText, lintTiming, noise, projectLayer, rand, random, registerSequenceType, resolveAt, summarizeWarnings };
|
|
2733
|
+
//# sourceMappingURL=chunk-JAMNDBXW.js.map
|
|
2734
|
+
//# sourceMappingURL=chunk-JAMNDBXW.js.map
|