pixi-effects 0.26.2 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +8 -10
- package/ai/CHAT.md +1 -1
- package/ai/chat-template.html +4 -6
- package/ai/tools/render.mjs +16 -11
- package/dist/{Base-CpdDs4HT.d.ts → Base-CVezIEdo.d.ts} +2 -4
- package/dist/{Base-TbBhHPrG.d.cts → Base-DzC3i919.d.cts} +2 -4
- package/dist/Composition-4TYDRRRY.js +7 -0
- package/dist/{Composition-H4QA24MV.js.map → Composition-4TYDRRRY.js.map} +1 -1
- package/dist/Composition-QCOWQSDB.cjs +16 -0
- package/dist/{Composition-HM4YT5L7.cjs.map → Composition-QCOWQSDB.cjs.map} +1 -1
- package/dist/Controller.d.cts +2 -3
- package/dist/Controller.d.ts +2 -3
- package/dist/{Movie-i05Oh9mJ.d.cts → Movie-CQ0Nz62a.d.cts} +12 -6
- package/dist/{Movie-DVeDTdnc.d.ts → Movie-M9dKm9dI.d.ts} +12 -6
- package/dist/Presenter.d.cts +2 -3
- package/dist/Presenter.d.ts +2 -3
- package/dist/{blendModes-YV43K6E7.cjs → blendModes-HDOP6R7T.cjs} +5 -5
- package/dist/{blendModes-YV43K6E7.cjs.map → blendModes-HDOP6R7T.cjs.map} +1 -1
- package/dist/{blendModes-G3NOAU3T.js → blendModes-PAVTW3BO.js} +4 -4
- package/dist/{blendModes-G3NOAU3T.js.map → blendModes-PAVTW3BO.js.map} +1 -1
- package/dist/{chunk-TLYTYBWX.js → chunk-45QKLD6M.js} +9 -11
- package/dist/chunk-45QKLD6M.js.map +1 -0
- package/dist/{chunk-GBUM7X2S.js → chunk-CKTS6G6I.js} +7 -11
- package/dist/chunk-CKTS6G6I.js.map +1 -0
- package/dist/{chunk-555URQHQ.cjs → chunk-NDR2VQFV.cjs} +91 -95
- package/dist/chunk-NDR2VQFV.cjs.map +1 -0
- package/dist/{chunk-3DLYAPK7.cjs → chunk-P4GY3Z4G.cjs} +5 -5
- package/dist/{chunk-3DLYAPK7.cjs.map → chunk-P4GY3Z4G.cjs.map} +1 -1
- package/dist/{chunk-WPXDRSGN.cjs → chunk-RQMI7EJT.cjs} +1170 -280
- package/dist/chunk-RQMI7EJT.cjs.map +1 -0
- package/dist/{chunk-X3HB4DSR.js → chunk-TGJACVLD.js} +1150 -263
- package/dist/chunk-TGJACVLD.js.map +1 -0
- package/dist/{chunk-AXZUKNXF.js → chunk-TYWFKCPY.js} +4 -4
- package/dist/{chunk-AXZUKNXF.js.map → chunk-TYWFKCPY.js.map} +1 -1
- package/dist/{chunk-ECA2WNRX.cjs → chunk-ZMAD3KJU.cjs} +9 -11
- package/dist/chunk-ZMAD3KJU.cjs.map +1 -0
- package/dist/index.cjs +189 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -14
- package/dist/index.d.ts +16 -14
- package/dist/index.js +136 -45
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/three.cjs +6 -6
- package/dist/three.d.cts +2 -3
- package/dist/three.d.ts +2 -3
- package/dist/three.js +2 -2
- package/dist/{types-DSGwN5w1.d.ts → types-DUVefWiB.d.cts} +128 -3
- package/dist/{types-DSGwN5w1.d.cts → types-DUVefWiB.d.ts} +128 -3
- package/docs/api.md +16 -6
- package/docs/dsl.md +14 -14
- package/llms-full.txt +38 -28
- package/llms.txt +1 -1
- package/package.json +3 -4
- package/skills/pixi-effects/SKILL.md +1 -1
- package/skills/pixi-effects/reference/cheatsheet.md +3 -3
- package/skills/pixi-effects/reference/pitfalls.md +3 -3
- package/skills/pixi-effects/reference/recipes.md +1 -1
- package/skills/pixi-effects/template.html +6 -8
- package/dist/Composition-H4QA24MV.js +0 -7
- package/dist/Composition-HM4YT5L7.cjs +0 -16
- package/dist/chunk-555URQHQ.cjs.map +0 -1
- package/dist/chunk-ECA2WNRX.cjs.map +0 -1
- package/dist/chunk-GBUM7X2S.js.map +0 -1
- package/dist/chunk-TLYTYBWX.js.map +0 -1
- package/dist/chunk-WPXDRSGN.cjs.map +0 -1
- package/dist/chunk-X3HB4DSR.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,41 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
3
|
+
var chunkNDR2VQFV_cjs = require('./chunk-NDR2VQFV.cjs');
|
|
4
|
+
var chunkRQMI7EJT_cjs = require('./chunk-RQMI7EJT.cjs');
|
|
5
|
+
var chunkP4GY3Z4G_cjs = require('./chunk-P4GY3Z4G.cjs');
|
|
6
|
+
var chunkZMAD3KJU_cjs = require('./chunk-ZMAD3KJU.cjs');
|
|
7
7
|
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
8
|
-
var
|
|
9
|
-
var gsap = require('gsap');
|
|
10
|
-
var PixiPlugin = require('gsap/PixiPlugin');
|
|
8
|
+
var pixi_js = require('pixi.js');
|
|
11
9
|
var mediabunny = require('mediabunny');
|
|
12
10
|
|
|
13
|
-
function _interopNamespace(e) {
|
|
14
|
-
if (e && e.__esModule) return e;
|
|
15
|
-
var n = Object.create(null);
|
|
16
|
-
if (e) {
|
|
17
|
-
Object.keys(e).forEach(function (k) {
|
|
18
|
-
if (k !== 'default') {
|
|
19
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
get: function () { return e[k]; }
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
n.default = e;
|
|
28
|
-
return Object.freeze(n);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
var PIXI__namespace = /*#__PURE__*/_interopNamespace(PIXI);
|
|
32
|
-
|
|
33
11
|
var registered = false;
|
|
34
12
|
function ensureLoadersRegistered(audioContext) {
|
|
35
13
|
if (registered) return;
|
|
36
14
|
registered = true;
|
|
37
|
-
|
|
38
|
-
extension: { type:
|
|
15
|
+
pixi_js.extensions.add({
|
|
16
|
+
extension: { type: pixi_js.ExtensionType.LoadParser, name: "pixi-effects-audio" },
|
|
39
17
|
test: (url) => /\.(mp3|wav|ogg)$/i.test(url),
|
|
40
18
|
async load(url) {
|
|
41
19
|
const res = await fetch(url);
|
|
@@ -45,8 +23,8 @@ function ensureLoadersRegistered(audioContext) {
|
|
|
45
23
|
return { audioBuffer, duration: audioBuffer.duration };
|
|
46
24
|
}
|
|
47
25
|
});
|
|
48
|
-
|
|
49
|
-
extension: { type:
|
|
26
|
+
pixi_js.extensions.add({
|
|
27
|
+
extension: { type: pixi_js.ExtensionType.LoadParser, name: "pixi-effects-video", priority: 1 },
|
|
50
28
|
test: (url) => /\.(mp4|webm|mov|mkv)$/i.test(url),
|
|
51
29
|
async load(url) {
|
|
52
30
|
const blob = await fetch(url).then((r) => r.blob());
|
|
@@ -83,8 +61,8 @@ function ensureLoadersRegistered(audioContext) {
|
|
|
83
61
|
async function loadAssetBundle(assets, audioContext, onProgress) {
|
|
84
62
|
ensureLoadersRegistered(audioContext);
|
|
85
63
|
const bundle = assets.map((a) => ({ alias: a.name, src: a.src }));
|
|
86
|
-
|
|
87
|
-
return await
|
|
64
|
+
pixi_js.Assets.addBundle("pixi-effects", bundle);
|
|
65
|
+
return await pixi_js.Assets.loadBundle("pixi-effects", onProgress);
|
|
88
66
|
}
|
|
89
67
|
|
|
90
68
|
// src/core/audioRemap.ts
|
|
@@ -779,24 +757,70 @@ function resolveRenderOptions(o) {
|
|
|
779
757
|
};
|
|
780
758
|
}
|
|
781
759
|
|
|
782
|
-
// src/core/
|
|
783
|
-
var
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
760
|
+
// src/core/renderOptions.ts
|
|
761
|
+
var QUALITY_NAMES = ["very-low", "low", "medium", "high", "very-high"];
|
|
762
|
+
function parseBitrate(v) {
|
|
763
|
+
if (v === void 0 || v === null) return {};
|
|
764
|
+
if (typeof v === "string" && QUALITY_NAMES.includes(v)) return { quality: v };
|
|
765
|
+
if (typeof v === "number" && Number.isFinite(v) && v > 0) return { bps: Math.round(v) };
|
|
766
|
+
const m = typeof v === "string" ? /^\s*(\d+(?:\.\d+)?)\s*([kKmM]?)\s*$/.exec(v) : null;
|
|
767
|
+
if (m) {
|
|
768
|
+
const n = Number(m[1]) * { "": 1, k: 1e3, m: 1e6 }[m[2].toLowerCase()];
|
|
769
|
+
if (n > 0) return { bps: Math.round(n) };
|
|
770
|
+
}
|
|
771
|
+
throw new Error(`pixi-effects: bitrate ${JSON.stringify(v)}: use a quality (${QUALITY_NAMES.join(", ")}) or bits a second (8000000, '8M', '800k')`);
|
|
772
|
+
}
|
|
773
|
+
var AUDIO_FORMATS = ["wav", "ogg"];
|
|
774
|
+
var isAudioFormat = (f) => AUDIO_FORMATS.includes(f);
|
|
775
|
+
var VIDEO_CODEC_PREFERENCE = {
|
|
776
|
+
mp4: ["avc", "hevc", "vp9", "av1"],
|
|
777
|
+
mov: ["avc", "hevc"],
|
|
778
|
+
webm: ["vp9", "av1", "vp8"],
|
|
779
|
+
mkv: ["vp9", "avc", "hevc", "av1", "vp8"]
|
|
788
780
|
};
|
|
789
|
-
var
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
781
|
+
var CODEC_ALIASES = {
|
|
782
|
+
h264: "avc",
|
|
783
|
+
"h.264": "avc",
|
|
784
|
+
x264: "avc",
|
|
785
|
+
avc1: "avc",
|
|
786
|
+
h265: "hevc",
|
|
787
|
+
"h.265": "hevc",
|
|
788
|
+
x265: "hevc",
|
|
789
|
+
hvc1: "hevc",
|
|
790
|
+
hev1: "hevc",
|
|
791
|
+
vp09: "vp9",
|
|
792
|
+
"vp-9": "vp9",
|
|
793
|
+
av01: "av1",
|
|
794
|
+
vp80: "vp8",
|
|
795
|
+
"vp-8": "vp8"
|
|
794
796
|
};
|
|
797
|
+
async function chooseVideoCodec(a) {
|
|
798
|
+
const held = a.supported ?? VIDEO_CODEC_PREFERENCE[a.fmt];
|
|
799
|
+
const order = VIDEO_CODEC_PREFERENCE[a.fmt].filter((c) => held.includes(c));
|
|
800
|
+
const firstThatWorks = async (list) => {
|
|
801
|
+
for (const c of list) if (await a.canEncode(c)) return c;
|
|
802
|
+
return null;
|
|
803
|
+
};
|
|
804
|
+
if (a.requested) {
|
|
805
|
+
const alias = CODEC_ALIASES[a.requested.toLowerCase()];
|
|
806
|
+
if (alias) throw new Error(`pixi-effects: render({ video: { codec: "${a.requested}" } }): "${a.requested}" is not a codec name here; did you mean "${alias}"?`);
|
|
807
|
+
if (!order.includes(a.requested)) throw new Error(`pixi-effects: render(): "${a.requested}" cannot go in ${a.fmt} (${a.fmt} holds ${order.join(", ")})`);
|
|
808
|
+
if (await a.canEncode(a.requested)) return { codec: a.requested };
|
|
809
|
+
const alt = await firstThatWorks(order.filter((c) => c !== a.requested));
|
|
810
|
+
throw new Error(`pixi-effects: this browser cannot encode "${a.requested}" video for ${a.fmt}` + (alt ? `; "${alt}" would work: render({ format: '${a.fmt}', video: { codec: '${alt}' } }), or leave video.codec out and the best one is chosen.` : "; it can encode none of " + order.join(", ") + "."));
|
|
811
|
+
}
|
|
812
|
+
const chosen = await firstThatWorks(order);
|
|
813
|
+
if (!chosen) throw new Error(`pixi-effects: this browser has no video encoder for ${a.fmt} (it tried ${order.join(", ")}): try another browser, or another format`);
|
|
814
|
+
return chosen === order[0] ? { codec: chosen } : { codec: chosen, fellBackFrom: order[0] };
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/core/Renderer.ts
|
|
795
818
|
var AUDIO_PREFERENCE = {
|
|
796
819
|
mp4: ["aac", "opus", "mp3", "flac"],
|
|
797
820
|
mov: ["aac", "mp3"],
|
|
798
821
|
webm: ["opus", "vorbis"],
|
|
799
|
-
mkv: ["opus", "vorbis", "aac", "flac", "mp3"]
|
|
822
|
+
mkv: ["opus", "vorbis", "aac", "flac", "mp3"],
|
|
823
|
+
ogg: ["opus", "vorbis", "flac"]
|
|
800
824
|
};
|
|
801
825
|
async function chooseAudioCodec(fmt, requested, container, audio, bitrate) {
|
|
802
826
|
const supported = container.getSupportedAudioCodecs?.();
|
|
@@ -821,6 +845,10 @@ var qualityMap = {
|
|
|
821
845
|
"high": mediabunny.QUALITY_HIGH,
|
|
822
846
|
"very-high": mediabunny.QUALITY_VERY_HIGH
|
|
823
847
|
};
|
|
848
|
+
function bitrateOf(v, fallback) {
|
|
849
|
+
const b = parseBitrate(v);
|
|
850
|
+
return b.bps ?? (b.quality ? qualityMap[b.quality] : fallback);
|
|
851
|
+
}
|
|
824
852
|
function makeOutputFormat(name) {
|
|
825
853
|
switch (name) {
|
|
826
854
|
case "mp4":
|
|
@@ -840,19 +868,47 @@ function sliceAudio(buffer, fromSec, toSec, fadeIn, fadeOut) {
|
|
|
840
868
|
cut.forEach((data, c) => out.copyToChannel(data, c));
|
|
841
869
|
return out;
|
|
842
870
|
}
|
|
871
|
+
async function exportAudioOnly(movie, options, fmt, range2) {
|
|
872
|
+
if (!movie.audioBuffer) {
|
|
873
|
+
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`);
|
|
874
|
+
}
|
|
875
|
+
if (options.video) console.warn(`pixi-effects: render({ format: '${fmt}' }): video options are ignored, only the sound is written`);
|
|
876
|
+
const audio = range2.partial ? sliceAudio(movie.audioBuffer, range2.fromSec, range2.toSec, range2.fromFrame > 0, range2.toFrame < movie.totalFrames) : movie.audioBuffer;
|
|
877
|
+
const container = fmt === "wav" ? new mediabunny.WavOutputFormat() : new mediabunny.OggOutputFormat();
|
|
878
|
+
let codec;
|
|
879
|
+
if (fmt === "wav") {
|
|
880
|
+
codec = options.audio?.codec ?? "pcm-s16";
|
|
881
|
+
const held = container.getSupportedAudioCodecs();
|
|
882
|
+
if (!held.includes(codec)) throw new Error(`pixi-effects: render({ format: 'wav', audio: { codec: "${codec}" } }): wav holds ${held.join(", ")} (the usual is pcm-s16)`);
|
|
883
|
+
} else {
|
|
884
|
+
codec = await chooseAudioCodec("ogg", options.audio?.codec, container, audio, bitrateOf(options.audio?.bitrate, mediabunny.QUALITY_HIGH));
|
|
885
|
+
}
|
|
886
|
+
const output = new mediabunny.Output({ format: container, target: new mediabunny.BufferTarget() });
|
|
887
|
+
const source = new mediabunny.AudioBufferSource({ codec, ...fmt === "wav" ? {} : { bitrate: bitrateOf(options.audio?.bitrate, mediabunny.QUALITY_HIGH) } });
|
|
888
|
+
output.addAudioTrack(source);
|
|
889
|
+
movie.emit("progress", { progress: 0, frame: range2.fromFrame, totalFrames: movie.totalFrames });
|
|
890
|
+
await output.start();
|
|
891
|
+
await source.add(audio);
|
|
892
|
+
await source.close();
|
|
893
|
+
await output.finalize();
|
|
894
|
+
movie.emit("progress", { progress: 100, frame: range2.toFrame, totalFrames: movie.totalFrames });
|
|
895
|
+
return new Blob([output.target.buffer], { type: output.format.mimeType });
|
|
896
|
+
}
|
|
843
897
|
async function exportFrames(movie, options = {}) {
|
|
844
898
|
const fmt = options.format ?? "mp4";
|
|
845
899
|
const eff = resolveRenderOptions(options);
|
|
846
900
|
const range2 = resolveRange(options.range, { frameRate: movie.frameRate, totalFrames: movie.totalFrames, duration: movie.duration, rows: typeof options.range === "string" ? movie.timelineData().rows : void 0 });
|
|
901
|
+
if (isAudioFormat(fmt)) return exportAudioOnly(movie, options, fmt, range2);
|
|
902
|
+
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)`);
|
|
903
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.render({ video })", options.video, ["codec", "bitrate", "hardware", "keyFrameInterval"]);
|
|
904
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.render({ audio })", options.audio, ["codec", "bitrate"]);
|
|
905
|
+
const videoBitrate = bitrateOf(eff.bitrate ?? "high", mediabunny.QUALITY_HIGH);
|
|
847
906
|
const opts = {
|
|
848
907
|
format: fmt,
|
|
849
|
-
video: {
|
|
850
|
-
codec: options.video?.codec ?? VIDEO_CODEC_BY_FORMAT[fmt],
|
|
851
|
-
bitrate: qualityMap[eff.bitrate ?? "high"] ?? mediabunny.QUALITY_HIGH
|
|
852
|
-
},
|
|
908
|
+
video: { codec: "", bitrate: videoBitrate },
|
|
853
909
|
audio: {
|
|
854
|
-
codec: options.audio?.codec ??
|
|
855
|
-
bitrate:
|
|
910
|
+
codec: options.audio?.codec ?? (fmt === "mp4" || fmt === "mov" ? "aac" : "opus"),
|
|
911
|
+
bitrate: bitrateOf(options.audio?.bitrate, mediabunny.QUALITY_HIGH)
|
|
856
912
|
}
|
|
857
913
|
};
|
|
858
914
|
const container = makeOutputFormat(opts.format);
|
|
@@ -867,9 +923,23 @@ async function exportFrames(movie, options = {}) {
|
|
|
867
923
|
const blurCanvas = mb ? Object.assign(document.createElement("canvas"), { width: stage.width, height: stage.height }) : null;
|
|
868
924
|
const small = eff.scale < 1 ? Object.assign(document.createElement("canvas"), { width: Math.max(2, Math.round(stage.width * eff.scale / 2) * 2), height: Math.max(2, Math.round(stage.height * eff.scale / 2) * 2) }) : null;
|
|
869
925
|
const smallCtx = small?.getContext("2d") ?? null;
|
|
870
|
-
const
|
|
926
|
+
const picture = small ?? blurCanvas ?? stage;
|
|
927
|
+
const chosen = await chooseVideoCodec({
|
|
928
|
+
fmt,
|
|
929
|
+
requested: options.video?.codec,
|
|
930
|
+
supported: container.getSupportedVideoCodecs(),
|
|
931
|
+
canEncode: (c) => mediabunny.canEncodeVideo(c, { width: picture.width, height: picture.height, bitrate: opts.video.bitrate })
|
|
932
|
+
});
|
|
933
|
+
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).`);
|
|
934
|
+
opts.video.codec = chosen.codec;
|
|
935
|
+
const hardware = options.video?.hardware;
|
|
936
|
+
if (hardware !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(hardware)) {
|
|
937
|
+
throw new Error(`pixi-effects: render({ video: { hardware: "${String(hardware)}" } }): use 'prefer-hardware', 'prefer-software' or 'no-preference'`);
|
|
938
|
+
}
|
|
939
|
+
const canvasSource = new mediabunny.CanvasSource(picture, {
|
|
871
940
|
codec: opts.video.codec,
|
|
872
|
-
bitrate: opts.video.bitrate
|
|
941
|
+
bitrate: opts.video.bitrate,
|
|
942
|
+
...hardware ? { hardwareAcceleration: hardware } : {}
|
|
873
943
|
});
|
|
874
944
|
output.addVideoTrack(canvasSource, { frameRate: movie.frameRate });
|
|
875
945
|
if (audio) {
|
|
@@ -885,7 +955,9 @@ async function exportFrames(movie, options = {}) {
|
|
|
885
955
|
await output.start();
|
|
886
956
|
}
|
|
887
957
|
movie.app.ticker.stop();
|
|
888
|
-
const
|
|
958
|
+
const interval = options.video?.keyFrameInterval ?? 2;
|
|
959
|
+
if (!(typeof interval === "number" && Number.isFinite(interval) && interval > 0)) throw new Error(`pixi-effects: render({ video: { keyFrameInterval: ${String(interval)} } }): seconds between keyframes, above 0 (default 2)`);
|
|
960
|
+
const keyframeIntervalFrames = Math.max(1, Math.round(interval * movie.frameRate));
|
|
889
961
|
try {
|
|
890
962
|
const count = Math.max(1, range2.toFrame - range2.fromFrame);
|
|
891
963
|
for (let frame = range2.fromFrame; frame <= range2.toFrame; frame++) {
|
|
@@ -1173,7 +1245,7 @@ fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
|
1173
1245
|
return raw * reveal;
|
|
1174
1246
|
}
|
|
1175
1247
|
`;
|
|
1176
|
-
var TransitionMaskFilter = class extends
|
|
1248
|
+
var TransitionMaskFilter = class extends pixi_js.Filter {
|
|
1177
1249
|
constructor(options = {}) {
|
|
1178
1250
|
const mode = options.mode ?? "wipe-left";
|
|
1179
1251
|
const smoothing = options.smoothing ?? 0.02;
|
|
@@ -1182,17 +1254,17 @@ var TransitionMaskFilter = class extends PIXI.Filter {
|
|
|
1182
1254
|
const scale = options.scale ?? 30;
|
|
1183
1255
|
const seed = options.seed ?? 0;
|
|
1184
1256
|
super({
|
|
1185
|
-
glProgram:
|
|
1186
|
-
vertex:
|
|
1257
|
+
glProgram: pixi_js.GlProgram.from({
|
|
1258
|
+
vertex: pixi_js.defaultFilterVert,
|
|
1187
1259
|
fragment: GL_FRAGMENT,
|
|
1188
1260
|
name: "transition-mask-filter"
|
|
1189
1261
|
}),
|
|
1190
|
-
gpuProgram:
|
|
1262
|
+
gpuProgram: pixi_js.GpuProgram.from({
|
|
1191
1263
|
vertex: { source: WGSL_SOURCE, entryPoint: "mainVertex" },
|
|
1192
1264
|
fragment: { source: WGSL_SOURCE, entryPoint: "mainFragment" }
|
|
1193
1265
|
}),
|
|
1194
1266
|
resources: {
|
|
1195
|
-
transitionUniforms: new
|
|
1267
|
+
transitionUniforms: new pixi_js.UniformGroup({
|
|
1196
1268
|
uProgress: { value: progress, type: "f32" },
|
|
1197
1269
|
uMode: { value: MODE_CODES[mode], type: "f32" },
|
|
1198
1270
|
uSmoothing: { value: smoothing, type: "f32" },
|
|
@@ -1319,19 +1391,19 @@ fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
|
|
|
1319
1391
|
if (lumaUniforms.uInvert > 0.5) { reveal = 1.0 - step(0.99, reveal); }
|
|
1320
1392
|
return raw * reveal;
|
|
1321
1393
|
}`;
|
|
1322
|
-
var LumaWipeFilter = class extends
|
|
1394
|
+
var LumaWipeFilter = class extends pixi_js.Filter {
|
|
1323
1395
|
_mapName;
|
|
1324
1396
|
_builtIn;
|
|
1325
1397
|
_resolved = false;
|
|
1326
1398
|
_warned = false;
|
|
1327
1399
|
constructor({ map, softness = 0.1, progress = 0, invert = false, flip = false }) {
|
|
1328
|
-
const t =
|
|
1400
|
+
const t = pixi_js.Texture.WHITE;
|
|
1329
1401
|
const mode = LUMA_MAPS.indexOf(map) + 1;
|
|
1330
1402
|
super({
|
|
1331
|
-
glProgram:
|
|
1332
|
-
gpuProgram:
|
|
1403
|
+
glProgram: pixi_js.GlProgram.from({ vertex: pixi_js.defaultFilterVert, fragment: GL, name: "pe-luma-wipe" }),
|
|
1404
|
+
gpuProgram: pixi_js.GpuProgram.from({ vertex: { source: WGSL, entryPoint: "mainVertex" }, fragment: { source: WGSL, entryPoint: "mainFragment" } }),
|
|
1333
1405
|
resources: {
|
|
1334
|
-
lumaUniforms: new
|
|
1406
|
+
lumaUniforms: new pixi_js.UniformGroup({
|
|
1335
1407
|
uProgress: { value: progress, type: "f32" },
|
|
1336
1408
|
uSoftness: { value: softness, type: "f32" },
|
|
1337
1409
|
uInvert: { value: invert ? 1 : 0, type: "f32" },
|
|
@@ -1353,7 +1425,7 @@ var LumaWipeFilter = class extends PIXI.Filter {
|
|
|
1353
1425
|
}
|
|
1354
1426
|
apply(fm, input, output, clear) {
|
|
1355
1427
|
if (!this._builtIn && !this._resolved) {
|
|
1356
|
-
const t =
|
|
1428
|
+
const t = pixi_js.Assets.get(this._mapName);
|
|
1357
1429
|
if (t) {
|
|
1358
1430
|
this.resources.uMap = t.source;
|
|
1359
1431
|
this.resources.uMapSampler = t.source.style;
|
|
@@ -1407,8 +1479,8 @@ function expandTransitions(spec) {
|
|
|
1407
1479
|
}
|
|
1408
1480
|
const transitions = out.transitions;
|
|
1409
1481
|
const sequences = out.sequences ?? [];
|
|
1410
|
-
const remap = out.duration !== void 0 ?
|
|
1411
|
-
const parentDuration = remap ?
|
|
1482
|
+
const remap = out.duration !== void 0 ? chunkRQMI7EJT_cjs.timeRemapOf(out) : null;
|
|
1483
|
+
const parentDuration = remap ? chunkRQMI7EJT_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
|
|
1412
1484
|
const compW = out.width;
|
|
1413
1485
|
const compH = out.height;
|
|
1414
1486
|
const threeDByName = new Set(sequences.filter((s) => s.name && s.threeD).map((s) => s.name));
|
|
@@ -1476,16 +1548,16 @@ function expandTransitions(spec) {
|
|
|
1476
1548
|
if (toUses > 1) {
|
|
1477
1549
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
1478
1550
|
}
|
|
1479
|
-
const tStart =
|
|
1551
|
+
const tStart = chunkRQMI7EJT_cjs.resolveAt(t.at, parentDuration);
|
|
1480
1552
|
const tEnd = tStart + t.duration;
|
|
1481
1553
|
const fromSeq = fromEntry.seq;
|
|
1482
|
-
const fromStart =
|
|
1554
|
+
const fromStart = chunkRQMI7EJT_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
1483
1555
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
1484
1556
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
1485
1557
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
1486
1558
|
}
|
|
1487
1559
|
const toSeq = toEntry.seq;
|
|
1488
|
-
const toStart =
|
|
1560
|
+
const toStart = chunkRQMI7EJT_cjs.resolveAt(toSeq.at, parentDuration);
|
|
1489
1561
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
1490
1562
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
1491
1563
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
@@ -1545,7 +1617,7 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
1545
1617
|
delete inner.at;
|
|
1546
1618
|
delete inner.duration;
|
|
1547
1619
|
const m = inner.mask;
|
|
1548
|
-
const carriesMatte = m !== void 0 &&
|
|
1620
|
+
const carriesMatte = m !== void 0 && chunkNDR2VQFV_cjs.maskSourceOf(m).kind === "refs";
|
|
1549
1621
|
if (carriesMatte) delete inner.mask;
|
|
1550
1622
|
return {
|
|
1551
1623
|
...carriesMatte ? { mask: m } : {},
|
|
@@ -1847,9 +1919,9 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1847
1919
|
onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
|
|
1848
1920
|
if (area === 0) onCanvas = "none";
|
|
1849
1921
|
}
|
|
1850
|
-
const keys =
|
|
1922
|
+
const keys = chunkZMAD3KJU_cjs.collectPropKeys(seq.spec);
|
|
1851
1923
|
const carried = carriers.some((c) => {
|
|
1852
|
-
const k =
|
|
1924
|
+
const k = chunkZMAD3KJU_cjs.collectPropKeys(c.spec);
|
|
1853
1925
|
return (c.spec.keyframes ?? []).length > 0 && (k.has("x") || k.has("y") || k.has("rotation") || k.has("scale"));
|
|
1854
1926
|
});
|
|
1855
1927
|
const moving = parentMoving || carried || (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
|
|
@@ -1872,7 +1944,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1872
1944
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1873
1945
|
if (group) scene.set(info, group);
|
|
1874
1946
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1875
|
-
if (seq instanceof
|
|
1947
|
+
if (seq instanceof chunkNDR2VQFV_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, moving, zero);
|
|
1876
1948
|
});
|
|
1877
1949
|
};
|
|
1878
1950
|
walk2(root, "", false, true);
|
|
@@ -1933,10 +2005,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
|
|
|
1933
2005
|
const start = parentStart + (seq.at ?? 0);
|
|
1934
2006
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
1935
2007
|
const span = end - start;
|
|
1936
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
2008
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkRQMI7EJT_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
1937
2009
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
|
|
1938
2010
|
const inner = [];
|
|
1939
|
-
const isComp = seq instanceof
|
|
2011
|
+
const isComp = seq instanceof chunkNDR2VQFV_cjs.CompositionSequence;
|
|
1940
2012
|
if (isComp) {
|
|
1941
2013
|
const label = seq.remapLabel();
|
|
1942
2014
|
walk(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
@@ -2448,9 +2520,7 @@ function setLoaderProgress(loader, state) {
|
|
|
2448
2520
|
}
|
|
2449
2521
|
|
|
2450
2522
|
// src/core/Movie.ts
|
|
2451
|
-
|
|
2452
|
-
gsap.gsap.registerPlugin(PixiPlugin.PixiPlugin);
|
|
2453
|
-
PixiPlugin.PixiPlugin.registerPIXI(PIXI__namespace);
|
|
2523
|
+
pixi_js.extensions.add(pixi_js.CullerPlugin);
|
|
2454
2524
|
var Movie = class {
|
|
2455
2525
|
_events = {};
|
|
2456
2526
|
_initState = "idle";
|
|
@@ -2586,8 +2656,8 @@ var Movie = class {
|
|
|
2586
2656
|
this.stops = normalizeStops(options.composition?.stops, this.duration, this.frameRate);
|
|
2587
2657
|
this._posterFrame = poster.frame;
|
|
2588
2658
|
this.background = options.background ?? "#000000";
|
|
2589
|
-
this.timeline =
|
|
2590
|
-
this.timeline
|
|
2659
|
+
this.timeline = chunkRQMI7EJT_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2660
|
+
chunkRQMI7EJT_cjs.lengthen(this.timeline, this.duration);
|
|
2591
2661
|
const baseAppOptions = {
|
|
2592
2662
|
width: this.width,
|
|
2593
2663
|
height: this.height,
|
|
@@ -2598,19 +2668,19 @@ var Movie = class {
|
|
|
2598
2668
|
preserveDrawingBuffer: true,
|
|
2599
2669
|
canvas: options.canvas
|
|
2600
2670
|
};
|
|
2601
|
-
this.app = new
|
|
2671
|
+
this.app = new pixi_js.Application();
|
|
2602
2672
|
try {
|
|
2603
2673
|
await this.app.init({ ...baseAppOptions, preference: "webgpu" });
|
|
2604
2674
|
} catch (err) {
|
|
2605
2675
|
console.warn("pixi-effects: WebGPU init failed, falling back to WebGL \u2014", err);
|
|
2606
|
-
this.app = new
|
|
2676
|
+
this.app = new pixi_js.Application();
|
|
2607
2677
|
await this.app.init({ ...baseAppOptions, preference: "webgl" });
|
|
2608
2678
|
}
|
|
2609
|
-
if (
|
|
2610
|
-
const root = new
|
|
2679
|
+
if (chunkP4GY3Z4G_cjs.usesAdvancedBlend(options.composition)) await chunkP4GY3Z4G_cjs.enableAdvancedBlend(this.app.renderer);
|
|
2680
|
+
const root = new pixi_js.Container();
|
|
2611
2681
|
root.cullable = true;
|
|
2612
2682
|
root.cullableChildren = true;
|
|
2613
|
-
root.cullArea = new
|
|
2683
|
+
root.cullArea = new pixi_js.Rectangle(0, 0, this.width, this.height);
|
|
2614
2684
|
this.app.stage.addChild(root);
|
|
2615
2685
|
this._rootContainer = root;
|
|
2616
2686
|
const audioContext = this._ensureAudioContext();
|
|
@@ -2646,7 +2716,7 @@ var Movie = class {
|
|
|
2646
2716
|
height: options.composition.height ?? this.height,
|
|
2647
2717
|
duration: options.composition.duration ?? this.duration
|
|
2648
2718
|
} : void 0;
|
|
2649
|
-
await
|
|
2719
|
+
await chunkRQMI7EJT_cjs.ensureFilterLibrary(seededComposition);
|
|
2650
2720
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
2651
2721
|
const rootSeqSpec = {
|
|
2652
2722
|
type: "composition",
|
|
@@ -2656,7 +2726,7 @@ var Movie = class {
|
|
|
2656
2726
|
...userComposition
|
|
2657
2727
|
};
|
|
2658
2728
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
2659
|
-
const composition = new
|
|
2729
|
+
const composition = new chunkNDR2VQFV_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
2660
2730
|
lp.begin("build", countLayers(rootSeqSpec));
|
|
2661
2731
|
await composition.build();
|
|
2662
2732
|
this._rootSequence = composition;
|
|
@@ -2672,8 +2742,8 @@ var Movie = class {
|
|
|
2672
2742
|
if (this.audioBuffer) this._mixStats = limitMix(this.audioBuffer, audios);
|
|
2673
2743
|
}
|
|
2674
2744
|
this._audioSources = audios;
|
|
2675
|
-
this.timeline.progress(1).progress(0);
|
|
2676
2745
|
lp.begin("frames", 0);
|
|
2746
|
+
this.timeline.time(this._timeOf(0));
|
|
2677
2747
|
await this._awaitVideoFrames();
|
|
2678
2748
|
this._updateSpace();
|
|
2679
2749
|
this._renderNow();
|
|
@@ -3008,7 +3078,7 @@ var Movie = class {
|
|
|
3008
3078
|
if (!this._synced) this._rootSequence?.syncFrame();
|
|
3009
3079
|
this._synced = false;
|
|
3010
3080
|
this._feedTimeFilters();
|
|
3011
|
-
|
|
3081
|
+
pixi_js.Culler.shared.cull(app.stage, app.renderer.screen, false);
|
|
3012
3082
|
app.renderer.render({ container: app.stage });
|
|
3013
3083
|
}
|
|
3014
3084
|
_requireReady(what) {
|
|
@@ -3329,9 +3399,9 @@ function countLayers(spec) {
|
|
|
3329
3399
|
}
|
|
3330
3400
|
var BY = ["chars", "words", "lines"];
|
|
3331
3401
|
var ALIGN = ["left", "center", "right"];
|
|
3332
|
-
var widthOf = (text, style) =>
|
|
3402
|
+
var widthOf = (text, style) => pixi_js.CanvasTextMetrics.measureText(text, style).width;
|
|
3333
3403
|
function measureText(text, style = {}) {
|
|
3334
|
-
const m =
|
|
3404
|
+
const m = pixi_js.CanvasTextMetrics.measureText(text, new pixi_js.TextStyle(style));
|
|
3335
3405
|
return { width: m.width, height: m.height, lines: text.split("\n").length };
|
|
3336
3406
|
}
|
|
3337
3407
|
function splitText(text, style = {}, opts = {}) {
|
|
@@ -3353,8 +3423,8 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3353
3423
|
if (typeof v !== "number" || !Number.isFinite(v)) throw new Error(`splitText(): ${n} must be a number of pixels (e.g. ${n}: 640), got ${JSON.stringify(v)}: the pieces are placed by measuring, so an expression such as 'GW/2' cannot be used here. \`y\` is the top of the line.`);
|
|
3354
3424
|
}
|
|
3355
3425
|
if (text === "") return [];
|
|
3356
|
-
const ts = new
|
|
3357
|
-
const lineHeight =
|
|
3426
|
+
const ts = new pixi_js.TextStyle(style);
|
|
3427
|
+
const lineHeight = pixi_js.CanvasTextMetrics.measureText("M", ts).lineHeight ?? pixi_js.CanvasTextMetrics.measureText("M", ts).height;
|
|
3358
3428
|
const sentinel = widthOf("|", ts);
|
|
3359
3429
|
const out = [];
|
|
3360
3430
|
text.split("\n").forEach((line, lineNo) => {
|
|
@@ -3378,6 +3448,12 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3378
3448
|
return out;
|
|
3379
3449
|
}
|
|
3380
3450
|
|
|
3451
|
+
// src/presets/_ease.ts
|
|
3452
|
+
function parseEase2(name) {
|
|
3453
|
+
chunkRQMI7EJT_cjs.checkEase(name, "a preset");
|
|
3454
|
+
return chunkRQMI7EJT_cjs.parseEase(name);
|
|
3455
|
+
}
|
|
3456
|
+
|
|
3381
3457
|
// src/presets/kenBurns.ts
|
|
3382
3458
|
var KEN_BURNS_KEYS = ["asset", "name", "at", "duration", "fit", "ease", "motion", "origin", "zoom", "direction", "angle", "from", "to"];
|
|
3383
3459
|
function kenBurns(opts) {
|
|
@@ -3490,10 +3566,6 @@ function kenBurns(opts) {
|
|
|
3490
3566
|
function clamp(v, lo, hi) {
|
|
3491
3567
|
return Math.max(lo, Math.min(hi, v));
|
|
3492
3568
|
}
|
|
3493
|
-
function parseEase(name) {
|
|
3494
|
-
chunkWPXDRSGN_cjs.checkEase(name, "a preset");
|
|
3495
|
-
return gsap.gsap.parseEase(name);
|
|
3496
|
-
}
|
|
3497
3569
|
|
|
3498
3570
|
// src/presets/orbit.ts
|
|
3499
3571
|
var ORBIT_KEYS = ["duration", "degrees", "start", "radius", "center", "width", "height", "fov", "ease", "dollyZoom", "at", "name", "stepsPerSecond"];
|
|
@@ -3514,17 +3586,17 @@ function orbit(opts) {
|
|
|
3514
3586
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
3515
3587
|
}
|
|
3516
3588
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
3517
|
-
const fixedR = opts.radius ??
|
|
3589
|
+
const fixedR = opts.radius ?? chunkRQMI7EJT_cjs.homeDistance(height, fov ?? chunkRQMI7EJT_cjs.DEFAULT_FOV);
|
|
3518
3590
|
const start = opts.start ?? -degrees / 2;
|
|
3519
3591
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
3520
|
-
const easeFn =
|
|
3521
|
-
const dollyEase = dolly ?
|
|
3592
|
+
const easeFn = parseEase2(ease);
|
|
3593
|
+
const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
|
|
3522
3594
|
const pos = (i) => {
|
|
3523
3595
|
const p = i / steps;
|
|
3524
|
-
const a = (start + degrees * easeFn(p)) *
|
|
3596
|
+
const a = (start + degrees * easeFn(p)) * chunkRQMI7EJT_cjs.DEG;
|
|
3525
3597
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
3526
3598
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
3527
|
-
const R =
|
|
3599
|
+
const R = chunkRQMI7EJT_cjs.homeDistance(height, f);
|
|
3528
3600
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
3529
3601
|
};
|
|
3530
3602
|
const keyframes = [];
|
|
@@ -3579,7 +3651,7 @@ function particles(opts) {
|
|
|
3579
3651
|
const round3 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3580
3652
|
const out = [];
|
|
3581
3653
|
for (let i = 0; i < count; i++) {
|
|
3582
|
-
const r =
|
|
3654
|
+
const r = chunkRQMI7EJT_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
3583
3655
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
3584
3656
|
const born = at + r() * emit;
|
|
3585
3657
|
const lifetime = pick(life);
|
|
@@ -3592,7 +3664,7 @@ function particles(opts) {
|
|
|
3592
3664
|
const turn = spin ? pick(spin) : 0;
|
|
3593
3665
|
const startAngle = spin ? r() * 360 : 0;
|
|
3594
3666
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
3595
|
-
const n0 = sway ?
|
|
3667
|
+
const n0 = sway ? chunkRQMI7EJT_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
3596
3668
|
const at_ = (t) => {
|
|
3597
3669
|
const axis = (p0, v0, acc) => {
|
|
3598
3670
|
if (drag > 0) {
|
|
@@ -3601,7 +3673,7 @@ function particles(opts) {
|
|
|
3601
3673
|
}
|
|
3602
3674
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
3603
3675
|
};
|
|
3604
|
-
const sw = sway ? swayAmp * (
|
|
3676
|
+
const sw = sway ? swayAmp * (chunkRQMI7EJT_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
3605
3677
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
3606
3678
|
};
|
|
3607
3679
|
const kfs = [];
|
|
@@ -3663,7 +3735,7 @@ function followPath(opts) {
|
|
|
3663
3735
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
3664
3736
|
const segments = [];
|
|
3665
3737
|
let total = 0;
|
|
3666
|
-
for (const line of
|
|
3738
|
+
for (const line of chunkRQMI7EJT_cjs.flattenSvgPath(d)) {
|
|
3667
3739
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
3668
3740
|
for (let i = 2; i < p.length; i += 2) {
|
|
3669
3741
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -3688,7 +3760,7 @@ function followPath(opts) {
|
|
|
3688
3760
|
const t = Math.min(Math.max((s - g.start) / g.len, 0), 1);
|
|
3689
3761
|
return { x: g.x0 + (g.x1 - g.x0) * t, y: g.y0 + (g.y1 - g.y0) * t, heading: Math.atan2(g.y1 - g.y0, g.x1 - g.x0) * 180 / Math.PI };
|
|
3690
3762
|
};
|
|
3691
|
-
const shape =
|
|
3763
|
+
const shape = parseEase2(ease);
|
|
3692
3764
|
const round3 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3693
3765
|
let turn = 0;
|
|
3694
3766
|
const sample = (k) => {
|
|
@@ -3765,7 +3837,7 @@ function cameraPath(opts) {
|
|
|
3765
3837
|
const a = curve[i], b = curve[i + 1];
|
|
3766
3838
|
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
|
|
3767
3839
|
};
|
|
3768
|
-
const shape =
|
|
3840
|
+
const shape = parseEase2(ease);
|
|
3769
3841
|
const round3 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3770
3842
|
const sample = (k) => {
|
|
3771
3843
|
const p = from + (to - from) * shape(k / steps);
|
|
@@ -3807,7 +3879,7 @@ function stagger(items, options = {}) {
|
|
|
3807
3879
|
const dist2 = distances(n, from, grid, seed);
|
|
3808
3880
|
const max = dist2.reduce((m, d) => Math.max(m, d), 0);
|
|
3809
3881
|
const total = amount !== void 0 ? amount : (each ?? 0.1) * max;
|
|
3810
|
-
const shape =
|
|
3882
|
+
const shape = parseEase2(ease);
|
|
3811
3883
|
const clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
3812
3884
|
const delays = dist2.map((d) => max === 0 ? 0 : Math.round(total * clamp01(shape(d / max)) * 1e6) / 1e6);
|
|
3813
3885
|
if (isCount) return delays;
|
|
@@ -3817,7 +3889,7 @@ function distances(n, from, grid, seed) {
|
|
|
3817
3889
|
if (n === 0) return [];
|
|
3818
3890
|
if (from === "random") {
|
|
3819
3891
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
3820
|
-
const r =
|
|
3892
|
+
const r = chunkRQMI7EJT_cjs.random(seed);
|
|
3821
3893
|
for (let i = n - 1; i > 0; i--) {
|
|
3822
3894
|
const j = Math.floor(r() * (i + 1));
|
|
3823
3895
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -3879,7 +3951,7 @@ function wiggle(opts) {
|
|
|
3879
3951
|
to[n] = p.around;
|
|
3880
3952
|
return;
|
|
3881
3953
|
}
|
|
3882
|
-
const off = (
|
|
3954
|
+
const off = (chunkRQMI7EJT_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
3883
3955
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
3884
3956
|
});
|
|
3885
3957
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -4354,19 +4426,19 @@ function withFade(spec, opts) {
|
|
|
4354
4426
|
|
|
4355
4427
|
Object.defineProperty(exports, "noise", {
|
|
4356
4428
|
enumerable: true,
|
|
4357
|
-
get: function () { return
|
|
4429
|
+
get: function () { return chunkRQMI7EJT_cjs.noise; }
|
|
4358
4430
|
});
|
|
4359
4431
|
Object.defineProperty(exports, "rand", {
|
|
4360
4432
|
enumerable: true,
|
|
4361
|
-
get: function () { return
|
|
4433
|
+
get: function () { return chunkRQMI7EJT_cjs.rand; }
|
|
4362
4434
|
});
|
|
4363
4435
|
Object.defineProperty(exports, "random", {
|
|
4364
4436
|
enumerable: true,
|
|
4365
|
-
get: function () { return
|
|
4437
|
+
get: function () { return chunkRQMI7EJT_cjs.random; }
|
|
4366
4438
|
});
|
|
4367
4439
|
Object.defineProperty(exports, "registerSequenceType", {
|
|
4368
4440
|
enumerable: true,
|
|
4369
|
-
get: function () { return
|
|
4441
|
+
get: function () { return chunkRQMI7EJT_cjs.registerSequenceType; }
|
|
4370
4442
|
});
|
|
4371
4443
|
exports.Movie = Movie;
|
|
4372
4444
|
exports.animateText = animateText;
|
|
@@ -4376,6 +4448,7 @@ exports.cameraPath = cameraPath;
|
|
|
4376
4448
|
exports.computeEnvelope = computeEnvelope;
|
|
4377
4449
|
exports.deck = deck;
|
|
4378
4450
|
exports.dismissLoader = dismissLoader;
|
|
4451
|
+
exports.ease = parseEase2;
|
|
4379
4452
|
exports.failLoader = failLoader;
|
|
4380
4453
|
exports.followPath = followPath;
|
|
4381
4454
|
exports.kenBurns = kenBurns;
|