pixi-effects 0.3.0 → 0.5.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 +53 -0
- package/README.md +10 -6
- package/ai/SKILL.md +9 -4
- package/ai/reference/cheatsheet.md +19 -7
- package/ai/reference/pitfalls.md +32 -7
- package/ai/reference/recipes.md +117 -0
- package/ai/template.html +6 -3
- package/ai/tools/check.mjs +385 -0
- package/dist/{Base-BDw6dKRB.d.cts → Base-CPSFBkPm.d.ts} +12 -1
- package/dist/{Base-Ba4Ta4ap.d.ts → Base-DnRAxroQ.d.cts} +12 -1
- package/dist/Composition-63EXHNJJ.cjs +13 -0
- package/dist/{Composition-6FDH5OPM.cjs.map → Composition-63EXHNJJ.cjs.map} +1 -1
- package/dist/Composition-TUCRSMJU.js +4 -0
- package/dist/{Composition-FEYAUMFI.js.map → Composition-TUCRSMJU.js.map} +1 -1
- package/dist/Controller.cjs +37 -13
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +4 -2
- package/dist/Controller.d.ts +4 -2
- package/dist/Controller.js +37 -13
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-W8ISiEBB.d.cts → Movie-CuU_aaCm.d.cts} +56 -2
- package/dist/{Movie-DMpaT67V.d.ts → Movie-VyDiUYOj.d.ts} +56 -2
- package/dist/{chunk-ZL262ZRM.cjs → chunk-23M5QTWW.cjs} +70 -20
- package/dist/chunk-23M5QTWW.cjs.map +1 -0
- package/dist/{chunk-SIRVULFF.cjs → chunk-2RR43OIN.cjs} +256 -60
- package/dist/chunk-2RR43OIN.cjs.map +1 -0
- package/dist/{chunk-DIJG2RSF.js → chunk-5Q5XZG7Z.js} +59 -9
- package/dist/chunk-5Q5XZG7Z.js.map +1 -0
- package/dist/chunk-DKGG7WD4.js +61 -0
- package/dist/chunk-DKGG7WD4.js.map +1 -0
- package/dist/{chunk-PN5A6QA7.js → chunk-UBPZLGLU.js} +255 -61
- package/dist/chunk-UBPZLGLU.js.map +1 -0
- package/dist/chunk-UQBGW5DO.cjs +64 -0
- package/dist/chunk-UQBGW5DO.cjs.map +1 -0
- package/dist/index.cjs +336 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -5
- package/dist/index.d.ts +54 -5
- package/dist/index.js +320 -75
- package/dist/index.js.map +1 -1
- package/dist/sfx-MZJZXYY3.cjs +446 -0
- package/dist/sfx-MZJZXYY3.cjs.map +1 -0
- package/dist/sfx-S37DDC66.js +434 -0
- package/dist/sfx-S37DDC66.js.map +1 -0
- package/dist/three.cjs +5 -5
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +1 -1
- package/dist/{types-3c8Vymgw.d.ts → types-7VtTEKUW.d.cts} +102 -6
- package/dist/{types-3c8Vymgw.d.cts → types-7VtTEKUW.d.ts} +102 -6
- package/docs/api.md +36 -0
- package/docs/dsl.md +56 -4
- package/llms-full.txt +268 -21
- package/llms.txt +1 -1
- package/package.json +3 -1
- package/dist/Composition-6FDH5OPM.cjs +0 -13
- package/dist/Composition-FEYAUMFI.js +0 -4
- package/dist/chunk-DIJG2RSF.js.map +0 -1
- package/dist/chunk-PN5A6QA7.js.map +0 -1
- package/dist/chunk-SIRVULFF.cjs.map +0 -1
- package/dist/chunk-ZL262ZRM.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkUQBGW5DO_cjs = require('./chunk-UQBGW5DO.cjs');
|
|
4
|
+
var chunk23M5QTWW_cjs = require('./chunk-23M5QTWW.cjs');
|
|
5
|
+
var chunk2RR43OIN_cjs = require('./chunk-2RR43OIN.cjs');
|
|
5
6
|
var PIXI = require('pixi.js');
|
|
6
7
|
var gsap = require('gsap');
|
|
7
8
|
var PixiPlugin = require('gsap/PixiPlugin');
|
|
@@ -88,21 +89,213 @@ async function loadAssetBundle(assets, audioContext) {
|
|
|
88
89
|
async function mixdown(audios, totalDuration, sampleRate = 44100) {
|
|
89
90
|
if (audios.length === 0) return null;
|
|
90
91
|
const ctx = new OfflineAudioContext(2, Math.ceil(sampleRate * totalDuration), sampleRate);
|
|
92
|
+
const synthesised = /* @__PURE__ */ new Map();
|
|
93
|
+
const bufferOf = (a) => {
|
|
94
|
+
if (a.buffer) return a.buffer;
|
|
95
|
+
if (!a.synth) return null;
|
|
96
|
+
let buf = synthesised.get(a.synth.key);
|
|
97
|
+
if (!buf) {
|
|
98
|
+
const [left, right] = a.synth.render(sampleRate);
|
|
99
|
+
buf = ctx.createBuffer(2, left.length, sampleRate);
|
|
100
|
+
buf.getChannelData(0).set(left);
|
|
101
|
+
buf.getChannelData(1).set(right);
|
|
102
|
+
synthesised.set(a.synth.key, buf);
|
|
103
|
+
}
|
|
104
|
+
return buf;
|
|
105
|
+
};
|
|
91
106
|
for (const a of audios) {
|
|
107
|
+
const buffer = bufferOf(a);
|
|
108
|
+
if (!buffer) continue;
|
|
109
|
+
const begin = Math.max(0, a.start);
|
|
110
|
+
const skipped = begin - a.start;
|
|
111
|
+
if (skipped > 0) {
|
|
112
|
+
console.warn(
|
|
113
|
+
`pixi-effects: ${a.layer ?? "an audio layer"} starts at ${a.start.toFixed(2)}s, before the movie starts, so its first ${skipped.toFixed(2)}s are cut off. Start it at 0 or later.`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
92
116
|
const src = ctx.createBufferSource();
|
|
93
|
-
src.buffer =
|
|
117
|
+
src.buffer = buffer;
|
|
94
118
|
src.loop = !!a.loop;
|
|
95
119
|
const gain = ctx.createGain();
|
|
96
|
-
gain.gain.setValueAtTime(a.initialVolume ?? 1,
|
|
120
|
+
gain.gain.setValueAtTime(a.initialVolume ?? 1, begin);
|
|
97
121
|
for (const kf of a.volumeKeyframes ?? []) {
|
|
98
|
-
gain.gain.linearRampToValueAtTime(kf.value, kf.time);
|
|
122
|
+
gain.gain.linearRampToValueAtTime(kf.value, Math.max(0, kf.time));
|
|
99
123
|
}
|
|
100
124
|
src.connect(gain).connect(ctx.destination);
|
|
101
|
-
src.start(
|
|
102
|
-
src.stop(a.end);
|
|
125
|
+
src.start(begin, skipped);
|
|
126
|
+
src.stop(Math.max(begin, a.end));
|
|
103
127
|
}
|
|
104
128
|
return await ctx.startRendering();
|
|
105
129
|
}
|
|
130
|
+
var KNEE = 0.9;
|
|
131
|
+
function limitMix(buffer, audios) {
|
|
132
|
+
let peak = 0;
|
|
133
|
+
let peakIndex = 0;
|
|
134
|
+
for (let ch = 0; ch < buffer.numberOfChannels; ch++) {
|
|
135
|
+
const d = buffer.getChannelData(ch);
|
|
136
|
+
for (let i = 0; i < d.length; i++) {
|
|
137
|
+
const x = Math.abs(d[i]);
|
|
138
|
+
if (x > peak) {
|
|
139
|
+
peak = x;
|
|
140
|
+
peakIndex = i;
|
|
141
|
+
}
|
|
142
|
+
if (x > KNEE) d[i] = Math.sign(d[i]) * (KNEE + (1 - KNEE) * Math.tanh((x - KNEE) / (1 - KNEE)));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const peakAt = peakIndex / buffer.sampleRate;
|
|
146
|
+
if (peak > 1) {
|
|
147
|
+
const playing = audios.filter((a) => a.start <= peakAt && peakAt < a.end).map((a) => a.layer ?? "an audio layer");
|
|
148
|
+
console.warn(
|
|
149
|
+
`pixi-effects: the audio mix peaks at ${peak.toFixed(2)} (${(20 * Math.log10(peak)).toFixed(1)} dBFS) at ${peakAt.toFixed(2)}s, so it was limited (it would distort). Playing there: ${[...new Set(playing)].join(", ")}. Lower their volume.`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return { peak, peakAt };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/core/spectrum.ts
|
|
156
|
+
function fft(re, im) {
|
|
157
|
+
const n = re.length;
|
|
158
|
+
for (let i = 1, j = 0; i < n; i++) {
|
|
159
|
+
let bit = n >> 1;
|
|
160
|
+
for (; j & bit; bit >>= 1) j ^= bit;
|
|
161
|
+
j ^= bit;
|
|
162
|
+
if (i < j) {
|
|
163
|
+
[re[i], re[j]] = [re[j], re[i]];
|
|
164
|
+
[im[i], im[j]] = [im[j], im[i]];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (let len = 2; len <= n; len <<= 1) {
|
|
168
|
+
const ang = -2 * Math.PI / len;
|
|
169
|
+
for (let i = 0; i < n; i += len) {
|
|
170
|
+
for (let k = 0; k < len / 2; k++) {
|
|
171
|
+
const wr = Math.cos(ang * k), wi = Math.sin(ang * k);
|
|
172
|
+
const a = i + k, b = a + len / 2;
|
|
173
|
+
const xr = re[b] * wr - im[b] * wi, xi = re[b] * wi + im[b] * wr;
|
|
174
|
+
re[b] = re[a] - xr;
|
|
175
|
+
im[b] = im[a] - xi;
|
|
176
|
+
re[a] = re[a] + xr;
|
|
177
|
+
im[a] = im[a] + xi;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
var FRAME = 2048;
|
|
183
|
+
function spectralCentroid(samples, sampleRate, from = 0, to = samples.length) {
|
|
184
|
+
let num = 0;
|
|
185
|
+
let den = 0;
|
|
186
|
+
const re = new Float64Array(FRAME);
|
|
187
|
+
const im = new Float64Array(FRAME);
|
|
188
|
+
const end = Math.min(to, samples.length);
|
|
189
|
+
for (let start = Math.max(0, from); start < end; start += FRAME / 2) {
|
|
190
|
+
for (let i = 0; i < FRAME; i++) {
|
|
191
|
+
const k = start + i;
|
|
192
|
+
const w = 0.5 - 0.5 * Math.cos(2 * Math.PI * i / (FRAME - 1));
|
|
193
|
+
re[i] = k < end ? samples[k] * w : 0;
|
|
194
|
+
im[i] = 0;
|
|
195
|
+
}
|
|
196
|
+
fft(re, im);
|
|
197
|
+
for (let b = 1; b < FRAME / 2; b++) {
|
|
198
|
+
const power = re[b] * re[b] + im[b] * im[b];
|
|
199
|
+
num += power * (b * sampleRate / FRAME);
|
|
200
|
+
den += power;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return den > 1e-9 ? Math.round(num / den / 10) * 10 : 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/core/inspectAudio.ts
|
|
207
|
+
var INAUDIBLE_DB = -50;
|
|
208
|
+
var db = (x) => Math.round(10 * Math.max(-120, 20 * Math.log10(x))) / 10;
|
|
209
|
+
var mono = (chans) => {
|
|
210
|
+
if (chans.length === 1) return chans[0];
|
|
211
|
+
const out = new Float32Array(chans[0].length);
|
|
212
|
+
for (const d of chans) for (let i = 0; i < out.length; i++) out[i] = out[i] + d[i] / chans.length;
|
|
213
|
+
return out;
|
|
214
|
+
};
|
|
215
|
+
function measure(chans, sampleRate) {
|
|
216
|
+
let peak = 0;
|
|
217
|
+
let at = 0;
|
|
218
|
+
for (const d of chans) for (let i = 0; i < d.length; i++) if (Math.abs(d[i]) > peak) {
|
|
219
|
+
peak = Math.abs(d[i]);
|
|
220
|
+
at = i;
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
length: Math.round(chans[0].length / sampleRate * 1e3) / 1e3,
|
|
224
|
+
peakDb: db(peak),
|
|
225
|
+
loudestAt: Math.round(at / sampleRate * 1e3) / 1e3,
|
|
226
|
+
brightnessHz: spectralCentroid(mono(chans), sampleRate)
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function analyzeAudio(mix, sources, stats, movieDuration, opts = {}) {
|
|
230
|
+
if (!mix) {
|
|
231
|
+
return { duration: movieDuration, sampleRate: 0, peakDb: -120, peakAt: 0, sources: [], windows: [], issues: ['no audio: the movie has no audio layers (sound effects need no files: { type: "audio", sfx: "pop", at: 1 })'] };
|
|
232
|
+
}
|
|
233
|
+
const sr = mix.sampleRate;
|
|
234
|
+
const chans = Array.from({ length: mix.numberOfChannels }, (_, c) => mix.getChannelData(c));
|
|
235
|
+
const mixMono = mono(chans);
|
|
236
|
+
const peakIn = (t0, t1) => {
|
|
237
|
+
let p = 0;
|
|
238
|
+
const i1 = Math.min(mix.length, Math.ceil(t1 * sr));
|
|
239
|
+
for (const d of chans) for (let i = Math.max(0, Math.floor(t0 * sr)); i < i1; i++) p = Math.max(p, Math.abs(d[i]));
|
|
240
|
+
return p;
|
|
241
|
+
};
|
|
242
|
+
const win = opts.window && opts.window > 0 ? Math.max(0.01, opts.window) : 0.1;
|
|
243
|
+
const windows2 = [];
|
|
244
|
+
for (let t = 0; t < movieDuration - 1e-9; t += win) {
|
|
245
|
+
const i0 = Math.floor(t * sr);
|
|
246
|
+
const i1 = Math.min(mix.length, Math.floor((t + win) * sr));
|
|
247
|
+
let sum = 0;
|
|
248
|
+
let peak = 0;
|
|
249
|
+
for (const d of chans) {
|
|
250
|
+
for (let i = i0; i < i1; i++) {
|
|
251
|
+
sum += d[i] * d[i];
|
|
252
|
+
peak = Math.max(peak, Math.abs(d[i]));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const n = Math.max(1, (i1 - i0) * chans.length);
|
|
256
|
+
windows2.push({ t: Math.round(t * 1e3) / 1e3, rmsDb: db(Math.sqrt(sum / n)), peakDb: db(peak), brightnessHz: spectralCentroid(mixMono, sr, i0, i1) });
|
|
257
|
+
}
|
|
258
|
+
const issues = [];
|
|
259
|
+
if (stats && stats.peak > 1) {
|
|
260
|
+
issues.push(`the mix peaks at ${db(stats.peak)} dBFS at ${stats.peakAt.toFixed(2)}s and was limited \u2014 lower the volume of the layers playing there`);
|
|
261
|
+
}
|
|
262
|
+
const rendered = /* @__PURE__ */ new Map();
|
|
263
|
+
const soundOf = (s) => {
|
|
264
|
+
if (s.synth) {
|
|
265
|
+
let m = rendered.get(s.synth.key);
|
|
266
|
+
if (!m) rendered.set(s.synth.key, m = measure(s.synth.render(sr), sr));
|
|
267
|
+
return m;
|
|
268
|
+
}
|
|
269
|
+
const b = s.buffer;
|
|
270
|
+
return measure(Array.from({ length: b.numberOfChannels }, (_, c) => b.getChannelData(c)), b.sampleRate);
|
|
271
|
+
};
|
|
272
|
+
const list = [...sources].sort((a, b) => a.start - b.start).map((s) => {
|
|
273
|
+
const layer = s.layer ?? "an audio layer";
|
|
274
|
+
const source = s.source ?? "audio";
|
|
275
|
+
const peakDb = db(peakIn(s.start, Math.min(s.end, movieDuration)));
|
|
276
|
+
const sound = soundOf(s);
|
|
277
|
+
const topVolume = Math.max(s.initialVolume ?? 1, ...(s.volumeKeyframes ?? []).map((k) => k.value));
|
|
278
|
+
const ownDb = db(Math.pow(10, sound.peakDb / 20) * Math.max(0, topVolume));
|
|
279
|
+
if (s.start >= movieDuration) {
|
|
280
|
+
issues.push(`${layer} (${source}) starts at ${s.start.toFixed(2)}s, after the movie ends (${movieDuration}s)`);
|
|
281
|
+
} else if (ownDb < INAUDIBLE_DB || peakDb < INAUDIBLE_DB) {
|
|
282
|
+
issues.push(`${layer} (${source}) is inaudible from ${s.start.toFixed(2)}s to ${s.end.toFixed(2)}s (its own peak ${ownDb} dBFS at volume ${topVolume}; mix peak there ${peakDb} dBFS) \u2014 check its volume`);
|
|
283
|
+
}
|
|
284
|
+
if (s.synth && s.end > movieDuration + 1e-6 && s.start < movieDuration) {
|
|
285
|
+
issues.push(`${layer} (${source}) is cut off by the end of the movie at ${movieDuration}s (it runs to ${s.end.toFixed(2)}s)`);
|
|
286
|
+
}
|
|
287
|
+
return { layer, source, start: s.start, end: s.end, peakDb, sound };
|
|
288
|
+
});
|
|
289
|
+
return {
|
|
290
|
+
duration: movieDuration,
|
|
291
|
+
sampleRate: sr,
|
|
292
|
+
peakDb: db(stats?.peak ?? peakIn(0, movieDuration)),
|
|
293
|
+
peakAt: stats?.peakAt ?? 0,
|
|
294
|
+
sources: list,
|
|
295
|
+
windows: windows2,
|
|
296
|
+
issues
|
|
297
|
+
};
|
|
298
|
+
}
|
|
106
299
|
var VIDEO_CODEC_BY_FORMAT = {
|
|
107
300
|
mp4: "avc",
|
|
108
301
|
mov: "avc",
|
|
@@ -160,7 +353,7 @@ async function exportFrames(movie, options = {}) {
|
|
|
160
353
|
const audioSource = new mediabunny.AudioBufferSource({
|
|
161
354
|
codec: opts.audio.codec,
|
|
162
355
|
bitrate: opts.audio.bitrate
|
|
163
|
-
});
|
|
356
|
+
}, { startTimestamp: opts.audio.codec === "aac" ? -2112 / movie.audioBuffer.sampleRate : 0 });
|
|
164
357
|
output.addAudioTrack(audioSource);
|
|
165
358
|
await output.start();
|
|
166
359
|
await audioSource.add(movie.audioBuffer);
|
|
@@ -521,6 +714,15 @@ var TransitionMaskFilter = class extends PIXI.Filter {
|
|
|
521
714
|
};
|
|
522
715
|
|
|
523
716
|
// src/core/Transitions.ts
|
|
717
|
+
var windows = /* @__PURE__ */ new WeakMap();
|
|
718
|
+
function transitionWindowsOf(spec) {
|
|
719
|
+
return windows.get(spec) ?? [];
|
|
720
|
+
}
|
|
721
|
+
function carryTransitionWindows(from, to) {
|
|
722
|
+
const w = windows.get(from);
|
|
723
|
+
if (w) windows.set(to, w);
|
|
724
|
+
return to;
|
|
725
|
+
}
|
|
524
726
|
function expandTransitions(spec) {
|
|
525
727
|
const out = {
|
|
526
728
|
...spec,
|
|
@@ -617,20 +819,23 @@ function expandTransitions(spec) {
|
|
|
617
819
|
if (toUses > 1) {
|
|
618
820
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
619
821
|
}
|
|
620
|
-
const tStart =
|
|
822
|
+
const tStart = chunk2RR43OIN_cjs.resolveAt(t.at, parentDuration);
|
|
621
823
|
const tEnd = tStart + t.duration;
|
|
622
824
|
const fromSeq = fromEntry.seq;
|
|
623
|
-
const fromStart =
|
|
825
|
+
const fromStart = chunk2RR43OIN_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
624
826
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
625
827
|
if (tStart < fromStart || tEnd > fromEnd) {
|
|
626
828
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
627
829
|
}
|
|
628
830
|
const toSeq = toEntry.seq;
|
|
629
|
-
const toStart =
|
|
831
|
+
const toStart = chunk2RR43OIN_cjs.resolveAt(toSeq.at, parentDuration);
|
|
630
832
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
631
833
|
if (tStart < toStart || tEnd > toEnd) {
|
|
632
834
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
633
835
|
}
|
|
836
|
+
const record = windows.get(out) ?? [];
|
|
837
|
+
record.push({ from: t.from, to: t.to, start: tStart, end: tEnd });
|
|
838
|
+
windows.set(out, record);
|
|
634
839
|
const abs = { ...t, at: tStart };
|
|
635
840
|
const nFrom = keyframeCount(fromEntry.seq);
|
|
636
841
|
const nTo = keyframeCount(toEntry.seq);
|
|
@@ -924,10 +1129,26 @@ var intersection = (a, b) => {
|
|
|
924
1129
|
const h = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
925
1130
|
return w > 0 && h > 0 ? w * h : 0;
|
|
926
1131
|
};
|
|
1132
|
+
var clip = (a, b) => {
|
|
1133
|
+
const x = Math.max(a.x, b.x), y = Math.max(a.y, b.y);
|
|
1134
|
+
const w = Math.min(a.x + a.width, b.x + b.width) - x, h = Math.min(a.y + a.height, b.y + b.height) - y;
|
|
1135
|
+
return w > 0 && h > 0 ? { x, y, width: w, height: h } : null;
|
|
1136
|
+
};
|
|
927
1137
|
function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
928
1138
|
const layers = [];
|
|
929
1139
|
const view = { x: 0, y: 0, width: canvas.width, height: canvas.height };
|
|
930
|
-
const
|
|
1140
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1141
|
+
const scene = /* @__PURE__ */ new Map();
|
|
1142
|
+
const scaledToNothing = /* @__PURE__ */ new Set();
|
|
1143
|
+
const walk = (comp, prefix, insideThreeD, parentVisible, parentScene, parentMoving = false, parentZero = false) => {
|
|
1144
|
+
const blending = /* @__PURE__ */ new Set();
|
|
1145
|
+
for (const w of transitionWindowsOf(comp.spec)) {
|
|
1146
|
+
const start = (comp.absoluteStart ?? 0) + w.start, end = (comp.absoluteStart ?? 0) + w.end;
|
|
1147
|
+
if (time >= start - 1e-9 && time <= end + 1e-9) {
|
|
1148
|
+
blending.add(w.from);
|
|
1149
|
+
blending.add(w.to);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
931
1152
|
comp.layers().forEach(({ seq, display, threeD }, i) => {
|
|
932
1153
|
const t = seq.target;
|
|
933
1154
|
const name = seq.spec.name;
|
|
@@ -947,10 +1168,23 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
947
1168
|
onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
|
|
948
1169
|
if (area === 0) onCanvas = "none";
|
|
949
1170
|
}
|
|
950
|
-
const keys =
|
|
951
|
-
const moving = (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
|
|
952
|
-
|
|
953
|
-
|
|
1171
|
+
const keys = chunk2RR43OIN_cjs.collectPropKeys(seq.spec);
|
|
1172
|
+
const moving = parentMoving || (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
|
|
1173
|
+
const scale = t?.scale;
|
|
1174
|
+
const zero = parentZero || !!scale && (scale.x === 0 || scale.y === 0);
|
|
1175
|
+
const info = { path: prefix + label, name, type: seq.spec.type, threeD, visible, alpha, moving, bounds, onCanvas };
|
|
1176
|
+
layers.push(info);
|
|
1177
|
+
let shown = bounds ? clip(bounds, view) : null;
|
|
1178
|
+
const maskTarget = seq.maskSequence?.target;
|
|
1179
|
+
if (shown && maskTarget && !seq.spec.maskInverted) {
|
|
1180
|
+
const m = maskTarget.getBounds();
|
|
1181
|
+
shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
|
|
1182
|
+
}
|
|
1183
|
+
seen.set(info, shown);
|
|
1184
|
+
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1185
|
+
if (group) scene.set(info, group);
|
|
1186
|
+
if (zero) scaledToNothing.add(info);
|
|
1187
|
+
if (seq instanceof chunk23M5QTWW_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible, group, moving, zero);
|
|
954
1188
|
});
|
|
955
1189
|
};
|
|
956
1190
|
walk(root, "", false, true);
|
|
@@ -960,8 +1194,9 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
960
1194
|
const b = l.bounds;
|
|
961
1195
|
const who = `text layer "${l.path}"`;
|
|
962
1196
|
if (b.width < 1 || b.height < 1) {
|
|
1197
|
+
if (scaledToNothing.has(l)) continue;
|
|
963
1198
|
issues.push(`${who} has no size (empty text, or not drawn yet)`);
|
|
964
|
-
} else if (l.moving) ; else if (l.onCanvas === "none") {
|
|
1199
|
+
} else if (l.moving || scene.has(l)) ; else if (l.onCanvas === "none") {
|
|
965
1200
|
issues.push(`${who} is entirely outside the canvas (at ${Math.round(b.x)},${Math.round(b.y)}, ${Math.round(b.width)}\xD7${Math.round(b.height)})`);
|
|
966
1201
|
} else if (l.onCanvas === "partial") {
|
|
967
1202
|
const over = [];
|
|
@@ -974,7 +1209,10 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
974
1209
|
}
|
|
975
1210
|
for (let i = 0; i < texts.length; i++) {
|
|
976
1211
|
for (let j = i + 1; j < texts.length; j++) {
|
|
977
|
-
const a = texts[i]
|
|
1212
|
+
const a = seen.get(texts[i]), b = seen.get(texts[j]);
|
|
1213
|
+
if (!a || !b) continue;
|
|
1214
|
+
const sa = scene.get(texts[i]), sb = scene.get(texts[j]);
|
|
1215
|
+
if (sa && sb && sa !== sb) continue;
|
|
978
1216
|
const smaller = Math.min(a.width * a.height, b.width * b.height);
|
|
979
1217
|
if (smaller <= 0) continue;
|
|
980
1218
|
const share = intersection(a, b) / smaller;
|
|
@@ -1006,64 +1244,6 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
|
1006
1244
|
return { cols, rows, cellW, cellH, width: cols * cellW, height: rows * (cellH + labelH), positions };
|
|
1007
1245
|
}
|
|
1008
1246
|
|
|
1009
|
-
// src/core/options.ts
|
|
1010
|
-
function distance(a, b) {
|
|
1011
|
-
const dp = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);
|
|
1012
|
-
for (let j = 1; j <= b.length; j++) dp[0][j] = j;
|
|
1013
|
-
for (let i = 1; i <= a.length; i++) {
|
|
1014
|
-
for (let j = 1; j <= b.length; j++) {
|
|
1015
|
-
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
1016
|
-
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + 1);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
return dp[a.length][b.length];
|
|
1020
|
-
}
|
|
1021
|
-
var isSubsequence = (small, big) => {
|
|
1022
|
-
let i = 0;
|
|
1023
|
-
for (const ch of big) if (i < small.length && ch === small[i]) i++;
|
|
1024
|
-
return i === small.length;
|
|
1025
|
-
};
|
|
1026
|
-
var COMMON_ALIASES = {
|
|
1027
|
-
fps: "frameRate",
|
|
1028
|
-
framerate: "frameRate",
|
|
1029
|
-
frame_rate: "frameRate",
|
|
1030
|
-
bg: "background",
|
|
1031
|
-
backgroundcolor: "background",
|
|
1032
|
-
bgcolor: "background",
|
|
1033
|
-
seconds: "duration",
|
|
1034
|
-
length: "duration",
|
|
1035
|
-
time: "duration",
|
|
1036
|
-
w: "width",
|
|
1037
|
-
h: "height",
|
|
1038
|
-
cols: "columns",
|
|
1039
|
-
sweep: "degrees",
|
|
1040
|
-
angle: "degrees"
|
|
1041
|
-
};
|
|
1042
|
-
function suggestName(name, valid) {
|
|
1043
|
-
const n = name.toLowerCase();
|
|
1044
|
-
const alias = COMMON_ALIASES[n];
|
|
1045
|
-
if (alias && valid.includes(alias)) return alias;
|
|
1046
|
-
let best = null;
|
|
1047
|
-
for (const v of valid) {
|
|
1048
|
-
const lv = v.toLowerCase();
|
|
1049
|
-
const d = distance(n, lv);
|
|
1050
|
-
const close = d <= Math.max(1, Math.floor(Math.min(n.length, lv.length) / 3));
|
|
1051
|
-
const abbreviation = n.length >= 3 && isSubsequence(n, lv) || lv.length >= 2 && n.length > lv.length && n.includes(lv);
|
|
1052
|
-
if (!close && !abbreviation) continue;
|
|
1053
|
-
const score = close ? d : 3 + (lv.length - n.length) / 100;
|
|
1054
|
-
if (!best || score < best.score) best = { v, score };
|
|
1055
|
-
}
|
|
1056
|
-
return best ? best.v : null;
|
|
1057
|
-
}
|
|
1058
|
-
function warnUnknownOptions(where, opts, valid) {
|
|
1059
|
-
if (!opts || typeof opts !== "object") return;
|
|
1060
|
-
for (const key of Object.keys(opts)) {
|
|
1061
|
-
if (valid.includes(key)) continue;
|
|
1062
|
-
const guess = suggestName(key, valid);
|
|
1063
|
-
console.warn(`pixi-effects: ${where}: unknown option "${key}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (valid: ${valid.join(", ")})`);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
1247
|
// src/core/Movie.ts
|
|
1068
1248
|
PIXI.extensions.add(PIXI.CullerPlugin);
|
|
1069
1249
|
gsap.gsap.registerPlugin(PixiPlugin.PixiPlugin);
|
|
@@ -1090,6 +1270,9 @@ var Movie = class {
|
|
|
1090
1270
|
_rootSequence = null;
|
|
1091
1271
|
_rootContainer = null;
|
|
1092
1272
|
_raf = null;
|
|
1273
|
+
/** What went into the mix, and its peak before limiting — kept for inspectAudio(). */
|
|
1274
|
+
_audioSources = [];
|
|
1275
|
+
_mixStats = null;
|
|
1093
1276
|
on(event, fn) {
|
|
1094
1277
|
(this._events[event] ??= []).push(fn);
|
|
1095
1278
|
if (event === "ready" && this._initState === "ready") {
|
|
@@ -1122,7 +1305,7 @@ var Movie = class {
|
|
|
1122
1305
|
return this._audioContext;
|
|
1123
1306
|
}
|
|
1124
1307
|
async init(options = {}) {
|
|
1125
|
-
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition"]);
|
|
1308
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition"]);
|
|
1126
1309
|
this._initState = "pending";
|
|
1127
1310
|
try {
|
|
1128
1311
|
this.width = options.width ?? 1920;
|
|
@@ -1174,7 +1357,8 @@ var Movie = class {
|
|
|
1174
1357
|
duration: this.duration,
|
|
1175
1358
|
...userComposition
|
|
1176
1359
|
};
|
|
1177
|
-
|
|
1360
|
+
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
1361
|
+
const composition = new chunk23M5QTWW_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
1178
1362
|
await composition.build();
|
|
1179
1363
|
this._rootSequence = composition;
|
|
1180
1364
|
if (composition.target) root.addChild(composition.target);
|
|
@@ -1183,7 +1367,9 @@ var Movie = class {
|
|
|
1183
1367
|
composition.collectAudio(audios, 0);
|
|
1184
1368
|
if (audios.length > 0) {
|
|
1185
1369
|
this.audioBuffer = await mixdown(audios, this.duration, audioContext.sampleRate);
|
|
1370
|
+
if (this.audioBuffer) this._mixStats = limitMix(this.audioBuffer, audios);
|
|
1186
1371
|
}
|
|
1372
|
+
this._audioSources = audios;
|
|
1187
1373
|
this.timeline.progress(1).progress(0);
|
|
1188
1374
|
await this._awaitVideoFrames();
|
|
1189
1375
|
this._updateSpace();
|
|
@@ -1221,7 +1407,7 @@ var Movie = class {
|
|
|
1221
1407
|
}));
|
|
1222
1408
|
}
|
|
1223
1409
|
async snapshot(frame = this.currentFrame, opts = {}) {
|
|
1224
|
-
warnUnknownOptions("movie.snapshot()", opts, ["scale", "type", "as"]);
|
|
1410
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.snapshot()", opts, ["scale", "type", "as"]);
|
|
1225
1411
|
this._requireReady("snapshot");
|
|
1226
1412
|
await this.gotoFrame(clampFrame(frame, this.totalFrames), true);
|
|
1227
1413
|
const scale = opts.scale ?? 1;
|
|
@@ -1232,7 +1418,7 @@ var Movie = class {
|
|
|
1232
1418
|
return encodeCanvas(out, opts.type ?? "image/png", opts.as ?? "blob");
|
|
1233
1419
|
}
|
|
1234
1420
|
async contactSheet(opts = {}) {
|
|
1235
|
-
warnUnknownOptions("movie.contactSheet()", opts, ["frames", "times", "count", "columns", "cellWidth", "as"]);
|
|
1421
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.contactSheet()", opts, ["frames", "times", "count", "columns", "cellWidth", "as"]);
|
|
1236
1422
|
this._requireReady("contactSheet");
|
|
1237
1423
|
const frames = (opts.frames ?? opts.times?.map((t) => Math.round(t * this.frameRate)) ?? pickFrames(this.totalFrames, opts.count ?? 6)).map((f) => clampFrame(f, this.totalFrames));
|
|
1238
1424
|
const LABEL_H = 26;
|
|
@@ -1265,12 +1451,21 @@ var Movie = class {
|
|
|
1265
1451
|
* the canvas, cut by an edge, empty, or overlapping other text. Seeks there and stays there.
|
|
1266
1452
|
*/
|
|
1267
1453
|
async inspect(frame = this.currentFrame, opts = { layers: "visible" }) {
|
|
1268
|
-
warnUnknownOptions("movie.inspect()", opts, ["layers"]);
|
|
1454
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.inspect()", opts, ["layers"]);
|
|
1269
1455
|
this._requireReady("inspect");
|
|
1270
1456
|
const f = clampFrame(frame, this.totalFrames);
|
|
1271
1457
|
await this.gotoFrame(f, true);
|
|
1272
1458
|
return inspectScene(this._rootSequence, f, f / this.frameRate, { width: this.width, height: this.height }, opts);
|
|
1273
1459
|
}
|
|
1460
|
+
/**
|
|
1461
|
+
* The soundtrack, measured: when every audio layer plays, how loud the mix is over time, and `issues`
|
|
1462
|
+
* (limiting, inaudible layers, sounds cut off by the end). Use it to CHECK sound you cannot hear.
|
|
1463
|
+
*/
|
|
1464
|
+
inspectAudio(opts = {}) {
|
|
1465
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.inspectAudio()", opts, ["window"]);
|
|
1466
|
+
this._requireReady("inspectAudio");
|
|
1467
|
+
return analyzeAudio(this.audioBuffer, this._audioSources, this._mixStats, this.duration, opts);
|
|
1468
|
+
}
|
|
1274
1469
|
/**
|
|
1275
1470
|
* Draw the stage now. PixiJS's CullerPlugin only culls inside `app.render()` (the ticker), and we render
|
|
1276
1471
|
* by hand — while seeking and especially during `render()`, which stops the ticker — so without this the
|
|
@@ -1281,6 +1476,7 @@ var Movie = class {
|
|
|
1281
1476
|
_renderNow() {
|
|
1282
1477
|
const app = this.app;
|
|
1283
1478
|
if (!app?.renderer) return;
|
|
1479
|
+
this._rootSequence?.syncFrame();
|
|
1284
1480
|
PIXI.Culler.shared.cull(app.stage, app.renderer.screen, false);
|
|
1285
1481
|
app.renderer.render({ container: app.stage });
|
|
1286
1482
|
}
|
|
@@ -1374,7 +1570,7 @@ var Movie = class {
|
|
|
1374
1570
|
return this.muted;
|
|
1375
1571
|
}
|
|
1376
1572
|
async render(options) {
|
|
1377
|
-
warnUnknownOptions("movie.render()", options, ["format", "video", "audio"]);
|
|
1573
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.render()", options, ["format", "video", "audio"]);
|
|
1378
1574
|
return await exportFrames(this, options);
|
|
1379
1575
|
}
|
|
1380
1576
|
async destroy() {
|
|
@@ -1386,6 +1582,8 @@ var Movie = class {
|
|
|
1386
1582
|
safeRun(() => this.app?.destroy(true, { children: true, texture: true }));
|
|
1387
1583
|
this.app = null;
|
|
1388
1584
|
this.audioBuffer = null;
|
|
1585
|
+
this._audioSources = [];
|
|
1586
|
+
this._mixStats = null;
|
|
1389
1587
|
safeRun(() => this._audioContext?.close().catch(() => {
|
|
1390
1588
|
}));
|
|
1391
1589
|
this._audioContext = null;
|
|
@@ -1413,11 +1611,58 @@ function collectVideoSequences(seq, out) {
|
|
|
1413
1611
|
collectVideoSequences(child, out);
|
|
1414
1612
|
}
|
|
1415
1613
|
}
|
|
1614
|
+
var BY = ["chars", "words", "lines"];
|
|
1615
|
+
var ALIGN = ["left", "center", "right"];
|
|
1616
|
+
var widthOf = (text, style) => PIXI.CanvasTextMetrics.measureText(text, style).width;
|
|
1617
|
+
function measureText(text, style = {}) {
|
|
1618
|
+
const m = PIXI.CanvasTextMetrics.measureText(text, new PIXI.TextStyle(style));
|
|
1619
|
+
return { width: m.width, height: m.height, lines: text.split("\n").length };
|
|
1620
|
+
}
|
|
1621
|
+
function splitText(text, style = {}, opts = {}) {
|
|
1622
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("splitText()", opts, ["by", "x", "y", "align"]);
|
|
1623
|
+
let by = opts.by ?? "chars";
|
|
1624
|
+
if (!BY.includes(by)) {
|
|
1625
|
+
const g = chunkUQBGW5DO_cjs.suggestName(String(by), BY);
|
|
1626
|
+
console.warn(`pixi-effects: splitText(): by "${by}" is not one of ${BY.map((b) => `"${b}"`).join(", ")}${g ? ` \u2014 did you mean "${g}"?` : ""}; using "chars"`);
|
|
1627
|
+
by = "chars";
|
|
1628
|
+
}
|
|
1629
|
+
let align = opts.align ?? "left";
|
|
1630
|
+
if (!ALIGN.includes(align)) {
|
|
1631
|
+
const g = chunkUQBGW5DO_cjs.suggestName(String(align), ALIGN);
|
|
1632
|
+
console.warn(`pixi-effects: splitText(): align "${align}" is not one of ${ALIGN.join(", ")}${g ? ` \u2014 did you mean "${g}"?` : ""}; using "left"`);
|
|
1633
|
+
align = "left";
|
|
1634
|
+
}
|
|
1635
|
+
const x0 = opts.x ?? 0, y0 = opts.y ?? 0;
|
|
1636
|
+
if (text === "") return [];
|
|
1637
|
+
const ts = new PIXI.TextStyle(style);
|
|
1638
|
+
const lineHeight = PIXI.CanvasTextMetrics.measureText("M", ts).lineHeight ?? PIXI.CanvasTextMetrics.measureText("M", ts).height;
|
|
1639
|
+
const sentinel = widthOf("|", ts);
|
|
1640
|
+
const out = [];
|
|
1641
|
+
text.split("\n").forEach((line, lineNo) => {
|
|
1642
|
+
const lineWidth = widthOf(line, ts);
|
|
1643
|
+
const left = align === "center" ? x0 - lineWidth / 2 : align === "right" ? x0 - lineWidth : x0;
|
|
1644
|
+
const y = y0 + lineNo * lineHeight;
|
|
1645
|
+
const advance = (upTo) => upTo === 0 ? 0 : widthOf(line.slice(0, upTo) + "|", ts) - sentinel;
|
|
1646
|
+
const spans = [];
|
|
1647
|
+
if (by === "lines") {
|
|
1648
|
+
if (line.trim() !== "") spans.push([0, line.length]);
|
|
1649
|
+
} else if (by === "words") {
|
|
1650
|
+
for (const m of line.matchAll(/\S+/g)) spans.push([m.index, m.index + m[0].length]);
|
|
1651
|
+
} else {
|
|
1652
|
+
for (let i = 0; i < line.length; i++) if (!/\s/.test(line[i])) spans.push([i, i + 1]);
|
|
1653
|
+
}
|
|
1654
|
+
for (const [a, b] of spans) {
|
|
1655
|
+
const piece = line.slice(a, b);
|
|
1656
|
+
out.push({ text: piece, x: left + advance(a), y, width: widthOf(piece, ts), index: out.length, line: lineNo });
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
return out;
|
|
1660
|
+
}
|
|
1416
1661
|
|
|
1417
1662
|
// src/presets/kenBurns.ts
|
|
1418
1663
|
var KEN_BURNS_KEYS = ["asset", "name", "at", "duration", "fit", "ease", "motion", "origin", "zoom", "direction", "angle", "from", "to"];
|
|
1419
1664
|
function kenBurns(opts) {
|
|
1420
|
-
warnUnknownOptions("kenBurns()", opts, KEN_BURNS_KEYS);
|
|
1665
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("kenBurns()", opts, KEN_BURNS_KEYS);
|
|
1421
1666
|
const {
|
|
1422
1667
|
asset,
|
|
1423
1668
|
name,
|
|
@@ -1533,7 +1778,7 @@ function parseEase(name) {
|
|
|
1533
1778
|
// src/presets/orbit.ts
|
|
1534
1779
|
var ORBIT_KEYS = ["duration", "degrees", "start", "radius", "center", "width", "height", "fov", "ease", "dollyZoom", "at", "name", "stepsPerSecond"];
|
|
1535
1780
|
function orbit(opts) {
|
|
1536
|
-
warnUnknownOptions("orbit()", opts, ORBIT_KEYS);
|
|
1781
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("orbit()", opts, ORBIT_KEYS);
|
|
1537
1782
|
const {
|
|
1538
1783
|
duration,
|
|
1539
1784
|
degrees,
|
|
@@ -1549,17 +1794,17 @@ function orbit(opts) {
|
|
|
1549
1794
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
1550
1795
|
}
|
|
1551
1796
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
1552
|
-
const fixedR = opts.radius ??
|
|
1797
|
+
const fixedR = opts.radius ?? chunk2RR43OIN_cjs.homeDistance(height, fov ?? chunk2RR43OIN_cjs.DEFAULT_FOV);
|
|
1553
1798
|
const start = opts.start ?? -degrees / 2;
|
|
1554
1799
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
1555
1800
|
const easeFn = parseEase(ease);
|
|
1556
1801
|
const dollyEase = dolly ? parseEase(dolly.ease ?? ease) : null;
|
|
1557
1802
|
const pos = (i) => {
|
|
1558
1803
|
const p = i / steps;
|
|
1559
|
-
const a = (start + degrees * easeFn(p)) *
|
|
1804
|
+
const a = (start + degrees * easeFn(p)) * chunk2RR43OIN_cjs.DEG;
|
|
1560
1805
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
1561
1806
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
1562
|
-
const R =
|
|
1807
|
+
const R = chunk2RR43OIN_cjs.homeDistance(height, f);
|
|
1563
1808
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
1564
1809
|
};
|
|
1565
1810
|
const keyframes = [];
|
|
@@ -1588,7 +1833,7 @@ function orbit(opts) {
|
|
|
1588
1833
|
|
|
1589
1834
|
// src/transforms/withFade.ts
|
|
1590
1835
|
function withFade(spec, opts) {
|
|
1591
|
-
warnUnknownOptions("withFade()", opts, ["in", "out"]);
|
|
1836
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("withFade()", opts, ["in", "out"]);
|
|
1592
1837
|
if (opts.in != null && opts.in > 0) {
|
|
1593
1838
|
spec.initial = { ...spec.initial ?? {}, alpha: 0 };
|
|
1594
1839
|
const kf = { at: 0, to: { alpha: 1 }, duration: opts.in };
|
|
@@ -1608,11 +1853,13 @@ function withFade(spec, opts) {
|
|
|
1608
1853
|
|
|
1609
1854
|
Object.defineProperty(exports, "registerSequenceType", {
|
|
1610
1855
|
enumerable: true,
|
|
1611
|
-
get: function () { return
|
|
1856
|
+
get: function () { return chunk2RR43OIN_cjs.registerSequenceType; }
|
|
1612
1857
|
});
|
|
1613
1858
|
exports.Movie = Movie;
|
|
1614
1859
|
exports.kenBurns = kenBurns;
|
|
1860
|
+
exports.measureText = measureText;
|
|
1615
1861
|
exports.orbit = orbit;
|
|
1862
|
+
exports.splitText = splitText;
|
|
1616
1863
|
exports.withFade = withFade;
|
|
1617
1864
|
//# sourceMappingURL=index.cjs.map
|
|
1618
1865
|
//# sourceMappingURL=index.cjs.map
|