pixi-effects 0.35.0 → 0.36.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 +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +26 -7
- package/ai/tools/lookup.mjs +14 -2
- package/dist/{Base-CXsMdmJB.d.ts → Base-CdF7AJop.d.ts} +1 -1
- package/dist/{Base-pNq6sVGl.d.cts → Base-CmiFiwQM.d.cts} +1 -1
- package/dist/Composition-BMRCE5FH.js +7 -0
- package/dist/{Composition-NDXKQHB4.js.map → Composition-BMRCE5FH.js.map} +1 -1
- package/dist/Composition-XRLYR6GL.cjs +16 -0
- package/dist/{Composition-OLH7RC5Z.cjs.map → Composition-XRLYR6GL.cjs.map} +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/{Movie-VYtUN4TS.d.ts → Movie-Bh1HPdKw.d.cts} +6 -1
- package/dist/{Movie-Db4QnMIH.d.cts → Movie-D5WFfZdZ.d.ts} +6 -1
- package/dist/{Spans-QRMN2EZO.cjs → Spans-4IRBSOLI.cjs} +11 -11
- package/dist/{Spans-QRMN2EZO.cjs.map → Spans-4IRBSOLI.cjs.map} +1 -1
- package/dist/{Spans-QHHWC2PB.js → Spans-MWP2FX3T.js} +6 -6
- package/dist/{Spans-QHHWC2PB.js.map → Spans-MWP2FX3T.js.map} +1 -1
- package/dist/{blendModes-WIUCYIMC.cjs → blendModes-KU7XLV7U.cjs} +5 -5
- package/dist/{blendModes-WIUCYIMC.cjs.map → blendModes-KU7XLV7U.cjs.map} +1 -1
- package/dist/{blendModes-PP5NPBXY.js → blendModes-OOI3T6BE.js} +4 -4
- package/dist/{blendModes-PP5NPBXY.js.map → blendModes-OOI3T6BE.js.map} +1 -1
- package/dist/{chunk-ITDYFBB6.js → chunk-2JFFKHXO.js} +5 -5
- package/dist/chunk-2JFFKHXO.js.map +1 -0
- package/dist/{chunk-GL2AQFLQ.cjs → chunk-42ML5AKN.cjs} +5 -5
- package/dist/chunk-42ML5AKN.cjs.map +1 -0
- package/dist/{chunk-XV4L72FW.js → chunk-AZ6AINSW.js} +5 -5
- package/dist/{chunk-XV4L72FW.js.map → chunk-AZ6AINSW.js.map} +1 -1
- package/dist/{chunk-7TTCPHAV.cjs → chunk-CC7SUR7Q.cjs} +153 -48
- package/dist/chunk-CC7SUR7Q.cjs.map +1 -0
- package/dist/{chunk-Y253JQOH.js → chunk-G3DX65HO.js} +110 -10
- package/dist/chunk-G3DX65HO.js.map +1 -0
- package/dist/{chunk-LEECUCTG.cjs → chunk-KJSEQVBV.cjs} +129 -29
- package/dist/chunk-KJSEQVBV.cjs.map +1 -0
- package/dist/{chunk-IMQJVRMT.cjs → chunk-NEUPEENI.cjs} +5 -5
- package/dist/{chunk-IMQJVRMT.cjs.map → chunk-NEUPEENI.cjs.map} +1 -1
- package/dist/{chunk-2GNK6DPV.js → chunk-VF56PRAA.js} +121 -16
- package/dist/chunk-VF56PRAA.js.map +1 -0
- package/dist/{chunk-RTJD3ZSW.js → chunk-WIIU42FH.js} +4 -4
- package/dist/{chunk-RTJD3ZSW.js.map → chunk-WIIU42FH.js.map} +1 -1
- package/dist/{chunk-5IJENZOG.cjs → chunk-Y5UWFH6Y.cjs} +91 -91
- package/dist/{chunk-5IJENZOG.cjs.map → chunk-Y5UWFH6Y.cjs.map} +1 -1
- package/dist/index.cjs +33 -33
- package/dist/index.d.cts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +5 -5
- package/dist/loader.css +1 -1
- package/dist/present.cjs +5 -5
- package/dist/present.d.cts +2 -2
- package/dist/present.d.ts +2 -2
- package/dist/present.js +5 -5
- package/dist/three.cjs +6 -6
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +2 -2
- package/dist/{types-CavnUvd5.d.ts → types-B6zDTU2V.d.cts} +14 -1
- package/dist/{types-CavnUvd5.d.cts → types-B6zDTU2V.d.ts} +14 -1
- package/docs/api.md +5 -4
- package/docs/dsl.md +7 -5
- package/llms-full.txt +85 -18
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +3 -3
- package/skills/pixi-effects/reference/cheatsheet.md +7 -6
- package/skills/pixi-effects/reference/pitfalls.md +3 -0
- package/skills/pixi-effects/reference/recipes.md +60 -0
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-NDXKQHB4.js +0 -7
- package/dist/Composition-OLH7RC5Z.cjs +0 -16
- package/dist/chunk-2GNK6DPV.js.map +0 -1
- package/dist/chunk-7TTCPHAV.cjs.map +0 -1
- package/dist/chunk-GL2AQFLQ.cjs.map +0 -1
- package/dist/chunk-ITDYFBB6.js.map +0 -1
- package/dist/chunk-LEECUCTG.cjs.map +0 -1
- package/dist/chunk-Y253JQOH.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkY5UWFH6Y_cjs = require('./chunk-Y5UWFH6Y.cjs');
|
|
4
|
+
var chunkKJSEQVBV_cjs = require('./chunk-KJSEQVBV.cjs');
|
|
5
|
+
var chunkNEUPEENI_cjs = require('./chunk-NEUPEENI.cjs');
|
|
6
6
|
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
7
7
|
var pixi_js = require('pixi.js');
|
|
8
8
|
var mediabunny = require('mediabunny');
|
|
@@ -392,6 +392,7 @@ function findSilences(channels, sampleRate, opts = {}) {
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
// src/core/inspectAudio.ts
|
|
395
|
+
var BURIED_DB = 12;
|
|
395
396
|
var INAUDIBLE_DB = -50;
|
|
396
397
|
var db = (x) => Math.round(10 * Math.max(-120, 20 * Math.log10(x))) / 10;
|
|
397
398
|
var mono = (chans) => {
|
|
@@ -477,6 +478,7 @@ function analyzeAudio(mix, sources, stats, movieDuration, opts = {}) {
|
|
|
477
478
|
return measure(Array.from({ length: b.numberOfChannels }, (_, c) => b.getChannelData(c)), b.sampleRate);
|
|
478
479
|
};
|
|
479
480
|
const scoreNotes = [];
|
|
481
|
+
const buried = [];
|
|
480
482
|
const list = [...sources].sort((a, b) => a.start - b.start).map((s) => {
|
|
481
483
|
const layer = s.layer ?? "an audio layer";
|
|
482
484
|
const source = s.source ?? "audio";
|
|
@@ -504,8 +506,22 @@ function analyzeAudio(mix, sources, stats, movieDuration, opts = {}) {
|
|
|
504
506
|
const over = s.music.seconds - plays;
|
|
505
507
|
if (over > 2 && over / s.music.seconds > 0.15) scoreNotes.push(`${layer} (${source}): the score is ${Math.round(s.music.seconds * 10) / 10}s long but only ${Math.round(plays * 100) / 100}s of it play, so it is cut off mid-phrase. Write fewer bars (or a faster tempo) so it ends with the movie`);
|
|
506
508
|
}
|
|
507
|
-
|
|
509
|
+
let belowMixDb;
|
|
510
|
+
if (!clock && !s.sourceMap && s.start < movieDuration && ownDb > INAUDIBLE_DB) {
|
|
511
|
+
const at = s.start + sound.loudestAt;
|
|
512
|
+
const around = db(peakIn(Math.max(0, at - 0.05), Math.min(movieDuration, at + 0.05)));
|
|
513
|
+
belowMixDb = Math.max(0, Math.round((around - ownDb) * 10) / 10);
|
|
514
|
+
if (!s.music && source.startsWith("sfx") && sound.length <= 4 && belowMixDb >= BURIED_DB) {
|
|
515
|
+
buried.push({ layer, source, ownDb, topVolume, around, belowMixDb, at: Math.round(at * 100) / 100 });
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return { layer, source, start: s.start, end: s.end, peakDb, sound, ...belowMixDb !== void 0 ? { belowMixDb } : {}, ...s.music ? { music: s.music } : {} };
|
|
508
519
|
});
|
|
520
|
+
if (buried.length > 0) {
|
|
521
|
+
const worst = buried.reduce((a, b) => b.belowMixDb > a.belowMixDb ? b : a);
|
|
522
|
+
const names = new Set(buried.map((x) => x.layer + x.source));
|
|
523
|
+
scoreNotes.push(`${names.size === 1 ? "1 sound effect is" : `${names.size} sound effects are`} buried (${BURIED_DB} dB or more under the loudest sample of the mix around its loudest moment${buried.length > names.size ? `, ${buried.length} times in all` : ""}): the worst is ${worst.layer} (${worst.source}), its own peak ${worst.ownDb} dBFS at volume ${worst.topVolume} against ${worst.around} dBFS at ${worst.at} s, ${worst.belowMixDb} dB louder. If it is meant to be heard, raise its volume (an accent over music needs 2 to 3) or lower what plays there; every source's belowMixDb has its own number`);
|
|
524
|
+
}
|
|
509
525
|
const whole = measureLoudness(chans, sr);
|
|
510
526
|
const silences = findSilences(chans, sr, { minLength: 1 });
|
|
511
527
|
if (whole.clippedSamples > 0) issues.push(`${whole.clippedSamples} sample(s) of the mix are at full scale (clipped) \u2014 lower the volume of the layers that play loudest`);
|
|
@@ -1490,8 +1506,8 @@ function expandTransitions(spec) {
|
|
|
1490
1506
|
}
|
|
1491
1507
|
const transitions = out.transitions;
|
|
1492
1508
|
const sequences = out.sequences ?? [];
|
|
1493
|
-
const remap = out.duration !== void 0 ?
|
|
1494
|
-
const parentDuration = remap ?
|
|
1509
|
+
const remap = out.duration !== void 0 ? chunkKJSEQVBV_cjs.timeRemapOf(out) : null;
|
|
1510
|
+
const parentDuration = remap ? chunkKJSEQVBV_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
|
|
1495
1511
|
const compW = out.width;
|
|
1496
1512
|
const compH = out.height;
|
|
1497
1513
|
const threeDByName = new Set(sequences.filter((s) => s.name && s.threeD).map((s) => s.name));
|
|
@@ -1559,16 +1575,16 @@ function expandTransitions(spec) {
|
|
|
1559
1575
|
if (toUses > 1) {
|
|
1560
1576
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
1561
1577
|
}
|
|
1562
|
-
const tStart =
|
|
1578
|
+
const tStart = chunkKJSEQVBV_cjs.resolveAt(t.at, parentDuration);
|
|
1563
1579
|
const tEnd = tStart + t.duration;
|
|
1564
1580
|
const fromSeq = fromEntry.seq;
|
|
1565
|
-
const fromStart =
|
|
1581
|
+
const fromStart = chunkKJSEQVBV_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
1566
1582
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
1567
1583
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
1568
1584
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
1569
1585
|
}
|
|
1570
1586
|
const toSeq = toEntry.seq;
|
|
1571
|
-
const toStart =
|
|
1587
|
+
const toStart = chunkKJSEQVBV_cjs.resolveAt(toSeq.at, parentDuration);
|
|
1572
1588
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
1573
1589
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
1574
1590
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
@@ -1628,7 +1644,7 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
1628
1644
|
delete inner.at;
|
|
1629
1645
|
delete inner.duration;
|
|
1630
1646
|
const m = inner.mask;
|
|
1631
|
-
const carriesMatte = m !== void 0 &&
|
|
1647
|
+
const carriesMatte = m !== void 0 && chunkY5UWFH6Y_cjs.maskSourceOf(m).kind === "refs";
|
|
1632
1648
|
if (carriesMatte) delete inner.mask;
|
|
1633
1649
|
return {
|
|
1634
1650
|
...carriesMatte ? { mask: m } : {},
|
|
@@ -1884,6 +1900,20 @@ function rejectReservedNameCollision(filters, seqName) {
|
|
|
1884
1900
|
}
|
|
1885
1901
|
|
|
1886
1902
|
// src/core/inspect.ts
|
|
1903
|
+
function chainOf(node) {
|
|
1904
|
+
const chain = [];
|
|
1905
|
+
for (let n = node; n && n.parent; n = n.parent) {
|
|
1906
|
+
const i = n.parent.children?.indexOf(n);
|
|
1907
|
+
if (i === void 0 || i < 0) return null;
|
|
1908
|
+
chain.unshift(i);
|
|
1909
|
+
}
|
|
1910
|
+
return chain.length ? chain : null;
|
|
1911
|
+
}
|
|
1912
|
+
function drawnAfter(a, b) {
|
|
1913
|
+
if (!a || !b) return null;
|
|
1914
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) if (a[i] !== b[i]) return a[i] > b[i];
|
|
1915
|
+
return null;
|
|
1916
|
+
}
|
|
1887
1917
|
var FAINT = 0.3;
|
|
1888
1918
|
var intersection = (a, b) => {
|
|
1889
1919
|
const w = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
@@ -1907,8 +1937,8 @@ function motionOf(keyframes, local, lives, keys = (k) => GEOMETRY.has(k)) {
|
|
|
1907
1937
|
let length = 0;
|
|
1908
1938
|
if (typeof kf.duration === "number") length = kf.duration;
|
|
1909
1939
|
else if (kf.duration === "auto") {
|
|
1910
|
-
const sp =
|
|
1911
|
-
length = sp ? Math.round(
|
|
1940
|
+
const sp = chunkKJSEQVBV_cjs.parseSpring(kf.ease);
|
|
1941
|
+
length = sp ? Math.round(chunkKJSEQVBV_cjs.springDuration(sp) * 1e3) / 1e3 : 0.5;
|
|
1912
1942
|
}
|
|
1913
1943
|
if (!(length > 0)) continue;
|
|
1914
1944
|
const kat = kf.at ?? 0;
|
|
@@ -1927,7 +1957,11 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1927
1957
|
const scene = /* @__PURE__ */ new Map();
|
|
1928
1958
|
const scaledToNothing = /* @__PURE__ */ new Set();
|
|
1929
1959
|
const hasMotion = /* @__PURE__ */ new Set();
|
|
1930
|
-
const
|
|
1960
|
+
const kinds = /* @__PURE__ */ new Map();
|
|
1961
|
+
const specs = /* @__PURE__ */ new Map();
|
|
1962
|
+
const chains = /* @__PURE__ */ new Map();
|
|
1963
|
+
const chainAlpha = /* @__PURE__ */ new Map();
|
|
1964
|
+
const walk2 = (comp, prefix, insideThreeD, parentVisible, parentScene, parentMotion = NO_MOTION, parentZero = false, parentAlpha = 1) => {
|
|
1931
1965
|
const blending = /* @__PURE__ */ new Set();
|
|
1932
1966
|
const now = comp.childTime(time);
|
|
1933
1967
|
const cameraMotion = (comp.spec.sequences ?? []).filter((q) => q.type === "camera").reduce((m, q) => either(m, motionOf(q.keyframes, now - comp.childBase - (q.at ?? 0), q.duration ?? comp.duration ?? Infinity, () => true)), NO_MOTION);
|
|
@@ -1971,10 +2005,14 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1971
2005
|
if (threeD) info.depthBlur = Number(depthBlur.toFixed(2));
|
|
1972
2006
|
if (threeD && light !== void 0) info.light = Number(light.toFixed(2));
|
|
1973
2007
|
layers.push(info);
|
|
2008
|
+
chainAlpha.set(info, parentAlpha * alpha);
|
|
2009
|
+
chains.set(info, chainOf(display));
|
|
2010
|
+
specs.set(info, seq.spec);
|
|
2011
|
+
kinds.set(info, seq.spec.type === "shape" ? String(seq.spec.shape) : seq.spec.type);
|
|
1974
2012
|
if (motion.ever) hasMotion.add(info);
|
|
1975
2013
|
let shown = bounds ? clip(bounds, view) : null;
|
|
1976
2014
|
const maskTarget = seq.maskSequence?.target;
|
|
1977
|
-
const maskSrc =
|
|
2015
|
+
const maskSrc = chunkY5UWFH6Y_cjs.maskSourceOf(seq.spec.mask);
|
|
1978
2016
|
if (shown && maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert)) {
|
|
1979
2017
|
const m = maskTarget.getBounds();
|
|
1980
2018
|
shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
|
|
@@ -1983,7 +2021,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1983
2021
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1984
2022
|
if (group) scene.set(info, group);
|
|
1985
2023
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1986
|
-
if (seq instanceof
|
|
2024
|
+
if (seq instanceof chunkY5UWFH6Y_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
|
|
1987
2025
|
});
|
|
1988
2026
|
};
|
|
1989
2027
|
walk2(root, "", false, true);
|
|
@@ -2019,6 +2057,42 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
2019
2057
|
if (share > 0.25) issues.push(`text layers "${texts[i].path}" and "${texts[j].path}" overlap by ${Math.round(share * 100)}% of the smaller one`);
|
|
2020
2058
|
}
|
|
2021
2059
|
}
|
|
2060
|
+
const FILLED = /* @__PURE__ */ new Set(["rect", "circle", "ellipse", "image", "video"]);
|
|
2061
|
+
for (const t of texts) {
|
|
2062
|
+
const tb = seen.get(t);
|
|
2063
|
+
if (!tb) continue;
|
|
2064
|
+
const area = tb.width * tb.height;
|
|
2065
|
+
if (!(area > 0)) continue;
|
|
2066
|
+
for (const o of layers) {
|
|
2067
|
+
if (o === t || o.type === "text" || !o.visible || !o.bounds) continue;
|
|
2068
|
+
if (o.path.startsWith(t.path + "/") || t.path.startsWith(o.path + "/")) continue;
|
|
2069
|
+
const kind = kinds.get(o) ?? o.type, spec = specs.get(o) ?? {};
|
|
2070
|
+
const initial = spec.initial ?? {};
|
|
2071
|
+
const hairline = (kind === "line" || kind === "rect") && Math.min(o.bounds.width, o.bounds.height) < 12 && Math.max(o.bounds.width, o.bounds.height) >= 40;
|
|
2072
|
+
const soft = spec.blendMode !== void 0 && spec.blendMode !== "normal" || Array.isArray(spec.filters) && spec.filters.length > 0;
|
|
2073
|
+
const filled = kind === "image" || kind === "video" || initial.fillColor !== void 0 || spec.fillGradient !== void 0 || initial.fillGradient !== void 0;
|
|
2074
|
+
if (o.threeD || t.threeD) continue;
|
|
2075
|
+
const over = drawnAfter(chains.get(o) ?? null, chains.get(t) ?? null) ?? layers.indexOf(o) > layers.indexOf(t);
|
|
2076
|
+
const opacity = chainAlpha.get(o) ?? o.alpha;
|
|
2077
|
+
const hides = FILLED.has(kind) && !hairline && filled && !soft && over && opacity >= 0.8;
|
|
2078
|
+
const cuts = hairline && !soft && over && opacity >= FAINT;
|
|
2079
|
+
if (!hides && !cuts) continue;
|
|
2080
|
+
const st = scene.get(t), so = scene.get(o);
|
|
2081
|
+
if (st && so && st !== so) continue;
|
|
2082
|
+
const ob = seen.get(o);
|
|
2083
|
+
if (!ob) continue;
|
|
2084
|
+
const covered = intersection(tb, ob) / area;
|
|
2085
|
+
if (cuts) {
|
|
2086
|
+
const horizontal = ob.width >= ob.height;
|
|
2087
|
+
const mid = horizontal ? ob.y + ob.height / 2 : ob.x + ob.width / 2;
|
|
2088
|
+
const lo = horizontal ? tb.y + tb.height * 0.2 : tb.x + tb.width * 0.2, hi = horizontal ? tb.y + tb.height * 0.8 : tb.x + tb.width * 0.8;
|
|
2089
|
+
const along = horizontal ? Math.min(ob.x + ob.width, tb.x + tb.width) - Math.max(ob.x, tb.x) : Math.min(ob.y + ob.height, tb.y + tb.height) - Math.max(ob.y, tb.y);
|
|
2090
|
+
if (mid < lo || mid > hi || along < 0.3 * (horizontal ? tb.width : tb.height)) continue;
|
|
2091
|
+
} else if (covered < 0.1) continue;
|
|
2092
|
+
const word = kind === "image" || kind === "video" ? kind : "shape";
|
|
2093
|
+
issues.push(`text layer "${t.path}" and ${word} layer "${o.path}" overlap: it covers ${Math.round(covered * 100)}% of the text (drawn ${over ? "over" : "under"} it)`);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2022
2096
|
const mode = opts.layers ?? "all";
|
|
2023
2097
|
const listed = mode === "none" ? [] : mode === "visible" ? layers.filter((l) => l.visible) : layers;
|
|
2024
2098
|
return { frame, time, canvas, summary: { layers: layers.length, visible: layers.filter((l) => l.visible).length }, issues, layers: listed };
|
|
@@ -2031,7 +2105,7 @@ var round = (n) => Math.round(n * 1e6) / 1e6;
|
|
|
2031
2105
|
var family = (name) => name.replace(/\d+/g, "#");
|
|
2032
2106
|
function detailOf(seq) {
|
|
2033
2107
|
const s = seq.spec;
|
|
2034
|
-
const spans =
|
|
2108
|
+
const spans = chunkKJSEQVBV_cjs.spansMeta.get(seq.spec)?.preview;
|
|
2035
2109
|
if (spans) return spans.length > 60 ? spans.slice(0, 57) + "\u2026" : spans;
|
|
2036
2110
|
if (typeof s.text === "string") return s.text.length > 60 ? s.text.slice(0, 57) + "\u2026" : s.text;
|
|
2037
2111
|
if (typeof s.asset === "string") return `asset \u201C${s.asset}\u201D`;
|
|
@@ -2047,10 +2121,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
|
|
|
2047
2121
|
const start = parentStart + (seq.at ?? 0);
|
|
2048
2122
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
2049
2123
|
const span = end - start;
|
|
2050
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
2124
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkKJSEQVBV_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
2051
2125
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
|
|
2052
2126
|
const inner = [];
|
|
2053
|
-
const isComp = seq instanceof
|
|
2127
|
+
const isComp = seq instanceof chunkY5UWFH6Y_cjs.CompositionSequence;
|
|
2054
2128
|
if (isComp) {
|
|
2055
2129
|
const label = seq.remapLabel();
|
|
2056
2130
|
walk(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
@@ -2209,7 +2283,7 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
|
2209
2283
|
}
|
|
2210
2284
|
|
|
2211
2285
|
// src/core/vars.ts
|
|
2212
|
-
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...
|
|
2286
|
+
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunkKJSEQVBV_cjs.EXPRESSION_NAMES];
|
|
2213
2287
|
var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2214
2288
|
var isPlain = (v) => !!v && typeof v === "object" && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
2215
2289
|
function normalizeVars(raw, where, warn = (m) => console.warn(m)) {
|
|
@@ -2748,8 +2822,8 @@ var Movie = class {
|
|
|
2748
2822
|
this.stops = normalizeStops(applyVars(options.composition, this._vars)?.stops, this.duration, this.frameRate);
|
|
2749
2823
|
this._posterFrame = poster.frame;
|
|
2750
2824
|
this.background = options.background ?? "#000000";
|
|
2751
|
-
this.timeline =
|
|
2752
|
-
|
|
2825
|
+
this.timeline = chunkKJSEQVBV_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2826
|
+
chunkKJSEQVBV_cjs.lengthen(this.timeline, this.duration);
|
|
2753
2827
|
const baseAppOptions = {
|
|
2754
2828
|
width: this.width,
|
|
2755
2829
|
height: this.height,
|
|
@@ -2843,8 +2917,8 @@ var Movie = class {
|
|
|
2843
2917
|
height: sizeWins ? height : spec.height ?? height,
|
|
2844
2918
|
duration: spec.duration ?? this.duration
|
|
2845
2919
|
} : void 0;
|
|
2846
|
-
await
|
|
2847
|
-
if (
|
|
2920
|
+
await chunkKJSEQVBV_cjs.ensureFilterLibrary(seededComposition);
|
|
2921
|
+
if (chunkNEUPEENI_cjs.usesAdvancedBlend(seededComposition)) await chunkNEUPEENI_cjs.enableAdvancedBlend(this.app.renderer);
|
|
2848
2922
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
2849
2923
|
const rootSeqSpec = {
|
|
2850
2924
|
type: "composition",
|
|
@@ -2854,7 +2928,7 @@ var Movie = class {
|
|
|
2854
2928
|
...userComposition
|
|
2855
2929
|
};
|
|
2856
2930
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
2857
|
-
const sequence = new
|
|
2931
|
+
const sequence = new chunkY5UWFH6Y_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
2858
2932
|
lp?.begin("build", countLayers(rootSeqSpec));
|
|
2859
2933
|
try {
|
|
2860
2934
|
await sequence.build();
|
|
@@ -2990,8 +3064,8 @@ var Movie = class {
|
|
|
2990
3064
|
if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
|
|
2991
3065
|
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged);
|
|
2992
3066
|
alive();
|
|
2993
|
-
const timeline =
|
|
2994
|
-
|
|
3067
|
+
const timeline = chunkKJSEQVBV_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
3068
|
+
chunkKJSEQVBV_cjs.lengthen(timeline, this.duration);
|
|
2995
3069
|
sequence.bindTimeline(timeline);
|
|
2996
3070
|
const hadSound = this.audioBuffer !== null;
|
|
2997
3071
|
const audio = await this._mixSound(sequence, this._ensureAudioContext());
|
|
@@ -3705,7 +3779,7 @@ function countLayers(spec) {
|
|
|
3705
3779
|
n += 1 + countLayers(s);
|
|
3706
3780
|
const spans = s.spans;
|
|
3707
3781
|
if (Array.isArray(spans)) n += spans.length;
|
|
3708
|
-
const src =
|
|
3782
|
+
const src = chunkY5UWFH6Y_cjs.maskSourceOf(mask);
|
|
3709
3783
|
if (src.kind === "inline") n += 1 + countLayers(src.spec);
|
|
3710
3784
|
}
|
|
3711
3785
|
return n;
|
|
@@ -3718,7 +3792,7 @@ function measureText(text, style = {}) {
|
|
|
3718
3792
|
return { width: m.width, height: m.height, lines: text.split("\n").length };
|
|
3719
3793
|
}
|
|
3720
3794
|
function splitText(text, style = {}, opts = {}) {
|
|
3721
|
-
chunkTWZNOUM7_cjs.warnUnknownOptions("splitText()", opts, ["by", "x", "y", "align"]);
|
|
3795
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("splitText()", opts, ["by", "x", "y", "align", "vertical"]);
|
|
3722
3796
|
let by = opts.by ?? "chars";
|
|
3723
3797
|
if (!BY.includes(by)) {
|
|
3724
3798
|
const g = chunkTWZNOUM7_cjs.suggestName(String(by), BY);
|
|
@@ -3737,6 +3811,7 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3737
3811
|
}
|
|
3738
3812
|
if (text === "") return [];
|
|
3739
3813
|
const ts = new pixi_js.TextStyle(style);
|
|
3814
|
+
if (opts.vertical) return splitVertical(text, style, ts, x0, y0, align, by);
|
|
3740
3815
|
const lineHeight = pixi_js.CanvasTextMetrics.measureText("M", ts).lineHeight ?? pixi_js.CanvasTextMetrics.measureText("M", ts).height;
|
|
3741
3816
|
const sentinel = widthOf("|", ts);
|
|
3742
3817
|
const out = [];
|
|
@@ -3760,11 +3835,41 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3760
3835
|
});
|
|
3761
3836
|
return out;
|
|
3762
3837
|
}
|
|
3838
|
+
var PUNCT = new Set("\u3001\u3002\uFF0C\uFF0E\uFF64\uFF61");
|
|
3839
|
+
var SMALL = new Set("\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308E\u30A1\u30A3\u30A5\u30A7\u30A9\u30C3\u30E3\u30E5\u30E7\u30EE\u30F5\u30F6");
|
|
3840
|
+
var TURNED = new Set("\u30FC\u2015\u2014\uFF0D\uFF5E\u301C\u2026\u2025\uFF08\uFF09()\uFF3B\uFF3D[]\uFF5B\uFF5D{}\u300C\u300D\u300E\u300F\u3008\u3009\u300A\u300B\u3010\u3011\u3014\u3015<>\u226A\u226B");
|
|
3841
|
+
function splitVertical(text, style, ts, right, top, align, by) {
|
|
3842
|
+
if (by !== "chars") console.warn(`pixi-effects: splitText(): vertical text has only a "chars" form (by "${by}" has no vertical layout); using "chars"`);
|
|
3843
|
+
const em = typeof style.fontSize === "number" ? style.fontSize : Number(ts.fontSize) || 26;
|
|
3844
|
+
const spacing = typeof style.letterSpacing === "number" ? style.letterSpacing : 0;
|
|
3845
|
+
const cell = em + spacing;
|
|
3846
|
+
const lineHeight = pixi_js.CanvasTextMetrics.measureText("M", ts).lineHeight ?? pixi_js.CanvasTextMetrics.measureText("M", ts).height;
|
|
3847
|
+
const out = [];
|
|
3848
|
+
text.split("\n").forEach((line, lineNo) => {
|
|
3849
|
+
const chars = Array.from(line);
|
|
3850
|
+
const start = align === "center" ? top - chars.length * cell / 2 : align === "right" ? top - chars.length * cell : top;
|
|
3851
|
+
const column = right - lineHeight / 2 - lineNo * lineHeight;
|
|
3852
|
+
chars.forEach((ch, i) => {
|
|
3853
|
+
if (/\s/.test(ch)) return;
|
|
3854
|
+
let cx = column, cy = start + i * cell + cell / 2;
|
|
3855
|
+
if (PUNCT.has(ch)) {
|
|
3856
|
+
cx += 0.5 * em;
|
|
3857
|
+
cy -= 0.5 * em;
|
|
3858
|
+
} else if (SMALL.has(ch)) {
|
|
3859
|
+
cx += 0.1 * em;
|
|
3860
|
+
cy -= 0.1 * em;
|
|
3861
|
+
}
|
|
3862
|
+
const width = widthOf(ch, ts);
|
|
3863
|
+
out.push({ text: ch, x: cx - width / 2, y: cy - lineHeight / 2, width, index: out.length, line: lineNo, cx, cy, rotation: TURNED.has(ch) ? 90 : 0 });
|
|
3864
|
+
});
|
|
3865
|
+
});
|
|
3866
|
+
return out;
|
|
3867
|
+
}
|
|
3763
3868
|
|
|
3764
3869
|
// src/presets/_ease.ts
|
|
3765
3870
|
function parseEase2(name) {
|
|
3766
|
-
|
|
3767
|
-
return
|
|
3871
|
+
chunkKJSEQVBV_cjs.checkEase(name, "a preset");
|
|
3872
|
+
return chunkKJSEQVBV_cjs.parseEase(name);
|
|
3768
3873
|
}
|
|
3769
3874
|
|
|
3770
3875
|
// src/presets/kenBurns.ts
|
|
@@ -3899,17 +4004,17 @@ function orbit(opts) {
|
|
|
3899
4004
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
3900
4005
|
}
|
|
3901
4006
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
3902
|
-
const fixedR = opts.radius ??
|
|
4007
|
+
const fixedR = opts.radius ?? chunkKJSEQVBV_cjs.homeDistance(height, fov ?? chunkKJSEQVBV_cjs.DEFAULT_FOV);
|
|
3903
4008
|
const start = opts.start ?? -degrees / 2;
|
|
3904
4009
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
3905
4010
|
const easeFn = parseEase2(ease);
|
|
3906
4011
|
const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
|
|
3907
4012
|
const pos = (i) => {
|
|
3908
4013
|
const p = i / steps;
|
|
3909
|
-
const a = (start + degrees * easeFn(p)) *
|
|
4014
|
+
const a = (start + degrees * easeFn(p)) * chunkKJSEQVBV_cjs.DEG;
|
|
3910
4015
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
3911
4016
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
3912
|
-
const R =
|
|
4017
|
+
const R = chunkKJSEQVBV_cjs.homeDistance(height, f);
|
|
3913
4018
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
3914
4019
|
};
|
|
3915
4020
|
const keyframes = [];
|
|
@@ -3964,7 +4069,7 @@ function particles(opts) {
|
|
|
3964
4069
|
const round2 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3965
4070
|
const out = [];
|
|
3966
4071
|
for (let i = 0; i < count; i++) {
|
|
3967
|
-
const r =
|
|
4072
|
+
const r = chunkKJSEQVBV_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
3968
4073
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
3969
4074
|
const born = at + r() * emit;
|
|
3970
4075
|
const lifetime = pick(life);
|
|
@@ -3977,7 +4082,7 @@ function particles(opts) {
|
|
|
3977
4082
|
const turn = spin ? pick(spin) : 0;
|
|
3978
4083
|
const startAngle = spin ? r() * 360 : 0;
|
|
3979
4084
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
3980
|
-
const n0 = sway ?
|
|
4085
|
+
const n0 = sway ? chunkKJSEQVBV_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
3981
4086
|
const at_ = (t) => {
|
|
3982
4087
|
const axis = (p0, v0, acc) => {
|
|
3983
4088
|
if (drag > 0) {
|
|
@@ -3986,7 +4091,7 @@ function particles(opts) {
|
|
|
3986
4091
|
}
|
|
3987
4092
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
3988
4093
|
};
|
|
3989
|
-
const sw = sway ? swayAmp * (
|
|
4094
|
+
const sw = sway ? swayAmp * (chunkKJSEQVBV_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
3990
4095
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
3991
4096
|
};
|
|
3992
4097
|
const kfs = [];
|
|
@@ -4048,7 +4153,7 @@ function followPath(opts) {
|
|
|
4048
4153
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
4049
4154
|
const segments = [];
|
|
4050
4155
|
let total = 0;
|
|
4051
|
-
for (const line of
|
|
4156
|
+
for (const line of chunkKJSEQVBV_cjs.flattenSvgPath(d)) {
|
|
4052
4157
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
4053
4158
|
for (let i = 2; i < p.length; i += 2) {
|
|
4054
4159
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -4202,7 +4307,7 @@ function distances(n, from, grid, seed) {
|
|
|
4202
4307
|
if (n === 0) return [];
|
|
4203
4308
|
if (from === "random") {
|
|
4204
4309
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
4205
|
-
const r =
|
|
4310
|
+
const r = chunkKJSEQVBV_cjs.random(seed);
|
|
4206
4311
|
for (let i = n - 1; i > 0; i--) {
|
|
4207
4312
|
const j = Math.floor(r() * (i + 1));
|
|
4208
4313
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -4264,7 +4369,7 @@ function wiggle(opts) {
|
|
|
4264
4369
|
to[n] = p.around;
|
|
4265
4370
|
return;
|
|
4266
4371
|
}
|
|
4267
|
-
const off = (
|
|
4372
|
+
const off = (chunkKJSEQVBV_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
4268
4373
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
4269
4374
|
});
|
|
4270
4375
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -4275,7 +4380,7 @@ function wiggle(opts) {
|
|
|
4275
4380
|
// src/presets/animateText.ts
|
|
4276
4381
|
var TWEEN_KEYS = ["preset", "from", "to", "duration", "ease"];
|
|
4277
4382
|
var TIME_KEYS = ["at", "delay", "start", "begin", "time"];
|
|
4278
|
-
var KEYS5 = ["by", "x", "y", "align", "name", "at", "duration", "in", "out", "stagger", "idle", "styleFor"];
|
|
4383
|
+
var KEYS5 = ["by", "x", "y", "align", "vertical", "name", "at", "duration", "in", "out", "stagger", "idle", "styleFor"];
|
|
4279
4384
|
var PRESETS = {
|
|
4280
4385
|
rise: { from: { y: 40, alpha: 0 }, duration: 0.5, ease: "back.out(2)" },
|
|
4281
4386
|
drop: { from: { y: -50, alpha: 0 }, duration: 0.7, ease: "bounce.out" },
|
|
@@ -4288,14 +4393,14 @@ var PRESETS = {
|
|
|
4288
4393
|
var PRESET_NAMES = Object.keys(PRESETS);
|
|
4289
4394
|
function animateText(text, style, options) {
|
|
4290
4395
|
chunkTWZNOUM7_cjs.warnUnknownOptions("animateText()", options, KEYS5);
|
|
4291
|
-
const { by = "chars", x = 0, y = 0, align = "left", name = "text", at = 0, duration, idle, styleFor } = options;
|
|
4396
|
+
const { by = "chars", x = 0, y = 0, align = "left", vertical = false, name = "text", at = 0, duration, idle, styleFor } = options;
|
|
4292
4397
|
for (const [n, v] of [["x", x], ["y", y]]) {
|
|
4293
4398
|
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
4294
4399
|
throw new Error(`animateText(): ${n} must be a number of pixels (e.g. ${n}: 640), got ${JSON.stringify(v)}. The letters are measured once, when the layers are made, so an expression such as 'GW/2' cannot be used here: compute the number (W / 2) yourself. \`y\` is the TOP of the line.`);
|
|
4295
4400
|
}
|
|
4296
4401
|
}
|
|
4297
4402
|
if (!(Number.isFinite(duration) && duration > 0)) throw new Error(`animateText(): duration must be a positive number of seconds (how long until the last piece is gone), got ${duration}`);
|
|
4298
|
-
const pieces = splitText(text, style, { by, x, y, align });
|
|
4403
|
+
const pieces = splitText(text, style, { by, x, y, align, ...vertical ? { vertical } : {} });
|
|
4299
4404
|
if (pieces.length === 0) return [];
|
|
4300
4405
|
const lineHeight = measureText("M", style).height;
|
|
4301
4406
|
const inTween = options.in === false ? null : resolveTween(options.in ?? "rise", "in");
|
|
@@ -4314,12 +4419,12 @@ function animateText(text, style, options) {
|
|
|
4314
4419
|
if (inTween && outTween.at - at < inTween.duration - 1e-9) console.warn(`pixi-effects: animateText(): out.at ${outTween.at} is before the entrance has finished (it takes ${inTween.duration} s from at ${at}): use out.at \u2265 ${+(at + inTween.duration).toFixed(3)}`);
|
|
4315
4420
|
}
|
|
4316
4421
|
return pieces.map((p, i) => {
|
|
4317
|
-
const cx = p.x + p.width / 2, cy = p.y + lineHeight / 2;
|
|
4318
|
-
const rest = { x: cx, y: cy, alpha: 1, scale: 1, scaleX: 1, scaleY: 1, rotation: 0 };
|
|
4422
|
+
const cx = p.cx ?? p.x + p.width / 2, cy = p.cy ?? p.y + lineHeight / 2;
|
|
4423
|
+
const rest = { x: cx, y: cy, alpha: 1, scale: 1, scaleX: 1, scaleY: 1, rotation: p.rotation ?? 0 };
|
|
4319
4424
|
const start = at + delays[i];
|
|
4320
4425
|
const len = end - start;
|
|
4321
4426
|
const keyframes = [];
|
|
4322
|
-
const place = (key, v) => key === "x" || key === "y" ? rest[key] + v : v;
|
|
4427
|
+
const place = (key, v) => key === "x" || key === "y" || key === "rotation" ? rest[key] + v : v;
|
|
4323
4428
|
if (inTween) {
|
|
4324
4429
|
keyframes.push({
|
|
4325
4430
|
at: 0,
|
|
@@ -4358,7 +4463,7 @@ function animateText(text, style, options) {
|
|
|
4358
4463
|
style: styleFor ? { ...style, ...styleFor(p) } : style,
|
|
4359
4464
|
at: start,
|
|
4360
4465
|
duration: len,
|
|
4361
|
-
initial: { x: cx, y: cy, anchorX: 0.5, anchorY: 0.5 },
|
|
4466
|
+
initial: { x: cx, y: cy, anchorX: 0.5, anchorY: 0.5, ...rest.rotation !== 0 ? { rotation: rest.rotation } : {} },
|
|
4362
4467
|
keyframes
|
|
4363
4468
|
};
|
|
4364
4469
|
});
|
|
@@ -4722,5 +4827,5 @@ exports.splitText = splitText;
|
|
|
4722
4827
|
exports.stagger = stagger;
|
|
4723
4828
|
exports.wiggle = wiggle;
|
|
4724
4829
|
exports.withFade = withFade;
|
|
4725
|
-
//# sourceMappingURL=chunk-
|
|
4726
|
-
//# sourceMappingURL=chunk-
|
|
4830
|
+
//# sourceMappingURL=chunk-CC7SUR7Q.cjs.map
|
|
4831
|
+
//# sourceMappingURL=chunk-CC7SUR7Q.cjs.map
|