pixi-effects 0.43.0 → 0.44.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 +10 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +131 -2
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/{Movie-BdUm2Mc9.d.cts → Movie-B3VOAgwc.d.cts} +3 -3
- package/dist/{Movie-B_qQIYV6.d.ts → Movie-CQCVUqRs.d.ts} +3 -3
- package/dist/{chunk-6N5ZBUOU.js → chunk-4MBTYREC.js} +81 -31
- package/dist/chunk-4MBTYREC.js.map +1 -0
- package/dist/{chunk-BEGOKE7Q.cjs → chunk-MAAM45ZX.cjs} +80 -30
- package/dist/chunk-MAAM45ZX.cjs.map +1 -0
- package/dist/index.cjs +25 -25
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/loader.css +1 -1
- package/dist/present.cjs +1 -1
- package/dist/present.d.cts +2 -2
- package/dist/present.d.ts +2 -2
- package/dist/present.js +1 -1
- package/dist/three.cjs +86 -16
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +22 -2
- package/dist/three.d.ts +22 -2
- package/dist/three.js +86 -16
- package/dist/three.js.map +1 -1
- package/dist/{types-DiNHtdrS.d.cts → types-C5xo0fzb.d.cts} +74 -2
- package/dist/{types-DiNHtdrS.d.ts → types-C5xo0fzb.d.ts} +74 -2
- package/docs/api.md +4 -2
- package/docs/dsl.md +1 -0
- package/llms-full.txt +9 -6
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +2 -2
- package/skills/pixi-effects/reference/recipes.md +2 -2
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Base-DKFQtqzW.d.ts +0 -60
- package/dist/Base-lb5Uhaqu.d.cts +0 -60
- package/dist/chunk-6N5ZBUOU.js.map +0 -1
- package/dist/chunk-BEGOKE7Q.cjs.map +0 -1
|
@@ -190,7 +190,7 @@ function inspectFonts(root) {
|
|
|
190
190
|
});
|
|
191
191
|
const missing = [];
|
|
192
192
|
const used = /* @__PURE__ */ new Set();
|
|
193
|
-
const
|
|
193
|
+
const walk3 = (seq, index) => {
|
|
194
194
|
const spec = seq.spec;
|
|
195
195
|
if (spec.type === "text") {
|
|
196
196
|
const raw = spec.style?.fontFamily;
|
|
@@ -199,10 +199,10 @@ function inspectFonts(root) {
|
|
|
199
199
|
for (const f of list) used.add(f.replace(/^["']|["']$/g, "").toLowerCase());
|
|
200
200
|
if (list.length && !list.some(fontAvailable) && !list.some((f) => failed.has(f.replace(/^["']|["']$/g, "")))) missing.push({ layer: spec.name ?? `text#${index}`, family: family2 });
|
|
201
201
|
}
|
|
202
|
-
if (seq.maskSequence)
|
|
203
|
-
(seq._children ?? []).forEach((child, i) =>
|
|
202
|
+
if (seq.maskSequence) walk3(seq.maskSequence, index);
|
|
203
|
+
(seq._children ?? []).forEach((child, i) => walk3(child, i));
|
|
204
204
|
};
|
|
205
|
-
|
|
205
|
+
walk3(root, 0);
|
|
206
206
|
const all = [...failed];
|
|
207
207
|
return { missing, failed: all.filter((f) => used.has(f.toLowerCase())), failedUnused: all.filter((f) => !used.has(f.toLowerCase())) };
|
|
208
208
|
}
|
|
@@ -1528,16 +1528,16 @@ function canvasReport(root) {
|
|
|
1528
1528
|
const problem = threw.length ? `${name} could not draw at ${threw.map((t) => `${t} s`).join(", ")} (its ${kind === "three" ? "update or render threw" : "draw threw"}, or the layer failed to build): ${kind === "three" ? "the warning above says why" : "it shows a magenta checkerboard there; the warning above says why"}, so the layer cannot be called deterministic` : differs.length ? `${name} does not draw the same picture for the same time (checked at ${differs.map(describeDiff).join(", ")}; drawn in two orders after one draw that was thrown away): ` + (kind === "three" ? "usually its update uses Math.random, Date.now, a clock, or state that builds up from call to call: a mixer advanced with mixer.update(dt) is one (pose a clip with mixer.setTime(t), or threeGltf(url).pose(t)), and so is a value moved by the time since the last call. A skinned model of your own (not loaded by threeGltf) that moves and casts a shadow does it too: three culls a skinned mesh by a bounding sphere that does not follow it, so set mesh.frustumCulled = false. Set every object from t, so playback, a seek and an export agree" : "usually its draw uses Math.random, Date.now or state that outlives the call (a value it keeps from the last call), so playback, a seek and an export would not agree: use info.random() (seeded) and derive everything from t. If it uses none of these, look at the canvases it draws from: make sprites and masks with info.canvas(w, h) (not document.createElement) and draw them into the picture before the strokes that depend on them") : "";
|
|
1529
1529
|
out.push({ name: seq.spec.name ?? name, moments, drawMs, ok: !differs.length && !threw.length, problem, kind });
|
|
1530
1530
|
}
|
|
1531
|
-
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence)
|
|
1531
|
+
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence) walk3(seq);
|
|
1532
1532
|
};
|
|
1533
|
-
const
|
|
1533
|
+
const walk3 = (comp) => {
|
|
1534
1534
|
for (const { seq } of comp.layers()) {
|
|
1535
1535
|
visit(seq);
|
|
1536
1536
|
const mask = seq.maskSequence;
|
|
1537
1537
|
if (mask) visit(mask);
|
|
1538
1538
|
}
|
|
1539
1539
|
};
|
|
1540
|
-
|
|
1540
|
+
walk3(root);
|
|
1541
1541
|
return out;
|
|
1542
1542
|
}
|
|
1543
1543
|
var canvasProblems = (root) => canvasReport(root).filter((r) => !r.ok).map((r) => r.problem);
|
|
@@ -1604,7 +1604,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1604
1604
|
const specs = /* @__PURE__ */ new Map();
|
|
1605
1605
|
const chains = /* @__PURE__ */ new Map();
|
|
1606
1606
|
const chainAlpha = /* @__PURE__ */ new Map();
|
|
1607
|
-
const
|
|
1607
|
+
const walk3 = (comp, prefix, insideThreeD, parentVisible, parentScene, parentMotion = NO_MOTION, parentZero = false, parentAlpha = 1) => {
|
|
1608
1608
|
const blending = /* @__PURE__ */ new Set();
|
|
1609
1609
|
const now = comp.childTime(time);
|
|
1610
1610
|
const cameraMotion = (comp.spec.sequences ?? []).filter((q) => q.type === "camera").reduce((m, q) => either(m, motionOf(q.keyframes, now - comp.childBase - (q.at ?? 0), q.duration ?? comp.duration ?? Infinity, () => true)), NO_MOTION);
|
|
@@ -1670,10 +1670,10 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1670
1670
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1671
1671
|
if (group) scene.set(info, group);
|
|
1672
1672
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1673
|
-
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence)
|
|
1673
|
+
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence) walk3(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
|
|
1674
1674
|
});
|
|
1675
1675
|
};
|
|
1676
|
-
|
|
1676
|
+
walk3(root, "", false, true);
|
|
1677
1677
|
const issues = [];
|
|
1678
1678
|
const texts = layers.filter((l) => l.type === "text" && l.visible && l.alpha >= FAINT && l.bounds);
|
|
1679
1679
|
for (const l of texts) {
|
|
@@ -1800,7 +1800,7 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1800
1800
|
return true;
|
|
1801
1801
|
};
|
|
1802
1802
|
const inside = (b, p) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
|
|
1803
|
-
const
|
|
1803
|
+
const walk3 = (comp, prefix, parentVisible) => {
|
|
1804
1804
|
comp.layers().forEach(({ seq, display, threeD, carriers, quad }, i) => {
|
|
1805
1805
|
const d = display;
|
|
1806
1806
|
if (!d) return;
|
|
@@ -1813,7 +1813,7 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1813
1813
|
if (!visible) return;
|
|
1814
1814
|
const isComposition = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
|
|
1815
1815
|
if (isComposition && !threeD) {
|
|
1816
|
-
|
|
1816
|
+
walk3(seq, path + "/", visible);
|
|
1817
1817
|
return;
|
|
1818
1818
|
}
|
|
1819
1819
|
if (!wanted(name, path)) return;
|
|
@@ -1841,7 +1841,7 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1841
1841
|
hit = { name, path, type: seq.spec.type, kind: "three", point, three };
|
|
1842
1842
|
} else if (three === void 0 && (typeof d.containsPoint !== "function" || d.containsPoint(local))) {
|
|
1843
1843
|
let opaque = true;
|
|
1844
|
-
const tex = opts.alpha !== void 0 && seq.spec.type !== "shader" ? d.texture : void 0;
|
|
1844
|
+
const tex = opts.alpha !== void 0 && seq.spec.type !== "shader" ? d.texture ?? deps.textureOf?.(d) : void 0;
|
|
1845
1845
|
if (tex?.source?.resource) {
|
|
1846
1846
|
const res = tex.source.resolution ?? 1;
|
|
1847
1847
|
const a = readAlpha(tex.source.resource, (tex.frame.x + (local.x - lb.x) / lb.width * tex.frame.width) * res, (tex.frame.y + (local.y - lb.y) / lb.height * tex.frame.height) * res);
|
|
@@ -1863,9 +1863,56 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1863
1863
|
found.push({ hit, order: orderOf(d) });
|
|
1864
1864
|
});
|
|
1865
1865
|
};
|
|
1866
|
-
|
|
1866
|
+
walk3(root, "", true);
|
|
1867
1867
|
return found.sort((a, b) => above(a.order, b.order)).map((f) => f.hit);
|
|
1868
1868
|
}
|
|
1869
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
1870
|
+
function textPictureOf(display) {
|
|
1871
|
+
if (!(display instanceof pixi_js.Text)) return null;
|
|
1872
|
+
const style = display.style;
|
|
1873
|
+
const key = `${display.text}|${display.resolution}|${style.styleKey ?? ""}`;
|
|
1874
|
+
const kept = cache.get(display);
|
|
1875
|
+
if (kept?.key === key) return kept.picture;
|
|
1876
|
+
try {
|
|
1877
|
+
const { canvasAndContext, frame } = pixi_js.CanvasTextGenerator.getCanvasAndContext({ text: display.text, style: display.style, resolution: display.resolution });
|
|
1878
|
+
const copy = document.createElement("canvas");
|
|
1879
|
+
copy.width = canvasAndContext.canvas.width;
|
|
1880
|
+
copy.height = canvasAndContext.canvas.height;
|
|
1881
|
+
copy.getContext("2d").drawImage(canvasAndContext.canvas, 0, 0);
|
|
1882
|
+
pixi_js.CanvasPool.returnCanvasAndContext(canvasAndContext);
|
|
1883
|
+
const picture = { frame: { x: frame.x, y: frame.y, width: frame.width, height: frame.height }, source: { resolution: display.resolution, resource: copy } };
|
|
1884
|
+
cache.set(display, { key, picture });
|
|
1885
|
+
return picture;
|
|
1886
|
+
} catch {
|
|
1887
|
+
return null;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
// src/core/reuse.ts
|
|
1892
|
+
var lendable = (s) => typeof s.reuseKey === "function";
|
|
1893
|
+
var borrower = (s) => typeof s.commitReuse === "function";
|
|
1894
|
+
function walk(root, visit) {
|
|
1895
|
+
for (const { seq } of root.layers()) {
|
|
1896
|
+
visit(seq);
|
|
1897
|
+
const mask = seq.maskSequence;
|
|
1898
|
+
if (mask) visit(mask);
|
|
1899
|
+
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence) walk(seq, visit);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
function reusePoolOf(old) {
|
|
1903
|
+
const free = /* @__PURE__ */ new Map();
|
|
1904
|
+
if (old) walk(old, (seq) => {
|
|
1905
|
+
if (!lendable(seq)) return;
|
|
1906
|
+
const key = seq.reuseKey();
|
|
1907
|
+
if (key !== null) free.set(key, [...free.get(key) ?? [], seq]);
|
|
1908
|
+
});
|
|
1909
|
+
return { claim: (key) => free.get(key)?.shift() ?? null };
|
|
1910
|
+
}
|
|
1911
|
+
function commitReuse(root) {
|
|
1912
|
+
walk(root, (seq) => {
|
|
1913
|
+
if (borrower(seq)) seq.commitReuse();
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1869
1916
|
|
|
1870
1917
|
// src/core/hover.ts
|
|
1871
1918
|
var keyOf = (h) => h ? `${h.path}${h.three ? `#${h.three.object}` : ""}` : null;
|
|
@@ -1959,7 +2006,7 @@ function detailOf(seq) {
|
|
|
1959
2006
|
if (s.music && typeof s.music === "object") return "music";
|
|
1960
2007
|
return void 0;
|
|
1961
2008
|
}
|
|
1962
|
-
function
|
|
2009
|
+
function walk2(comp, parentStart, parentEnd, depth, prefix, rows, transitions, local) {
|
|
1963
2010
|
const entries = [];
|
|
1964
2011
|
comp._children.forEach((seq, i) => {
|
|
1965
2012
|
const name = seq.spec.name ?? `${seq.spec.type}#${i}`;
|
|
@@ -1972,7 +2019,7 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
|
|
|
1972
2019
|
const isComp = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
|
|
1973
2020
|
if (isComp) {
|
|
1974
2021
|
const label = seq.remapLabel();
|
|
1975
|
-
|
|
2022
|
+
walk2(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
1976
2023
|
}
|
|
1977
2024
|
entries.push({ row, inner, groupable: !isComp });
|
|
1978
2025
|
});
|
|
@@ -2020,7 +2067,7 @@ function collectTimeline(root, duration) {
|
|
|
2020
2067
|
const rows = [];
|
|
2021
2068
|
const transitions = [];
|
|
2022
2069
|
const label = root.remapLabel();
|
|
2023
|
-
|
|
2070
|
+
walk2(root, 0, label ? root.contentSpan : duration, 0, "", rows, transitions, label ? `movie ${label}` : void 0);
|
|
2024
2071
|
return { duration, rows, transitions };
|
|
2025
2072
|
}
|
|
2026
2073
|
var COLORS = {
|
|
@@ -2168,28 +2215,28 @@ function substitute(s, vars) {
|
|
|
2168
2215
|
}
|
|
2169
2216
|
function applyVars(spec, vars) {
|
|
2170
2217
|
if (Object.keys(vars).length === 0) return spec;
|
|
2171
|
-
const
|
|
2218
|
+
const walk3 = (v) => {
|
|
2172
2219
|
if (typeof v === "string") return substitute(v, vars);
|
|
2173
|
-
if (Array.isArray(v)) return v.map(
|
|
2220
|
+
if (Array.isArray(v)) return v.map(walk3);
|
|
2174
2221
|
if (isPlain(v)) {
|
|
2175
2222
|
const o = {};
|
|
2176
|
-
for (const [k, x] of Object.entries(v)) o[k] =
|
|
2223
|
+
for (const [k, x] of Object.entries(v)) o[k] = walk3(x);
|
|
2177
2224
|
return o;
|
|
2178
2225
|
}
|
|
2179
2226
|
return v;
|
|
2180
2227
|
};
|
|
2181
|
-
return
|
|
2228
|
+
return walk3(spec);
|
|
2182
2229
|
}
|
|
2183
2230
|
var escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2184
2231
|
function lintVars(spec, vars) {
|
|
2185
2232
|
const declared = Object.keys(vars);
|
|
2186
2233
|
const strings = [];
|
|
2187
|
-
const
|
|
2234
|
+
const walk3 = (v) => {
|
|
2188
2235
|
if (typeof v === "string") strings.push(v);
|
|
2189
|
-
else if (Array.isArray(v)) v.forEach(
|
|
2190
|
-
else if (isPlain(v)) Object.values(v).forEach(
|
|
2236
|
+
else if (Array.isArray(v)) v.forEach(walk3);
|
|
2237
|
+
else if (isPlain(v)) Object.values(v).forEach(walk3);
|
|
2191
2238
|
};
|
|
2192
|
-
|
|
2239
|
+
walk3(spec);
|
|
2193
2240
|
const out = [];
|
|
2194
2241
|
for (const name of declared) {
|
|
2195
2242
|
const word = new RegExp(`(?<![A-Za-z0-9_.])${escapeRe(name)}(?![A-Za-z0-9_])`);
|
|
@@ -2743,7 +2790,7 @@ var Movie = class {
|
|
|
2743
2790
|
* Build the composition tree for these variables and this size, off stage: `{name}` replaced, the root shape (with the numeric variables for the
|
|
2744
2791
|
* expressions), transitions expanded, every layer built. Used by `init` and by `rebuild`.
|
|
2745
2792
|
*/
|
|
2746
|
-
async _construct(composition, vars, width, height, lp, sizeWins = this._resized) {
|
|
2793
|
+
async _construct(composition, vars, width, height, lp, sizeWins = this._resized, reuse) {
|
|
2747
2794
|
const spec = applyVars(composition, vars);
|
|
2748
2795
|
const gpu = sharedGpuOf(this.app?.renderer);
|
|
2749
2796
|
const gpuField = gpu ? { gpu } : {};
|
|
@@ -2754,6 +2801,7 @@ var Movie = class {
|
|
|
2754
2801
|
frameRate: this.frameRate,
|
|
2755
2802
|
vars: numericVars(vars),
|
|
2756
2803
|
...gpuField,
|
|
2804
|
+
...reuse ? { reuse } : {},
|
|
2757
2805
|
...lp ? { onLayerBuilt: async () => {
|
|
2758
2806
|
lp.tick();
|
|
2759
2807
|
await lp.yieldIfDue();
|
|
@@ -2910,7 +2958,7 @@ var Movie = class {
|
|
|
2910
2958
|
if (change.composition !== void 0) for (const w of lintVars(change.composition, vars)) console.warn(w);
|
|
2911
2959
|
changed = changed || sizeChanged || change.composition !== void 0 || reason === "rebuild";
|
|
2912
2960
|
if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
|
|
2913
|
-
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged);
|
|
2961
|
+
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged, reusePoolOf(this._rootSequence));
|
|
2914
2962
|
alive();
|
|
2915
2963
|
const timeline = chunkX62H3RBG_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2916
2964
|
chunkX62H3RBG_cjs.lengthen(timeline, this.duration);
|
|
@@ -2950,6 +2998,7 @@ var Movie = class {
|
|
|
2950
2998
|
if (old?.target) root.removeChild(old.target);
|
|
2951
2999
|
if (sequence.target) root.addChild(sequence.target);
|
|
2952
3000
|
this._rootSequence = sequence;
|
|
3001
|
+
commitReuse(sequence);
|
|
2953
3002
|
this.timeline = timeline;
|
|
2954
3003
|
this._timeFilters = collectTimeFilters(sequence);
|
|
2955
3004
|
const unmute = muteBoundTextureWarning();
|
|
@@ -3224,7 +3273,8 @@ var Movie = class {
|
|
|
3224
3273
|
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.pick()", opts, ["only", "ignore", "alpha"]);
|
|
3225
3274
|
this._requireReady("pick");
|
|
3226
3275
|
if (!Number.isFinite(x) || !Number.isFinite(y)) throw new Error(`pixi-effects: movie.pick(x, y) needs two numbers (canvas pixels), got ${x}, ${y}. For a pointer event: movie.pick(...movie.canvasPoint(event))`);
|
|
3227
|
-
|
|
3276
|
+
const textureOf = textPictureOf;
|
|
3277
|
+
return pickScene(this._rootSequence, x, y, opts, { textureOf });
|
|
3228
3278
|
}
|
|
3229
3279
|
/**
|
|
3230
3280
|
* Which layer the pointer is over, as callbacks: `onEnter(hit)` when the layer (or, in a `three` layer, the object) under the pointer changes to another, `onLeave(hit)` for the one it
|
|
@@ -4768,5 +4818,5 @@ exports.splitText = splitText;
|
|
|
4768
4818
|
exports.stagger = stagger;
|
|
4769
4819
|
exports.wiggle = wiggle;
|
|
4770
4820
|
exports.withFade = withFade;
|
|
4771
|
-
//# sourceMappingURL=chunk-
|
|
4772
|
-
//# sourceMappingURL=chunk-
|
|
4821
|
+
//# sourceMappingURL=chunk-MAAM45ZX.cjs.map
|
|
4822
|
+
//# sourceMappingURL=chunk-MAAM45ZX.cjs.map
|