pixi-effects 0.47.4 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +8 -6
- package/ai/chat-template.html +3 -3
- package/dist/Composition-PMWLJQPI.cjs +16 -0
- package/dist/{Composition-ZYRDRLYB.cjs.map → Composition-PMWLJQPI.cjs.map} +1 -1
- package/dist/Composition-ZCRJHBB5.js +7 -0
- package/dist/{Composition-HTHQ2RLF.js.map → Composition-ZCRJHBB5.js.map} +1 -1
- package/dist/Controller.cjs +3 -0
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +1 -1
- package/dist/Controller.d.ts +1 -1
- package/dist/Controller.js +3 -0
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-sV8nJr_f.d.ts → Movie--qSYKgAQ.d.ts} +2 -2
- package/dist/{Movie-BqrAWN0g.d.cts → Movie-svZQF-9Z.d.cts} +2 -2
- package/dist/{Spans-JYCTJV4V.js → Spans-FMAVPATS.js} +4 -4
- package/dist/{Spans-JYCTJV4V.js.map → Spans-FMAVPATS.js.map} +1 -1
- package/dist/{Spans-I7P7ZVZO.cjs → Spans-KTUPDFSR.cjs} +9 -9
- package/dist/{Spans-I7P7ZVZO.cjs.map → Spans-KTUPDFSR.cjs.map} +1 -1
- package/dist/{chunk-34YNRCMT.js → chunk-4PYVHLIK.js} +20 -5
- package/dist/chunk-4PYVHLIK.js.map +1 -0
- package/dist/{chunk-CJS2S5XU.cjs → chunk-ECLBZV4N.cjs} +20 -5
- package/dist/chunk-ECLBZV4N.cjs.map +1 -0
- package/dist/{chunk-NCM2WU7R.js → chunk-GX2WQV4A.js} +58 -35
- package/dist/chunk-GX2WQV4A.js.map +1 -0
- package/dist/chunk-K3XOEC3C.js +53 -0
- package/dist/chunk-K3XOEC3C.js.map +1 -0
- package/dist/{chunk-AES2L75M.cjs → chunk-NGK4E536.cjs} +103 -80
- package/dist/chunk-NGK4E536.cjs.map +1 -0
- package/dist/{chunk-DS2EWRV4.cjs → chunk-OGLRSR6C.cjs} +63 -63
- package/dist/{chunk-DS2EWRV4.cjs.map → chunk-OGLRSR6C.cjs.map} +1 -1
- package/dist/{chunk-RTZ5MW3E.js → chunk-UI7CEUTP.js} +3 -3
- package/dist/{chunk-RTZ5MW3E.js.map → chunk-UI7CEUTP.js.map} +1 -1
- package/dist/chunk-VQXZ2NOI.cjs +56 -0
- package/dist/chunk-VQXZ2NOI.cjs.map +1 -0
- package/dist/index.cjs +38 -33
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +4 -3
- package/dist/loader.css +1 -1
- package/dist/present.cjs +4 -3
- package/dist/present.cjs.map +1 -1
- package/dist/present.d.cts +1 -1
- package/dist/present.d.ts +1 -1
- package/dist/present.js +4 -3
- package/dist/present.js.map +1 -1
- package/dist/three.cjs +5 -5
- package/dist/three.js +1 -1
- package/docs/api.md +17 -2
- package/docs/dsl.md +7 -7
- package/llms-full.txt +26 -11
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +1 -1
- package/skills/pixi-effects/reference/pitfalls.md +1 -1
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-HTHQ2RLF.js +0 -7
- package/dist/Composition-ZYRDRLYB.cjs +0 -16
- package/dist/chunk-34YNRCMT.js.map +0 -1
- package/dist/chunk-AES2L75M.cjs.map +0 -1
- package/dist/chunk-CJS2S5XU.cjs.map +0 -1
- package/dist/chunk-NCM2WU7R.js.map +0 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/core/mediabunny.ts
|
|
2
|
+
var source = null;
|
|
3
|
+
var pending = null;
|
|
4
|
+
function useMediabunny(from) {
|
|
5
|
+
if (from == null || typeof from !== "string" && typeof from !== "function" && typeof from !== "object") {
|
|
6
|
+
throw new TypeError(`pixi-effects: useMediabunny() takes the mediabunny module, a URL or a function that returns the module; it got ${String(from)}`);
|
|
7
|
+
}
|
|
8
|
+
source = from;
|
|
9
|
+
pending = null;
|
|
10
|
+
}
|
|
11
|
+
function loadMediabunny() {
|
|
12
|
+
if (!pending) {
|
|
13
|
+
const from = source;
|
|
14
|
+
const p = fetchModule(from).then(
|
|
15
|
+
(mod) => {
|
|
16
|
+
if (!mod || typeof mod.Output !== "function") {
|
|
17
|
+
throw new Error(`pixi-effects: ${describe(from)} did not give the mediabunny module (no Output in it). ${HOW}`);
|
|
18
|
+
}
|
|
19
|
+
return mod;
|
|
20
|
+
},
|
|
21
|
+
(err) => {
|
|
22
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
23
|
+
throw new Error(`pixi-effects: could not load mediabunny from ${describe(from)} (${why}). ${HOW}`, { cause: err });
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
pending = p;
|
|
27
|
+
p.catch(() => {
|
|
28
|
+
if (pending === p) pending = null;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return pending;
|
|
32
|
+
}
|
|
33
|
+
var HOW = 'mediabunny is needed to export (movie.render(), the download button) and for a video layer; playing needs nothing. Add it to the import map ("mediabunny": "https://cdn.jsdelivr.net/npm/mediabunny@1/+esm"), install it next to pixi-effects, or call useMediabunny(module | url | () => import(...)) before you export.';
|
|
34
|
+
function fetchModule(from) {
|
|
35
|
+
if (from === null) return import('mediabunny');
|
|
36
|
+
if (typeof from === "string") return import(
|
|
37
|
+
/* @vite-ignore */
|
|
38
|
+
/* webpackIgnore: true */
|
|
39
|
+
from
|
|
40
|
+
);
|
|
41
|
+
if (typeof from === "function") return Promise.resolve().then(from);
|
|
42
|
+
return Promise.resolve(from);
|
|
43
|
+
}
|
|
44
|
+
function describe(from) {
|
|
45
|
+
if (from === null) return "'mediabunny' (the bare name: an import map or a bundler resolves it)";
|
|
46
|
+
if (typeof from === "string") return from;
|
|
47
|
+
if (typeof from === "function") return "the function given to useMediabunny()";
|
|
48
|
+
return "the object given to useMediabunny()";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { loadMediabunny, useMediabunny };
|
|
52
|
+
//# sourceMappingURL=chunk-K3XOEC3C.js.map
|
|
53
|
+
//# sourceMappingURL=chunk-K3XOEC3C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/mediabunny.ts"],"names":[],"mappings":";AAeA,IAAI,MAAA,GAAkC,IAAA;AACtC,IAAI,OAAA,GAA4C,IAAA;AAOzC,SAAS,cAAc,IAAA,EAA8B;AAC1D,EAAA,IAAI,IAAA,IAAQ,IAAA,IAAS,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,IAAA,KAAS,UAAA,IAAc,OAAO,IAAA,KAAS,QAAA,EAAW;AACxG,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,+GAAA,EAAkH,MAAA,CAAO,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACtJ;AACA,EAAA,MAAA,GAAS,IAAA;AACT,EAAA,OAAA,GAAU,IAAA;AACZ;AAGO,SAAS,cAAA,GAA4C;AAC1D,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAA,GAAO,MAAA;AACb,IAAA,MAAM,CAAA,GAAI,WAAA,CAAY,IAAI,CAAA,CAAE,IAAA;AAAA,MAC1B,CAAC,GAAA,KAAQ;AACP,QAAA,IAAI,CAAC,GAAA,IAAO,OAAQ,GAAA,CAA6B,WAAW,UAAA,EAAY;AACtE,UAAA,MAAM,IAAI,MAAM,CAAA,cAAA,EAAiB,QAAA,CAAS,IAAI,CAAC,CAAA,uDAAA,EAA0D,GAAG,CAAA,CAAE,CAAA;AAAA,QAChH;AACA,QAAA,OAAO,GAAA;AAAA,MACT,CAAA;AAAA,MACA,CAAC,GAAA,KAAiB;AAChB,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgD,QAAA,CAAS,IAAI,CAAC,CAAA,EAAA,EAAK,GAAG,CAAA,GAAA,EAAM,GAAG,CAAA,CAAA,EAAI,EAAE,KAAA,EAAO,KAAK,CAAA;AAAA,MACnH;AAAA,KACF;AACA,IAAA,OAAA,GAAU,CAAA;AACV,IAAA,CAAA,CAAE,MAAM,MAAM;AAAE,MAAA,IAAI,OAAA,KAAY,GAAG,OAAA,GAAU,IAAA;AAAA,IAAM,CAAC,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,OAAA;AACT;AAEA,IAAM,GAAA,GAAM,2TAAA;AAIZ,SAAS,YAAY,IAAA,EAA0D;AAC7E,EAAA,IAAI,IAAA,KAAS,IAAA,EAAM,OAAO,OAAO,YAAY,CAAA;AAC7C,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO;AAAA;AAAA;AAAA,IAAoD;AAAA,GAAA;AACzF,EAAA,IAAI,OAAO,SAAS,UAAA,EAAY,OAAO,QAAQ,OAAA,EAAQ,CAAE,KAAK,IAAI,CAAA;AAClE,EAAA,OAAO,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAC7B;AAEA,SAAS,SAAS,IAAA,EAAuC;AACvD,EAAA,IAAI,IAAA,KAAS,MAAM,OAAO,sEAAA;AAC1B,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,OAAO,IAAA,KAAS,UAAA,EAAY,OAAO,uCAAA;AACvC,EAAA,OAAO,qCAAA;AACT","file":"chunk-K3XOEC3C.js","sourcesContent":["// mediabunny (about 180 KB gzipped) is what writes a video file and decodes a `video` layer. A page that only plays never needs it, so it is\n// fetched the first time something asks for it: `movie.render()`, a video asset. Nothing imports it at the top of a module.\nimport type * as Mediabunny from 'mediabunny';\n\n/** The mediabunny module, as `import * as mb from 'mediabunny'` gives it. */\nexport type MediabunnyModule = typeof Mediabunny;\n\n/**\n * Where mediabunny comes from, for {@link useMediabunny}:\n * - the module itself (`import * as mb from 'mediabunny'`: it is ready, nothing is fetched),\n * - a URL to `import()` (a page with no import map entry for it),\n * - a function that returns the module (`() => import('mediabunny')`, your own copy, a bundler chunk).\n */\nexport type MediabunnySource = MediabunnyModule | string | (() => Promise<MediabunnyModule>);\n\nlet source: MediabunnySource | null = null;\nlet pending: Promise<MediabunnyModule> | null = null;\n\n/**\n * Says where mediabunny comes from. Without it, the bare name `'mediabunny'` is imported the first time it is needed, which your bundler or the\n * page's import map resolves. A page that only plays (no export, no `video` layer) needs neither this nor an import map entry for it.\n * Calling it again replaces the source for the next load; a module that was already loaded stays in use by what holds it.\n */\nexport function useMediabunny(from: MediabunnySource): void {\n if (from == null || (typeof from !== 'string' && typeof from !== 'function' && typeof from !== 'object')) {\n throw new TypeError(`pixi-effects: useMediabunny() takes the mediabunny module, a URL or a function that returns the module; it got ${String(from)}`);\n }\n source = from;\n pending = null;\n}\n\n/** The mediabunny module, fetched once (the first call starts it; later calls share it). A failed load is tried again on the next call. */\nexport function loadMediabunny(): Promise<MediabunnyModule> {\n if (!pending) {\n const from = source;\n const p = fetchModule(from).then(\n (mod) => {\n if (!mod || typeof (mod as { Output?: unknown }).Output !== 'function') {\n throw new Error(`pixi-effects: ${describe(from)} did not give the mediabunny module (no Output in it). ${HOW}`);\n }\n return mod;\n },\n (err: unknown) => {\n const why = err instanceof Error ? err.message : String(err);\n throw new Error(`pixi-effects: could not load mediabunny from ${describe(from)} (${why}). ${HOW}`, { cause: err });\n },\n );\n pending = p;\n p.catch(() => { if (pending === p) pending = null; }); // the next call tries again (a network blip, an import map added later)\n }\n return pending;\n}\n\nconst HOW = 'mediabunny is needed to export (movie.render(), the download button) and for a video layer; playing needs nothing. '\n + 'Add it to the import map (\"mediabunny\": \"https://cdn.jsdelivr.net/npm/mediabunny@1/+esm\"), install it next to pixi-effects, '\n + 'or call useMediabunny(module | url | () => import(...)) before you export.';\n\nfunction fetchModule(from: MediabunnySource | null): Promise<MediabunnyModule> {\n if (from === null) return import('mediabunny');\n if (typeof from === 'string') return import(/* @vite-ignore */ /* webpackIgnore: true */ from) as Promise<MediabunnyModule>;\n if (typeof from === 'function') return Promise.resolve().then(from);\n return Promise.resolve(from);\n}\n\nfunction describe(from: MediabunnySource | null): string {\n if (from === null) return \"'mediabunny' (the bare name: an import map or a bundler resolves it)\";\n if (typeof from === 'string') return from;\n if (typeof from === 'function') return 'the function given to useMediabunny()';\n return 'the object given to useMediabunny()';\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkOGLRSR6C_cjs = require('./chunk-OGLRSR6C.cjs');
|
|
4
|
+
var chunkVQXZ2NOI_cjs = require('./chunk-VQXZ2NOI.cjs');
|
|
5
|
+
var chunkECLBZV4N_cjs = require('./chunk-ECLBZV4N.cjs');
|
|
5
6
|
var chunkZAHCGFGC_cjs = require('./chunk-ZAHCGFGC.cjs');
|
|
6
7
|
var chunkWYR2AU4W_cjs = require('./chunk-WYR2AU4W.cjs');
|
|
7
8
|
var chunkNGJXVJB7_cjs = require('./chunk-NGJXVJB7.cjs');
|
|
8
9
|
var chunkDOLTCXCL_cjs = require('./chunk-DOLTCXCL.cjs');
|
|
9
10
|
var pixi_js = require('pixi.js');
|
|
10
|
-
var mediabunny = require('mediabunny');
|
|
11
11
|
|
|
12
12
|
// src/core/gpuShare.ts
|
|
13
13
|
function sharedGpuOf(renderer) {
|
|
@@ -43,8 +43,9 @@ function ensureLoadersRegistered(audioContext) {
|
|
|
43
43
|
extension: { type: pixi_js.ExtensionType.LoadParser, name: "pixi-effects-video", priority: 1 },
|
|
44
44
|
test: (url) => /\.(mp4|webm|mov|mkv)$/i.test(url),
|
|
45
45
|
async load(url) {
|
|
46
|
-
const blob = await fetch(url).then((r) => r.blob());
|
|
47
|
-
const
|
|
46
|
+
const [M, blob] = await Promise.all([chunkVQXZ2NOI_cjs.loadMediabunny(), fetch(url).then((r) => r.blob())]);
|
|
47
|
+
const { Input, BlobSource, ALL_FORMATS, Output, WavOutputFormat, BufferTarget, Conversion, VideoSampleSink } = M;
|
|
48
|
+
const input = new Input({ source: new BlobSource(blob), formats: ALL_FORMATS });
|
|
48
49
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
49
50
|
if (!videoTrack || !await videoTrack.canDecode()) {
|
|
50
51
|
throw new Error("pixi-effects: video track cannot be decoded");
|
|
@@ -55,8 +56,8 @@ function ensureLoadersRegistered(audioContext) {
|
|
|
55
56
|
let audioBuffer = null;
|
|
56
57
|
if (audioTrack) {
|
|
57
58
|
try {
|
|
58
|
-
const out = new
|
|
59
|
-
const conv = await
|
|
59
|
+
const out = new Output({ format: new WavOutputFormat(), target: new BufferTarget() });
|
|
60
|
+
const conv = await Conversion.init({ input, output: out, video: { discard: true } });
|
|
60
61
|
await conv.execute();
|
|
61
62
|
audioBuffer = await audioContext.decodeAudioData(out.target.buffer);
|
|
62
63
|
} catch (e) {
|
|
@@ -69,7 +70,7 @@ function ensureLoadersRegistered(audioContext) {
|
|
|
69
70
|
videoDuration,
|
|
70
71
|
audioDuration,
|
|
71
72
|
duration: Math.max(videoDuration, audioDuration),
|
|
72
|
-
sink: new
|
|
73
|
+
sink: new VideoSampleSink(videoTrack)
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
76
|
});
|
|
@@ -250,6 +251,19 @@ async function normalizeMix(buffer, target, between) {
|
|
|
250
251
|
gainDb = next;
|
|
251
252
|
}
|
|
252
253
|
}
|
|
254
|
+
if (original && final.integratedLufs !== null && m.integratedLufs !== null) {
|
|
255
|
+
const plainDb = Math.min(target - m.integratedLufs, LOUDNESS_CEILING_DB - m.samplePeakDb);
|
|
256
|
+
if (final.integratedLufs < m.integratedLufs + plainDb - 0.1) {
|
|
257
|
+
const k = 10 ** (plainDb / 20);
|
|
258
|
+
for (let ch = 0; ch < chans.length; ch++) {
|
|
259
|
+
const o = original[ch], d = chans[ch];
|
|
260
|
+
for (let i = 0; i < d.length; i++) d[i] = o[i] * k;
|
|
261
|
+
}
|
|
262
|
+
gainDb = plainDb;
|
|
263
|
+
applied = { reductionDb: 0, at: 0 };
|
|
264
|
+
final = chunkZAHCGFGC_cjs.measureLoudness(chans, sr);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
253
267
|
let trimDb = 0;
|
|
254
268
|
if (final.truePeakDb > LOUDNESS_CEILING_DB) {
|
|
255
269
|
trimDb = final.truePeakDb - LOUDNESS_CEILING_DB + 0.01;
|
|
@@ -587,10 +601,10 @@ var AUDIO_PREFERENCE = {
|
|
|
587
601
|
mkv: ["opus", "vorbis", "aac", "flac", "mp3"],
|
|
588
602
|
ogg: ["opus", "vorbis", "flac"]
|
|
589
603
|
};
|
|
590
|
-
async function chooseAudioCodec(fmt, requested, container, audio, bitrate) {
|
|
604
|
+
async function chooseAudioCodec(M, fmt, requested, container, audio, bitrate) {
|
|
591
605
|
const supported = container.getSupportedAudioCodecs?.();
|
|
592
606
|
const preferred = AUDIO_PREFERENCE[fmt].filter((c) => !supported || supported.includes(c));
|
|
593
|
-
const canEncode = (list) =>
|
|
607
|
+
const canEncode = (list) => M.getFirstEncodableAudioCodec(list, { numberOfChannels: audio.numberOfChannels ?? 2, sampleRate: audio.sampleRate, bitrate });
|
|
594
608
|
if (requested) {
|
|
595
609
|
if (await canEncode([requested])) return requested;
|
|
596
610
|
const alt = await canEncode(preferred.filter((c) => c !== requested));
|
|
@@ -603,27 +617,34 @@ async function chooseAudioCodec(fmt, requested, container, audio, bitrate) {
|
|
|
603
617
|
}
|
|
604
618
|
return chosen;
|
|
605
619
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
620
|
+
function qualityOf(M, name) {
|
|
621
|
+
switch (name) {
|
|
622
|
+
case "very-low":
|
|
623
|
+
return M.QUALITY_VERY_LOW;
|
|
624
|
+
case "low":
|
|
625
|
+
return M.QUALITY_LOW;
|
|
626
|
+
case "medium":
|
|
627
|
+
return M.QUALITY_MEDIUM;
|
|
628
|
+
case "very-high":
|
|
629
|
+
return M.QUALITY_VERY_HIGH;
|
|
630
|
+
default:
|
|
631
|
+
return M.QUALITY_HIGH;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
function bitrateOf(M, v) {
|
|
614
635
|
const b = parseBitrate(v);
|
|
615
|
-
return b.bps ?? (
|
|
636
|
+
return b.bps ?? qualityOf(M, b.quality ?? "high");
|
|
616
637
|
}
|
|
617
|
-
function makeOutputFormat(name) {
|
|
638
|
+
function makeOutputFormat(M, name) {
|
|
618
639
|
switch (name) {
|
|
619
640
|
case "mp4":
|
|
620
|
-
return new
|
|
641
|
+
return new M.Mp4OutputFormat({ fastStart: "in-memory" });
|
|
621
642
|
case "mov":
|
|
622
|
-
return new
|
|
643
|
+
return new M.MovOutputFormat({ fastStart: "in-memory" });
|
|
623
644
|
case "webm":
|
|
624
|
-
return new
|
|
645
|
+
return new M.WebMOutputFormat();
|
|
625
646
|
case "mkv":
|
|
626
|
-
return new
|
|
647
|
+
return new M.MkvOutputFormat();
|
|
627
648
|
}
|
|
628
649
|
}
|
|
629
650
|
function sliceAudio(buffer, fromSec, toSec, fadeIn, fadeOut) {
|
|
@@ -638,18 +659,19 @@ async function exportAudioOnly(movie, options, fmt, range2) {
|
|
|
638
659
|
throw new Error(`pixi-effects: render({ format: '${fmt}' }): this movie has no sound to export (add an audio layer, an sfx or a music score); for the picture use mp4, webm, mov or mkv`);
|
|
639
660
|
}
|
|
640
661
|
if (options.video) console.warn(`pixi-effects: render({ format: '${fmt}' }): video options are ignored, only the sound is written`);
|
|
662
|
+
const M = await chunkVQXZ2NOI_cjs.loadMediabunny();
|
|
641
663
|
const audio = range2.partial ? sliceAudio(movie.audioBuffer, range2.fromSec, range2.toSec, range2.fromFrame > 0, range2.toFrame < movie.totalFrames) : movie.audioBuffer;
|
|
642
|
-
const container = fmt === "wav" ? new
|
|
664
|
+
const container = fmt === "wav" ? new M.WavOutputFormat() : new M.OggOutputFormat();
|
|
643
665
|
let codec;
|
|
644
666
|
if (fmt === "wav") {
|
|
645
667
|
codec = options.audio?.codec ?? "pcm-s16";
|
|
646
668
|
const held = container.getSupportedAudioCodecs();
|
|
647
669
|
if (!held.includes(codec)) throw new Error(`pixi-effects: render({ format: 'wav', audio: { codec: "${codec}" } }): wav holds ${held.join(", ")} (the usual is pcm-s16)`);
|
|
648
670
|
} else {
|
|
649
|
-
codec = await chooseAudioCodec("ogg", options.audio?.codec, container, audio, bitrateOf(options.audio?.bitrate
|
|
671
|
+
codec = await chooseAudioCodec(M, "ogg", options.audio?.codec, container, audio, bitrateOf(M, options.audio?.bitrate));
|
|
650
672
|
}
|
|
651
|
-
const output = new
|
|
652
|
-
const source = new
|
|
673
|
+
const output = new M.Output({ format: container, target: new M.BufferTarget() });
|
|
674
|
+
const source = new M.AudioBufferSource({ codec, ...fmt === "wav" ? {} : { bitrate: bitrateOf(M, options.audio?.bitrate) } });
|
|
653
675
|
output.addAudioTrack(source);
|
|
654
676
|
movie.emit("progress", { progress: 0, frame: range2.fromFrame, totalFrames: movie.totalFrames });
|
|
655
677
|
await output.start();
|
|
@@ -667,21 +689,22 @@ async function exportFrames(movie, options = {}) {
|
|
|
667
689
|
if (!["mp4", "mov", "webm", "mkv"].includes(fmt)) throw new Error(`pixi-effects: render({ format: "${String(fmt)}" }): use mp4, mov, webm, mkv (a picture) or wav, ogg (only the sound)`);
|
|
668
690
|
chunkDOLTCXCL_cjs.warnUnknownOptions("movie.render({ video })", options.video, ["codec", "bitrate", "hardware", "keyFrameInterval"]);
|
|
669
691
|
chunkDOLTCXCL_cjs.warnUnknownOptions("movie.render({ audio })", options.audio, ["codec", "bitrate"]);
|
|
670
|
-
const
|
|
692
|
+
const M = await chunkVQXZ2NOI_cjs.loadMediabunny();
|
|
693
|
+
const videoBitrate = bitrateOf(M, eff.bitrate ?? "high");
|
|
671
694
|
const opts = {
|
|
672
695
|
format: fmt,
|
|
673
696
|
video: { codec: "", bitrate: videoBitrate },
|
|
674
697
|
audio: {
|
|
675
698
|
codec: options.audio?.codec ?? (fmt === "mp4" || fmt === "mov" ? "aac" : "opus"),
|
|
676
|
-
bitrate: bitrateOf(options.audio?.bitrate
|
|
699
|
+
bitrate: bitrateOf(M, options.audio?.bitrate)
|
|
677
700
|
}
|
|
678
701
|
};
|
|
679
|
-
const container = makeOutputFormat(opts.format);
|
|
702
|
+
const container = makeOutputFormat(M, opts.format);
|
|
680
703
|
const audio = movie.audioBuffer && range2.partial ? sliceAudio(movie.audioBuffer, range2.fromSec, range2.toSec, range2.fromFrame > 0, range2.toFrame < movie.totalFrames) : movie.audioBuffer;
|
|
681
|
-
if (audio) opts.audio.codec = await chooseAudioCodec(fmt, options.audio?.codec, container, audio, opts.audio.bitrate);
|
|
682
|
-
const output = new
|
|
704
|
+
if (audio) opts.audio.codec = await chooseAudioCodec(M, fmt, options.audio?.codec, container, audio, opts.audio.bitrate);
|
|
705
|
+
const output = new M.Output({
|
|
683
706
|
format: container,
|
|
684
|
-
target: new
|
|
707
|
+
target: new M.BufferTarget()
|
|
685
708
|
});
|
|
686
709
|
const mb = eff.motionBlur !== void 0 ? resolveMotionBlur(eff.motionBlur, "movie.render()") : movie.motionBlur ?? null;
|
|
687
710
|
const stage = movie.app.canvas;
|
|
@@ -693,7 +716,7 @@ async function exportFrames(movie, options = {}) {
|
|
|
693
716
|
fmt,
|
|
694
717
|
requested: options.video?.codec,
|
|
695
718
|
supported: container.getSupportedVideoCodecs(),
|
|
696
|
-
canEncode: (c) =>
|
|
719
|
+
canEncode: (c) => M.canEncodeVideo(c, { width: picture.width, height: picture.height, bitrate: opts.video.bitrate })
|
|
697
720
|
});
|
|
698
721
|
if (chosen.fellBackFrom) console.warn(`pixi-effects: this browser cannot encode ${chosen.fellBackFrom.toUpperCase()} video, so the ${fmt} carries ${chosen.codec.toUpperCase()} instead (name a codec with render({ video: { codec } }) to choose yourself).`);
|
|
699
722
|
opts.video.codec = chosen.codec;
|
|
@@ -701,14 +724,14 @@ async function exportFrames(movie, options = {}) {
|
|
|
701
724
|
if (hardware !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(hardware)) {
|
|
702
725
|
throw new Error(`pixi-effects: render({ video: { hardware: "${String(hardware)}" } }): use 'prefer-hardware', 'prefer-software' or 'no-preference'`);
|
|
703
726
|
}
|
|
704
|
-
const canvasSource = new
|
|
727
|
+
const canvasSource = new M.CanvasSource(picture, {
|
|
705
728
|
codec: opts.video.codec,
|
|
706
729
|
bitrate: opts.video.bitrate,
|
|
707
730
|
...hardware ? { hardwareAcceleration: hardware } : {}
|
|
708
731
|
});
|
|
709
732
|
output.addVideoTrack(canvasSource, { frameRate: movie.frameRate });
|
|
710
733
|
if (audio) {
|
|
711
|
-
const audioSource = new
|
|
734
|
+
const audioSource = new M.AudioBufferSource({
|
|
712
735
|
codec: opts.audio.codec,
|
|
713
736
|
bitrate: opts.audio.bitrate
|
|
714
737
|
}, { startTimestamp: opts.audio.codec === "aac" ? -2112 / audio.sampleRate : 0 });
|
|
@@ -1245,8 +1268,8 @@ function expandTransitions(spec) {
|
|
|
1245
1268
|
}
|
|
1246
1269
|
const transitions = out.transitions;
|
|
1247
1270
|
const sequences = out.sequences ?? [];
|
|
1248
|
-
const remap = out.duration !== void 0 ?
|
|
1249
|
-
const parentDuration = remap ?
|
|
1271
|
+
const remap = out.duration !== void 0 ? chunkECLBZV4N_cjs.timeRemapOf(out) : null;
|
|
1272
|
+
const parentDuration = remap ? chunkECLBZV4N_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
|
|
1250
1273
|
const compW = out.width;
|
|
1251
1274
|
const compH = out.height;
|
|
1252
1275
|
const threeDByName = new Set(sequences.filter((s) => s.name && s.threeD).map((s) => s.name));
|
|
@@ -1314,16 +1337,16 @@ function expandTransitions(spec) {
|
|
|
1314
1337
|
if (toUses > 1) {
|
|
1315
1338
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
1316
1339
|
}
|
|
1317
|
-
const tStart =
|
|
1340
|
+
const tStart = chunkECLBZV4N_cjs.resolveAt(t.at, parentDuration);
|
|
1318
1341
|
const tEnd = tStart + t.duration;
|
|
1319
1342
|
const fromSeq = fromEntry.seq;
|
|
1320
|
-
const fromStart =
|
|
1343
|
+
const fromStart = chunkECLBZV4N_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
1321
1344
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
1322
1345
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
1323
1346
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
1324
1347
|
}
|
|
1325
1348
|
const toSeq = toEntry.seq;
|
|
1326
|
-
const toStart =
|
|
1349
|
+
const toStart = chunkECLBZV4N_cjs.resolveAt(toSeq.at, parentDuration);
|
|
1327
1350
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
1328
1351
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
1329
1352
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
@@ -1383,7 +1406,7 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
1383
1406
|
delete inner.at;
|
|
1384
1407
|
delete inner.duration;
|
|
1385
1408
|
const m = inner.mask;
|
|
1386
|
-
const carriesMatte = m !== void 0 &&
|
|
1409
|
+
const carriesMatte = m !== void 0 && chunkOGLRSR6C_cjs.maskSourceOf(m).kind === "refs";
|
|
1387
1410
|
if (carriesMatte) delete inner.mask;
|
|
1388
1411
|
return {
|
|
1389
1412
|
...carriesMatte ? { mask: m } : {},
|
|
@@ -1653,7 +1676,7 @@ function canvasReport(root) {
|
|
|
1653
1676
|
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") : "";
|
|
1654
1677
|
out.push({ name: seq.spec.name ?? name, moments, drawMs, ok: !differs.length && !threw.length, problem, kind });
|
|
1655
1678
|
}
|
|
1656
|
-
if (seq instanceof
|
|
1679
|
+
if (seq instanceof chunkOGLRSR6C_cjs.CompositionSequence) walk3(seq);
|
|
1657
1680
|
};
|
|
1658
1681
|
const walk3 = (comp) => {
|
|
1659
1682
|
for (const { seq } of comp.layers()) {
|
|
@@ -1705,8 +1728,8 @@ function motionOf(keyframes, local, lives, keys = (k) => GEOMETRY.has(k)) {
|
|
|
1705
1728
|
let length = 0;
|
|
1706
1729
|
if (typeof kf.duration === "number") length = kf.duration;
|
|
1707
1730
|
else if (kf.duration === "auto") {
|
|
1708
|
-
const sp =
|
|
1709
|
-
length = sp ? Math.round(
|
|
1731
|
+
const sp = chunkECLBZV4N_cjs.parseSpring(kf.ease);
|
|
1732
|
+
length = sp ? Math.round(chunkECLBZV4N_cjs.springDuration(sp) * 1e3) / 1e3 : 0.5;
|
|
1710
1733
|
}
|
|
1711
1734
|
if (!(length > 0)) continue;
|
|
1712
1735
|
const kat = kf.at ?? 0;
|
|
@@ -1786,7 +1809,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1786
1809
|
if (motion.ever) hasMotion.add(info);
|
|
1787
1810
|
let shown = bounds ? clip(bounds, view) : null;
|
|
1788
1811
|
const maskTarget = seq.maskSequence?.target;
|
|
1789
|
-
const maskSrc =
|
|
1812
|
+
const maskSrc = chunkOGLRSR6C_cjs.maskSourceOf(seq.spec.mask);
|
|
1790
1813
|
if (shown && maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert)) {
|
|
1791
1814
|
const m = maskTarget.getBounds();
|
|
1792
1815
|
shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
|
|
@@ -1795,7 +1818,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1795
1818
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1796
1819
|
if (group) scene.set(info, group);
|
|
1797
1820
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1798
|
-
if (seq instanceof
|
|
1821
|
+
if (seq instanceof chunkOGLRSR6C_cjs.CompositionSequence) walk3(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
|
|
1799
1822
|
});
|
|
1800
1823
|
};
|
|
1801
1824
|
walk3(root, "", false, true);
|
|
@@ -1967,12 +1990,12 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
1967
1990
|
const alive = (threeD ? d.visible : (t?.renderable ?? true) && t?.visible !== false) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1968
1991
|
const visible = parentVisible && alive && alpha > 0;
|
|
1969
1992
|
if (!visible) {
|
|
1970
|
-
if (seq instanceof
|
|
1993
|
+
if (seq instanceof chunkOGLRSR6C_cjs.CompositionSequence && !threeD && parentVisible && alpha > 0 && t?.visible === false && (t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true)) hiddenSources.set(seq, path);
|
|
1971
1994
|
return;
|
|
1972
1995
|
}
|
|
1973
|
-
const isComposition = seq instanceof
|
|
1996
|
+
const isComposition = seq instanceof chunkOGLRSR6C_cjs.CompositionSequence;
|
|
1974
1997
|
if (isComposition && !threeD) {
|
|
1975
|
-
const gm = seq.maskSequence?.target, gs =
|
|
1998
|
+
const gm = seq.maskSequence?.target, gs = chunkOGLRSR6C_cjs.maskSourceOf(seq.spec.mask);
|
|
1976
1999
|
if (gm && gs.kind === "inline" && !gs.invert && !inMask(gm, at)) return;
|
|
1977
2000
|
walk3(seq, path + "/", visible, at, orderBase, via);
|
|
1978
2001
|
return;
|
|
@@ -2028,7 +2051,7 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
2028
2051
|
}
|
|
2029
2052
|
if (!hit) return;
|
|
2030
2053
|
const maskTarget = seq.maskSequence?.target;
|
|
2031
|
-
const maskSrc =
|
|
2054
|
+
const maskSrc = chunkOGLRSR6C_cjs.maskSourceOf(seq.spec.mask);
|
|
2032
2055
|
if (maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert) && !(maskSrc.kind === "inline" ? inMask(maskTarget, point) : inside(maskTarget.getBounds(), point))) return;
|
|
2033
2056
|
found.push({ hit: via ? { ...hit, point: { x, y }, via } : hit, order: orderBase ? [...orderBase, ...orderOf(d)] : orderOf(d) });
|
|
2034
2057
|
});
|
|
@@ -2038,7 +2061,7 @@ function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
|
2038
2061
|
const path = hiddenSources.get(f.source);
|
|
2039
2062
|
if (path === void 0) continue;
|
|
2040
2063
|
const g = f.source.target.toGlobal({ x: f.at.x * f.source.intrinsicWidth, y: f.at.y * f.source.intrinsicHeight });
|
|
2041
|
-
const sm = f.source.maskSequence?.target, ss =
|
|
2064
|
+
const sm = f.source.maskSequence?.target, ss = chunkOGLRSR6C_cjs.maskSourceOf(f.source.spec.mask);
|
|
2042
2065
|
if (sm && ss.kind === "inline" && !ss.invert && !inMask(sm, g)) continue;
|
|
2043
2066
|
walk3(f.source, path + "/", true, g, f.order, f.via);
|
|
2044
2067
|
}
|
|
@@ -2074,7 +2097,7 @@ function walk(root, visit) {
|
|
|
2074
2097
|
visit(seq);
|
|
2075
2098
|
const mask = seq.maskSequence;
|
|
2076
2099
|
if (mask) visit(mask);
|
|
2077
|
-
if (seq instanceof
|
|
2100
|
+
if (seq instanceof chunkOGLRSR6C_cjs.CompositionSequence) walk(seq, visit);
|
|
2078
2101
|
}
|
|
2079
2102
|
}
|
|
2080
2103
|
function reusePoolOf(old) {
|
|
@@ -2175,7 +2198,7 @@ var round = (n) => Math.round(n * 1e6) / 1e6;
|
|
|
2175
2198
|
var family = (name) => name.replace(/\d+/g, "#");
|
|
2176
2199
|
function detailOf(seq) {
|
|
2177
2200
|
const s = seq.spec;
|
|
2178
|
-
const spans =
|
|
2201
|
+
const spans = chunkECLBZV4N_cjs.spansMeta.get(seq.spec)?.preview;
|
|
2179
2202
|
if (spans) return spans.length > 60 ? spans.slice(0, 57) + "\u2026" : spans;
|
|
2180
2203
|
if (typeof s.text === "string") return s.text.length > 60 ? s.text.slice(0, 57) + "\u2026" : s.text;
|
|
2181
2204
|
if (typeof s.asset === "string") return `asset \u201C${s.asset}\u201D`;
|
|
@@ -2191,10 +2214,10 @@ function walk2(comp, parentStart, parentEnd, depth, prefix, rows, transitions, l
|
|
|
2191
2214
|
const start = parentStart + (seq.at ?? 0);
|
|
2192
2215
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
2193
2216
|
const span = end - start;
|
|
2194
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
2217
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkECLBZV4N_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
2195
2218
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
|
|
2196
2219
|
const inner = [];
|
|
2197
|
-
const isComp = seq instanceof
|
|
2220
|
+
const isComp = seq instanceof chunkOGLRSR6C_cjs.CompositionSequence;
|
|
2198
2221
|
if (isComp) {
|
|
2199
2222
|
const label = seq.remapLabel();
|
|
2200
2223
|
walk2(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
@@ -2353,7 +2376,7 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
|
2353
2376
|
}
|
|
2354
2377
|
|
|
2355
2378
|
// src/core/vars.ts
|
|
2356
|
-
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...
|
|
2379
|
+
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunkECLBZV4N_cjs.EXPRESSION_NAMES];
|
|
2357
2380
|
var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2358
2381
|
var isPlain = (v) => !!v && typeof v === "object" && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
2359
2382
|
function normalizeVars(raw, where, warn = (m) => console.warn(m)) {
|
|
@@ -2897,8 +2920,8 @@ var Movie = class {
|
|
|
2897
2920
|
this.stops = normalizeStops(applyVars(options.composition, this._vars)?.stops, this.duration, this.frameRate);
|
|
2898
2921
|
this._posterFrame = poster.frame;
|
|
2899
2922
|
this.background = options.background ?? "#000000";
|
|
2900
|
-
this.timeline =
|
|
2901
|
-
|
|
2923
|
+
this.timeline = chunkECLBZV4N_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2924
|
+
chunkECLBZV4N_cjs.lengthen(this.timeline, this.duration);
|
|
2902
2925
|
const baseAppOptions = {
|
|
2903
2926
|
width: this.width,
|
|
2904
2927
|
height: this.height,
|
|
@@ -2997,7 +3020,7 @@ var Movie = class {
|
|
|
2997
3020
|
height: sizeWins ? height : spec.height ?? height,
|
|
2998
3021
|
duration: spec.duration ?? this.duration
|
|
2999
3022
|
} : void 0;
|
|
3000
|
-
await
|
|
3023
|
+
await chunkECLBZV4N_cjs.ensureFilterLibrary(seededComposition);
|
|
3001
3024
|
if (chunkWYR2AU4W_cjs.usesAdvancedBlend(seededComposition)) await chunkWYR2AU4W_cjs.enableAdvancedBlend(this.app.renderer);
|
|
3002
3025
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
3003
3026
|
const rootSeqSpec = {
|
|
@@ -3008,7 +3031,7 @@ var Movie = class {
|
|
|
3008
3031
|
...userComposition
|
|
3009
3032
|
};
|
|
3010
3033
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
3011
|
-
const sequence = new
|
|
3034
|
+
const sequence = new chunkOGLRSR6C_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
3012
3035
|
lp?.begin("build", countLayers(rootSeqSpec));
|
|
3013
3036
|
try {
|
|
3014
3037
|
await sequence.build();
|
|
@@ -3147,8 +3170,8 @@ var Movie = class {
|
|
|
3147
3170
|
if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
|
|
3148
3171
|
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged, reusePoolOf(this._rootSequence));
|
|
3149
3172
|
alive();
|
|
3150
|
-
const timeline =
|
|
3151
|
-
|
|
3173
|
+
const timeline = chunkECLBZV4N_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
3174
|
+
chunkECLBZV4N_cjs.lengthen(timeline, this.duration);
|
|
3152
3175
|
sequence.bindTimeline(timeline);
|
|
3153
3176
|
const hadSound = this.audioBuffer !== null;
|
|
3154
3177
|
const audio = await this._mixSound(sequence, this._ensureAudioContext());
|
|
@@ -3923,7 +3946,7 @@ function countLayers(spec) {
|
|
|
3923
3946
|
n += 1 + countLayers(s);
|
|
3924
3947
|
const spans = s.spans;
|
|
3925
3948
|
if (Array.isArray(spans)) n += spans.length;
|
|
3926
|
-
const src =
|
|
3949
|
+
const src = chunkOGLRSR6C_cjs.maskSourceOf(mask);
|
|
3927
3950
|
if (src.kind === "inline") n += 1 + countLayers(src.spec);
|
|
3928
3951
|
}
|
|
3929
3952
|
return n;
|
|
@@ -4012,8 +4035,8 @@ function splitVertical(text, style, ts, right, top, align, by) {
|
|
|
4012
4035
|
|
|
4013
4036
|
// src/presets/_ease.ts
|
|
4014
4037
|
function parseEase2(name) {
|
|
4015
|
-
|
|
4016
|
-
return
|
|
4038
|
+
chunkECLBZV4N_cjs.checkEase(name, "a preset");
|
|
4039
|
+
return chunkECLBZV4N_cjs.parseEase(name);
|
|
4017
4040
|
}
|
|
4018
4041
|
|
|
4019
4042
|
// src/presets/kenBurns.ts
|
|
@@ -4148,17 +4171,17 @@ function orbit(opts) {
|
|
|
4148
4171
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
4149
4172
|
}
|
|
4150
4173
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
4151
|
-
const fixedR = opts.radius ??
|
|
4174
|
+
const fixedR = opts.radius ?? chunkECLBZV4N_cjs.homeDistance(height, fov ?? chunkECLBZV4N_cjs.DEFAULT_FOV);
|
|
4152
4175
|
const start = opts.start ?? -degrees / 2;
|
|
4153
4176
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
4154
4177
|
const easeFn = parseEase2(ease);
|
|
4155
4178
|
const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
|
|
4156
4179
|
const pos = (i) => {
|
|
4157
4180
|
const p = i / steps;
|
|
4158
|
-
const a = (start + degrees * easeFn(p)) *
|
|
4181
|
+
const a = (start + degrees * easeFn(p)) * chunkECLBZV4N_cjs.DEG;
|
|
4159
4182
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
4160
4183
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
4161
|
-
const R =
|
|
4184
|
+
const R = chunkECLBZV4N_cjs.homeDistance(height, f);
|
|
4162
4185
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
4163
4186
|
};
|
|
4164
4187
|
const keyframes = [];
|
|
@@ -4213,7 +4236,7 @@ function particles(opts) {
|
|
|
4213
4236
|
const round2 = (v) => Math.round(v * 1e6) / 1e6;
|
|
4214
4237
|
const out = [];
|
|
4215
4238
|
for (let i = 0; i < count; i++) {
|
|
4216
|
-
const r =
|
|
4239
|
+
const r = chunkECLBZV4N_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
4217
4240
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
4218
4241
|
const born = at + r() * emit;
|
|
4219
4242
|
const lifetime = pick(life);
|
|
@@ -4226,7 +4249,7 @@ function particles(opts) {
|
|
|
4226
4249
|
const turn = spin ? pick(spin) : 0;
|
|
4227
4250
|
const startAngle = spin ? r() * 360 : 0;
|
|
4228
4251
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
4229
|
-
const n0 = sway ?
|
|
4252
|
+
const n0 = sway ? chunkECLBZV4N_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
4230
4253
|
const at_ = (t) => {
|
|
4231
4254
|
const axis = (p0, v0, acc) => {
|
|
4232
4255
|
if (drag > 0) {
|
|
@@ -4235,7 +4258,7 @@ function particles(opts) {
|
|
|
4235
4258
|
}
|
|
4236
4259
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
4237
4260
|
};
|
|
4238
|
-
const sw = sway ? swayAmp * (
|
|
4261
|
+
const sw = sway ? swayAmp * (chunkECLBZV4N_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
4239
4262
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
4240
4263
|
};
|
|
4241
4264
|
const kfs = [];
|
|
@@ -4297,7 +4320,7 @@ function followPath(opts) {
|
|
|
4297
4320
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
4298
4321
|
const segments = [];
|
|
4299
4322
|
let total = 0;
|
|
4300
|
-
for (const line of
|
|
4323
|
+
for (const line of chunkECLBZV4N_cjs.flattenSvgPath(d)) {
|
|
4301
4324
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
4302
4325
|
for (let i = 2; i < p.length; i += 2) {
|
|
4303
4326
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -4350,7 +4373,7 @@ function followPath(opts) {
|
|
|
4350
4373
|
// src/core/pathSample.ts
|
|
4351
4374
|
function samplePath(d) {
|
|
4352
4375
|
if (typeof d !== "string" || d.trim() === "") throw new Error('samplePath(): d must be SVG path data, e.g. "M 40 300 C 200 20 400 20 560 300"');
|
|
4353
|
-
const lines =
|
|
4376
|
+
const lines = chunkECLBZV4N_cjs.flattenSvgPath(d);
|
|
4354
4377
|
const segments = [];
|
|
4355
4378
|
let length = 0;
|
|
4356
4379
|
for (const line of lines) {
|
|
@@ -4381,7 +4404,7 @@ function samplePath(d) {
|
|
|
4381
4404
|
return { x: g.x0 + (g.x1 - g.x0) * t, y: g.y0 + (g.y1 - g.y0) * t, angle: Math.atan2(g.y1 - g.y0, g.x1 - g.x0) };
|
|
4382
4405
|
},
|
|
4383
4406
|
trim(start = 0, end = 1) {
|
|
4384
|
-
return
|
|
4407
|
+
return chunkECLBZV4N_cjs.trimPolylines(lines, start, end).map((l) => l.closed ? [...l.pts, l.pts[0], l.pts[1]] : l.pts);
|
|
4385
4408
|
}
|
|
4386
4409
|
};
|
|
4387
4410
|
}
|
|
@@ -4492,7 +4515,7 @@ function distances(n, from, grid, seed) {
|
|
|
4492
4515
|
if (n === 0) return [];
|
|
4493
4516
|
if (from === "random") {
|
|
4494
4517
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
4495
|
-
const r =
|
|
4518
|
+
const r = chunkECLBZV4N_cjs.random(seed);
|
|
4496
4519
|
for (let i = n - 1; i > 0; i--) {
|
|
4497
4520
|
const j = Math.floor(r() * (i + 1));
|
|
4498
4521
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -4554,7 +4577,7 @@ function wiggle(opts) {
|
|
|
4554
4577
|
to[n] = p.around;
|
|
4555
4578
|
return;
|
|
4556
4579
|
}
|
|
4557
|
-
const off = (
|
|
4580
|
+
const off = (chunkECLBZV4N_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
4558
4581
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
4559
4582
|
});
|
|
4560
4583
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -5025,5 +5048,5 @@ exports.splitText = splitText;
|
|
|
5025
5048
|
exports.stagger = stagger;
|
|
5026
5049
|
exports.wiggle = wiggle;
|
|
5027
5050
|
exports.withFade = withFade;
|
|
5028
|
-
//# sourceMappingURL=chunk-
|
|
5029
|
-
//# sourceMappingURL=chunk-
|
|
5051
|
+
//# sourceMappingURL=chunk-NGK4E536.cjs.map
|
|
5052
|
+
//# sourceMappingURL=chunk-NGK4E536.cjs.map
|