pixi-effects 0.44.0 → 0.46.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 +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +117 -2
- package/ai/tools/lookup.mjs +1 -0
- package/dist/Composition-NSY7A32Y.js +7 -0
- package/dist/{Composition-YGBQX3HZ.js.map → Composition-NSY7A32Y.js.map} +1 -1
- package/dist/Composition-PME3P5LP.cjs +16 -0
- package/dist/{Composition-N6BOROJ2.cjs.map → Composition-PME3P5LP.cjs.map} +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/{Movie-B3VOAgwc.d.cts → Movie-BqrAWN0g.d.cts} +13 -1
- package/dist/{Movie-CQCVUqRs.d.ts → Movie-sV8nJr_f.d.ts} +13 -1
- package/dist/{Spans-XTIWYSNO.cjs → Spans-2TZCNREQ.cjs} +9 -9
- package/dist/{Spans-XTIWYSNO.cjs.map → Spans-2TZCNREQ.cjs.map} +1 -1
- package/dist/{Spans-6L2ZVECX.js → Spans-TESJPQKX.js} +4 -4
- package/dist/{Spans-6L2ZVECX.js.map → Spans-TESJPQKX.js.map} +1 -1
- package/dist/{chunk-4MBTYREC.js → chunk-2E74SP63.js} +72 -17
- package/dist/chunk-2E74SP63.js.map +1 -0
- package/dist/{chunk-MAAM45ZX.cjs → chunk-7M63Y6MO.cjs} +114 -59
- package/dist/chunk-7M63Y6MO.cjs.map +1 -0
- package/dist/{chunk-3HZV3UHU.cjs → chunk-DKCMJILW.cjs} +67 -65
- package/dist/chunk-DKCMJILW.cjs.map +1 -0
- package/dist/{chunk-4QVQ5UJJ.js → chunk-DM2OLQOJ.js} +5 -6
- package/dist/chunk-DM2OLQOJ.js.map +1 -0
- package/dist/{chunk-ICI6ACHY.js → chunk-FPV3NPYC.js} +8 -6
- package/dist/chunk-FPV3NPYC.js.map +1 -0
- package/dist/{chunk-UHNSL2KJ.js → chunk-K24FF4BT.js} +10 -5
- package/dist/chunk-K24FF4BT.js.map +1 -0
- package/dist/{chunk-X62H3RBG.cjs → chunk-LALEBV63.cjs} +5 -6
- package/dist/chunk-LALEBV63.cjs.map +1 -0
- package/dist/{chunk-LQDDDIC4.cjs → chunk-O66JGPVV.cjs} +10 -4
- package/dist/chunk-O66JGPVV.cjs.map +1 -0
- package/dist/index.cjs +35 -35
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/loader.css +1 -1
- package/dist/present.cjs +4 -4
- package/dist/present.d.cts +2 -2
- package/dist/present.d.ts +2 -2
- package/dist/present.js +4 -4
- package/dist/sound.cjs +2 -2
- package/dist/sound.js +1 -1
- package/dist/three.cjs +194 -15
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +75 -4
- package/dist/three.d.ts +75 -4
- package/dist/three.js +191 -13
- package/dist/three.js.map +1 -1
- package/dist/{types-C5xo0fzb.d.cts → types-CTSrPvY3.d.cts} +64 -58
- package/dist/{types-C5xo0fzb.d.ts → types-CTSrPvY3.d.ts} +64 -58
- package/docs/api.md +2 -0
- package/docs/dsl.md +26 -0
- package/llms-full.txt +66 -4
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +2 -2
- package/skills/pixi-effects/reference/cheatsheet.md +2 -2
- package/skills/pixi-effects/reference/recipes.md +34 -0
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-N6BOROJ2.cjs +0 -16
- package/dist/Composition-YGBQX3HZ.js +0 -7
- package/dist/chunk-3HZV3UHU.cjs.map +0 -1
- package/dist/chunk-4MBTYREC.js.map +0 -1
- package/dist/chunk-4QVQ5UJJ.js.map +0 -1
- package/dist/chunk-ICI6ACHY.js.map +0 -1
- package/dist/chunk-LQDDDIC4.cjs.map +0 -1
- package/dist/chunk-MAAM45ZX.cjs.map +0 -1
- package/dist/chunk-UHNSL2KJ.js.map +0 -1
- package/dist/chunk-X62H3RBG.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CompositionSequence, maskSourceOf } from './chunk-
|
|
2
|
-
import { EXPRESSION_NAMES, createTimeline, lengthen, ensureFilterLibrary, checkEase, parseEase, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, trimPolylines, rand, DEG, timeRemapOf, contentLength, resolveAt, parseSpring, springDuration, spansMeta } from './chunk-
|
|
3
|
-
import { analyzeAudio, fft, resampleThrough, playSpan } from './chunk-
|
|
1
|
+
import { CompositionSequence, maskSourceOf } from './chunk-FPV3NPYC.js';
|
|
2
|
+
import { EXPRESSION_NAMES, createTimeline, lengthen, ensureFilterLibrary, checkEase, parseEase, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, trimPolylines, rand, DEG, timeRemapOf, contentLength, resolveAt, parseSpring, springDuration, spansMeta } from './chunk-DM2OLQOJ.js';
|
|
3
|
+
import { analyzeAudio, fft, resampleThrough, measureLoudness, playSpan } from './chunk-K24FF4BT.js';
|
|
4
4
|
import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-VNP7QCJE.js';
|
|
5
5
|
import { describeLayer } from './chunk-32MMNDDN.js';
|
|
6
6
|
import { warnUnknownOptions, suggestName } from './chunk-BXOCEZ4U.js';
|
|
@@ -140,6 +140,20 @@ async function mixdown(audios, totalDuration, sampleRate = 44100, pace) {
|
|
|
140
140
|
return await ctx.startRendering();
|
|
141
141
|
}
|
|
142
142
|
var KNEE = 0.9;
|
|
143
|
+
var LOUDNESS_CEILING_DB = -1;
|
|
144
|
+
function normalizeMix(buffer, target) {
|
|
145
|
+
const chans = [];
|
|
146
|
+
for (let ch = 0; ch < buffer.numberOfChannels; ch++) chans.push(buffer.getChannelData(ch));
|
|
147
|
+
const m = measureLoudness(chans, buffer.sampleRate, { truePeak: false });
|
|
148
|
+
if (m.integratedLufs === null) return { target, gainDb: 0, reachedLufs: null, limited: false };
|
|
149
|
+
let gainDb = target - m.integratedLufs;
|
|
150
|
+
const room = LOUDNESS_CEILING_DB - m.samplePeakDb;
|
|
151
|
+
const limited = gainDb > room;
|
|
152
|
+
if (limited) gainDb = room;
|
|
153
|
+
const gain = 10 ** (gainDb / 20);
|
|
154
|
+
for (const d of chans) for (let i = 0; i < d.length; i++) d[i] = d[i] * gain;
|
|
155
|
+
return { target, gainDb: Math.round(gainDb * 10) / 10, reachedLufs: Math.round((m.integratedLufs + gainDb) * 10) / 10, limited };
|
|
156
|
+
}
|
|
143
157
|
function limitMix(buffer, audios) {
|
|
144
158
|
let peak = 0;
|
|
145
159
|
let peakIndex = 0;
|
|
@@ -1618,7 +1632,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1618
1632
|
const name = seq.spec.name;
|
|
1619
1633
|
const label = name ?? `${seq.spec.type}#${i}`;
|
|
1620
1634
|
const alpha = (t?.alpha ?? 1) * carriers.reduce((a, c) => a * (c.target?.alpha ?? 1), 1);
|
|
1621
|
-
const alive = (threeD ? display.visible : t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1635
|
+
const alive = (threeD ? display.visible : (t?.renderable ?? true) && t?.visible !== false) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1622
1636
|
const visible = parentVisible && alive && alpha > 0;
|
|
1623
1637
|
let bounds = null;
|
|
1624
1638
|
if (!insideThreeD) {
|
|
@@ -1798,7 +1812,22 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1798
1812
|
return true;
|
|
1799
1813
|
};
|
|
1800
1814
|
const inside = (b, p) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
|
|
1801
|
-
const
|
|
1815
|
+
const hiddenSources = /* @__PURE__ */ new Map();
|
|
1816
|
+
const forwards = [];
|
|
1817
|
+
const rays = /* @__PURE__ */ new Map();
|
|
1818
|
+
const rayOf = (seq, d, local, lb) => {
|
|
1819
|
+
if (typeof seq.pickAt !== "function") return null;
|
|
1820
|
+
if (!rays.has(seq)) rays.set(seq, seq.pickAt((local.x - lb.x) / lb.width, (local.y - lb.y) / lb.height));
|
|
1821
|
+
return rays.get(seq);
|
|
1822
|
+
};
|
|
1823
|
+
const forwardThrough = (seq, d, path, local, lb) => {
|
|
1824
|
+
const shows = seq.screenOf;
|
|
1825
|
+
if (!shows || !inside(lb, local)) return;
|
|
1826
|
+
const r = rayOf(seq, d, local, lb);
|
|
1827
|
+
const shown = r?.uv ? shows.call(seq, r.material) : null;
|
|
1828
|
+
if (r?.uv && shown) forwards.push({ source: shown.source, uv: r.uv, via: { path, object: String(r.object) }, order: orderOf(d) });
|
|
1829
|
+
};
|
|
1830
|
+
const walk3 = (comp, prefix, parentVisible, at = { x, y }, orderBase, via) => {
|
|
1802
1831
|
comp.layers().forEach(({ seq, display, threeD, carriers, quad }, i) => {
|
|
1803
1832
|
const d = display;
|
|
1804
1833
|
if (!d) return;
|
|
@@ -1806,16 +1835,25 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1806
1835
|
const name = seq.spec.name;
|
|
1807
1836
|
const path = prefix + (name ?? `${seq.spec.type}#${i}`);
|
|
1808
1837
|
const alpha = (t?.alpha ?? 1) * carriers.reduce((a, c) => a * (c.target?.alpha ?? 1), 1);
|
|
1809
|
-
const alive = (threeD ? d.visible : t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1838
|
+
const alive = (threeD ? d.visible : (t?.renderable ?? true) && t?.visible !== false) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1810
1839
|
const visible = parentVisible && alive && alpha > 0;
|
|
1811
|
-
if (!visible)
|
|
1840
|
+
if (!visible) {
|
|
1841
|
+
if (seq instanceof CompositionSequence && !threeD && parentVisible && alpha > 0 && t?.visible === false && (t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true)) hiddenSources.set(seq, path);
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1812
1844
|
const isComposition = seq instanceof CompositionSequence;
|
|
1813
1845
|
if (isComposition && !threeD) {
|
|
1814
|
-
walk3(seq, path + "/", visible);
|
|
1846
|
+
walk3(seq, path + "/", visible, at, orderBase, via);
|
|
1815
1847
|
return;
|
|
1816
1848
|
}
|
|
1817
|
-
if (!wanted(name, path))
|
|
1818
|
-
|
|
1849
|
+
if (!wanted(name, path)) {
|
|
1850
|
+
if (!threeD) {
|
|
1851
|
+
const lp = d.toLocal(at);
|
|
1852
|
+
forwardThrough(seq, d, path, lp, d.getLocalBounds());
|
|
1853
|
+
}
|
|
1854
|
+
return;
|
|
1855
|
+
}
|
|
1856
|
+
const point = at;
|
|
1819
1857
|
let hit = null;
|
|
1820
1858
|
if (threeD) {
|
|
1821
1859
|
if (quad && pointInQuad(quad, d.toLocal(point).x, d.toLocal(point).y)) hit = { name, path, type: seq.spec.type, kind: "card", point };
|
|
@@ -1823,7 +1861,10 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1823
1861
|
const local = d.toLocal(point);
|
|
1824
1862
|
const lb = d.getLocalBounds();
|
|
1825
1863
|
if (inside(lb, local)) {
|
|
1826
|
-
const
|
|
1864
|
+
const isThree = typeof seq.pickAt === "function";
|
|
1865
|
+
const ray = isThree ? rayOf(seq, d, local, lb) : void 0;
|
|
1866
|
+
if (isThree) forwardThrough(seq, d, path, local, lb);
|
|
1867
|
+
const three = ray ? { object: ray.object, point: ray.point, distance: ray.distance, object3d: ray.object3d } : isThree ? null : void 0;
|
|
1827
1868
|
if (three) {
|
|
1828
1869
|
const planeOf = seq.dragPlane;
|
|
1829
1870
|
if (planeOf) {
|
|
@@ -1858,10 +1899,16 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1858
1899
|
const maskTarget = seq.maskSequence?.target;
|
|
1859
1900
|
const maskSrc = maskSourceOf(seq.spec.mask);
|
|
1860
1901
|
if (maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert) && !inside(maskTarget.getBounds(), point)) return;
|
|
1861
|
-
found.push({ hit, order: orderOf(d) });
|
|
1902
|
+
found.push({ hit: via ? { ...hit, point: { x, y }, via } : hit, order: orderBase ? [...orderBase, ...orderOf(d)] : orderOf(d) });
|
|
1862
1903
|
});
|
|
1863
1904
|
};
|
|
1864
1905
|
walk3(root, "", true);
|
|
1906
|
+
for (const f of forwards) {
|
|
1907
|
+
const path = hiddenSources.get(f.source);
|
|
1908
|
+
if (path === void 0) continue;
|
|
1909
|
+
const g = f.source.target.toGlobal({ x: f.uv.u * f.source.intrinsicWidth, y: (1 - f.uv.v) * f.source.intrinsicHeight });
|
|
1910
|
+
walk3(f.source, path + "/", true, g, f.order, f.via);
|
|
1911
|
+
}
|
|
1865
1912
|
return found.sort((a, b) => above(a.order, b.order)).map((f) => f.hit);
|
|
1866
1913
|
}
|
|
1867
1914
|
var cache = /* @__PURE__ */ new WeakMap();
|
|
@@ -2617,6 +2664,7 @@ var Movie = class {
|
|
|
2617
2664
|
/** What went into the mix, and its peak before limiting — kept for inspectAudio(). */
|
|
2618
2665
|
_audioSources = [];
|
|
2619
2666
|
_mixStats = null;
|
|
2667
|
+
_loudness = null;
|
|
2620
2668
|
on(event, fn) {
|
|
2621
2669
|
(this._events[event] ??= []).push(fn);
|
|
2622
2670
|
if (event === "ready" && this._initState === "ready") {
|
|
@@ -2691,7 +2739,11 @@ var Movie = class {
|
|
|
2691
2739
|
return this._audioContext;
|
|
2692
2740
|
}
|
|
2693
2741
|
async init(options = {}) {
|
|
2694
|
-
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition", "vars", "poster", "motionBlur", "loader", "loop"]);
|
|
2742
|
+
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition", "vars", "poster", "motionBlur", "loader", "loop", "loudness"]);
|
|
2743
|
+
if (options.loudness !== void 0 && options.loudness !== false && !(typeof options.loudness === "number" && Number.isFinite(options.loudness) && options.loudness <= 0 && options.loudness >= -70)) {
|
|
2744
|
+
throw new Error(`pixi-effects: movie.init({ loudness }) is the loudness of the whole mix in LUFS: a number from -70 to 0 (-16 is usual for web video: loudness: -16), or false for no change; got ${JSON.stringify(options.loudness)}`);
|
|
2745
|
+
}
|
|
2746
|
+
this._loudness = options.loudness === void 0 || options.loudness === false ? null : options.loudness;
|
|
2695
2747
|
this._initState = "pending";
|
|
2696
2748
|
try {
|
|
2697
2749
|
this.width = options.width ?? 1920;
|
|
@@ -2799,6 +2851,7 @@ var Movie = class {
|
|
|
2799
2851
|
frameRate: this.frameRate,
|
|
2800
2852
|
vars: numericVars(vars),
|
|
2801
2853
|
...gpuField,
|
|
2854
|
+
...this.app?.renderer ? { pixiRenderer: this.app.renderer } : {},
|
|
2802
2855
|
...reuse ? { reuse } : {},
|
|
2803
2856
|
...lp ? { onLayerBuilt: async () => {
|
|
2804
2857
|
lp.tick();
|
|
@@ -2842,7 +2895,8 @@ var Movie = class {
|
|
|
2842
2895
|
this._mixStats = null;
|
|
2843
2896
|
this._mixCache.set(null, null);
|
|
2844
2897
|
} else {
|
|
2845
|
-
const
|
|
2898
|
+
const baseKey = mixKey(audios, this.duration, audioContext.sampleRate);
|
|
2899
|
+
const key = baseKey === null ? null : `${baseKey}|loudness:${this._loudness}`;
|
|
2846
2900
|
const hit = this._mixCache.get(key);
|
|
2847
2901
|
if (hit) {
|
|
2848
2902
|
this.audioBuffer = hit.buffer;
|
|
@@ -2853,7 +2907,8 @@ var Movie = class {
|
|
|
2853
2907
|
lp.part(done);
|
|
2854
2908
|
await lp.yieldIfDue();
|
|
2855
2909
|
} : void 0);
|
|
2856
|
-
|
|
2910
|
+
const loudness = this.audioBuffer && this._loudness !== null ? normalizeMix(this.audioBuffer, this._loudness) : void 0;
|
|
2911
|
+
this._mixStats = this.audioBuffer ? { ...limitMix(this.audioBuffer, audios), ...loudness ? { loudness } : {} } : null;
|
|
2857
2912
|
this._mixCache.set(key, this.audioBuffer, this._mixStats);
|
|
2858
2913
|
status = "mixed";
|
|
2859
2914
|
}
|
|
@@ -4793,5 +4848,5 @@ function withFade(spec, opts) {
|
|
|
4793
4848
|
}
|
|
4794
4849
|
|
|
4795
4850
|
export { Movie, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, dismissLoader, failLoader, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, orbit, parseEase2 as parseEase, particles, react, resolveLoader, samplePath, splitText, stagger, wiggle, withFade };
|
|
4796
|
-
//# sourceMappingURL=chunk-
|
|
4797
|
-
//# sourceMappingURL=chunk-
|
|
4851
|
+
//# sourceMappingURL=chunk-2E74SP63.js.map
|
|
4852
|
+
//# sourceMappingURL=chunk-2E74SP63.js.map
|