pixi-effects 0.35.0 → 0.37.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 +35 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +38 -9
- package/ai/tools/lookup.mjs +15 -2
- package/dist/{Base-pNq6sVGl.d.cts → Base-BlA6SeqJ.d.cts} +1 -1
- package/dist/{Base-CXsMdmJB.d.ts → Base-YqM0Ljvp.d.ts} +1 -1
- package/dist/Composition-5KZETM4J.js +7 -0
- package/dist/{Composition-NDXKQHB4.js.map → Composition-5KZETM4J.js.map} +1 -1
- package/dist/Composition-MHDI7UNZ.cjs +16 -0
- package/dist/{Composition-OLH7RC5Z.cjs.map → Composition-MHDI7UNZ.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-CJN_gvLB.d.cts} +26 -2
- package/dist/{Movie-Db4QnMIH.d.cts → Movie-CfHaGmUP.d.ts} +26 -2
- package/dist/{Spans-QHHWC2PB.js → Spans-FSSO2HGX.js} +6 -6
- package/dist/{Spans-QHHWC2PB.js.map → Spans-FSSO2HGX.js.map} +1 -1
- package/dist/{Spans-QRMN2EZO.cjs → Spans-WVJH77BW.cjs} +11 -11
- package/dist/{Spans-QRMN2EZO.cjs.map → Spans-WVJH77BW.cjs.map} +1 -1
- package/dist/{blendModes-WIUCYIMC.cjs → blendModes-FD3THLNC.cjs} +5 -5
- package/dist/{blendModes-WIUCYIMC.cjs.map → blendModes-FD3THLNC.cjs.map} +1 -1
- package/dist/{blendModes-PP5NPBXY.js → blendModes-FMYO6SQN.js} +4 -4
- package/dist/{blendModes-PP5NPBXY.js.map → blendModes-FMYO6SQN.js.map} +1 -1
- package/dist/{chunk-ITDYFBB6.js → chunk-32MMNDDN.js} +7 -6
- package/dist/chunk-32MMNDDN.js.map +1 -0
- package/dist/{chunk-GL2AQFLQ.cjs → chunk-3SAS3ZE5.cjs} +7 -6
- package/dist/chunk-3SAS3ZE5.cjs.map +1 -0
- package/dist/{chunk-7TTCPHAV.cjs → chunk-E26M4NTL.cjs} +235 -49
- package/dist/chunk-E26M4NTL.cjs.map +1 -0
- package/dist/{chunk-XV4L72FW.js → chunk-IPQNT65V.js} +6 -6
- package/dist/chunk-IPQNT65V.js.map +1 -0
- package/dist/{chunk-IMQJVRMT.cjs → chunk-JN7JHNZR.cjs} +5 -5
- package/dist/{chunk-IMQJVRMT.cjs.map → chunk-JN7JHNZR.cjs.map} +1 -1
- package/dist/{chunk-2GNK6DPV.js → chunk-KNDEKWQO.js} +203 -18
- package/dist/chunk-KNDEKWQO.js.map +1 -0
- package/dist/{chunk-5IJENZOG.cjs → chunk-MJMOPWMK.cjs} +92 -92
- package/dist/chunk-MJMOPWMK.cjs.map +1 -0
- package/dist/{chunk-LEECUCTG.cjs → chunk-QHIOOK5S.cjs} +436 -29
- package/dist/chunk-QHIOOK5S.cjs.map +1 -0
- package/dist/{chunk-Y253JQOH.js → chunk-SBR75G73.js} +416 -11
- package/dist/chunk-SBR75G73.js.map +1 -0
- package/dist/{chunk-RTJD3ZSW.js → chunk-VNP7QCJE.js} +4 -4
- package/dist/{chunk-RTJD3ZSW.js.map → chunk-VNP7QCJE.js.map} +1 -1
- package/dist/index.cjs +41 -33
- package/dist/index.d.cts +47 -7
- package/dist/index.d.ts +47 -7
- 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.cts → types-DvnXXm33.d.cts} +67 -3
- package/dist/{types-CavnUvd5.d.ts → types-DvnXXm33.d.ts} +67 -3
- package/docs/api.md +5 -4
- package/docs/dsl.md +42 -5
- package/llms-full.txt +305 -22
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +5 -4
- package/skills/pixi-effects/reference/cheatsheet.md +9 -6
- package/skills/pixi-effects/reference/pitfalls.md +7 -0
- package/skills/pixi-effects/reference/recipes.md +237 -3
- 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-5IJENZOG.cjs.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-XV4L72FW.js.map +0 -1
- package/dist/chunk-Y253JQOH.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkMJMOPWMK_cjs = require('./chunk-MJMOPWMK.cjs');
|
|
4
|
+
var chunkQHIOOK5S_cjs = require('./chunk-QHIOOK5S.cjs');
|
|
5
|
+
var chunkJN7JHNZR_cjs = require('./chunk-JN7JHNZR.cjs');
|
|
6
|
+
var chunk3SAS3ZE5_cjs = require('./chunk-3SAS3ZE5.cjs');
|
|
6
7
|
var chunkTWZNOUM7_cjs = require('./chunk-TWZNOUM7.cjs');
|
|
7
8
|
var pixi_js = require('pixi.js');
|
|
8
9
|
var mediabunny = require('mediabunny');
|
|
@@ -392,6 +393,7 @@ function findSilences(channels, sampleRate, opts = {}) {
|
|
|
392
393
|
}
|
|
393
394
|
|
|
394
395
|
// src/core/inspectAudio.ts
|
|
396
|
+
var BURIED_DB = 12;
|
|
395
397
|
var INAUDIBLE_DB = -50;
|
|
396
398
|
var db = (x) => Math.round(10 * Math.max(-120, 20 * Math.log10(x))) / 10;
|
|
397
399
|
var mono = (chans) => {
|
|
@@ -477,6 +479,7 @@ function analyzeAudio(mix, sources, stats, movieDuration, opts = {}) {
|
|
|
477
479
|
return measure(Array.from({ length: b.numberOfChannels }, (_, c) => b.getChannelData(c)), b.sampleRate);
|
|
478
480
|
};
|
|
479
481
|
const scoreNotes = [];
|
|
482
|
+
const buried = [];
|
|
480
483
|
const list = [...sources].sort((a, b) => a.start - b.start).map((s) => {
|
|
481
484
|
const layer = s.layer ?? "an audio layer";
|
|
482
485
|
const source = s.source ?? "audio";
|
|
@@ -504,8 +507,22 @@ function analyzeAudio(mix, sources, stats, movieDuration, opts = {}) {
|
|
|
504
507
|
const over = s.music.seconds - plays;
|
|
505
508
|
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
509
|
}
|
|
507
|
-
|
|
510
|
+
let belowMixDb;
|
|
511
|
+
if (!clock && !s.sourceMap && s.start < movieDuration && ownDb > INAUDIBLE_DB) {
|
|
512
|
+
const at = s.start + sound.loudestAt;
|
|
513
|
+
const around = db(peakIn(Math.max(0, at - 0.05), Math.min(movieDuration, at + 0.05)));
|
|
514
|
+
belowMixDb = Math.max(0, Math.round((around - ownDb) * 10) / 10);
|
|
515
|
+
if (!s.music && source.startsWith("sfx") && sound.length <= 4 && belowMixDb >= BURIED_DB) {
|
|
516
|
+
buried.push({ layer, source, ownDb, topVolume, around, belowMixDb, at: Math.round(at * 100) / 100 });
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return { layer, source, start: s.start, end: s.end, peakDb, sound, ...belowMixDb !== void 0 ? { belowMixDb } : {}, ...s.music ? { music: s.music } : {} };
|
|
508
520
|
});
|
|
521
|
+
if (buried.length > 0) {
|
|
522
|
+
const worst = buried.reduce((a, b) => b.belowMixDb > a.belowMixDb ? b : a);
|
|
523
|
+
const distinct = new Set(buried.map((x) => (x.layer === "an audio layer" ? `#${buried.indexOf(x)}` : x.layer) + x.source)).size;
|
|
524
|
+
scoreNotes.push(`${distinct === 1 ? "1 sound effect is" : `${distinct} sound effects are`} buried (${BURIED_DB} dB or more under the loudest sample of the mix around its loudest moment${buried.length > distinct ? `, ${buried.length} times in all` : ""}): the worst is ${worst.layer} (${worst.source}), its own peak ${worst.ownDb} dBFS at volume ${Math.round(worst.topVolume * 100) / 100} 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`);
|
|
525
|
+
}
|
|
509
526
|
const whole = measureLoudness(chans, sr);
|
|
510
527
|
const silences = findSilences(chans, sr, { minLength: 1 });
|
|
511
528
|
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`);
|
|
@@ -679,12 +696,14 @@ async function reviewMovie(movie, opts = {}) {
|
|
|
679
696
|
if (r.issues.length) perFrame.push({ frame, issues: r.issues });
|
|
680
697
|
}
|
|
681
698
|
const grouped = splitIssues(groupIssues(perFrame), !!opts.strict);
|
|
699
|
+
const canvas = movie.canvasReport();
|
|
700
|
+
for (const r of canvas) if (!r.ok) grouped.problems.push({ message: r.problem, count: 1, firstFrame: 0, lastFrame: 0, kind: "canvas" });
|
|
682
701
|
const fonts = movie.inspectFonts();
|
|
683
702
|
for (const f of fonts.failedUnused) grouped.review.push({ message: `web font "${f}" failed to load, but no text layer uses it (a broken or unused @font-face)`, count: 1, firstFrame: 0, lastFrame: 0 });
|
|
684
703
|
for (const m of fonts.missing) {
|
|
685
704
|
(opts.strict ? grouped.problems : grouped.review).push({ message: `layer "${m.layer}": none of the fonts "${m.family}" is available here (it is drawn in a fallback font)`, count: 1, firstFrame: 0, lastFrame: 0 });
|
|
686
705
|
}
|
|
687
|
-
return { frames: frames.length, problems: grouped.problems, review: grouped.review, fonts, audio: movie.audioBuffer ? movie.inspectAudio() : null, at };
|
|
706
|
+
return { frames: frames.length, problems: grouped.problems, review: grouped.review, canvas, fonts, audio: movie.audioBuffer ? movie.inspectAudio() : null, at };
|
|
688
707
|
}
|
|
689
708
|
|
|
690
709
|
// src/core/onion.ts
|
|
@@ -1490,8 +1509,8 @@ function expandTransitions(spec) {
|
|
|
1490
1509
|
}
|
|
1491
1510
|
const transitions = out.transitions;
|
|
1492
1511
|
const sequences = out.sequences ?? [];
|
|
1493
|
-
const remap = out.duration !== void 0 ?
|
|
1494
|
-
const parentDuration = remap ?
|
|
1512
|
+
const remap = out.duration !== void 0 ? chunkQHIOOK5S_cjs.timeRemapOf(out) : null;
|
|
1513
|
+
const parentDuration = remap ? chunkQHIOOK5S_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
|
|
1495
1514
|
const compW = out.width;
|
|
1496
1515
|
const compH = out.height;
|
|
1497
1516
|
const threeDByName = new Set(sequences.filter((s) => s.name && s.threeD).map((s) => s.name));
|
|
@@ -1559,16 +1578,16 @@ function expandTransitions(spec) {
|
|
|
1559
1578
|
if (toUses > 1) {
|
|
1560
1579
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
1561
1580
|
}
|
|
1562
|
-
const tStart =
|
|
1581
|
+
const tStart = chunkQHIOOK5S_cjs.resolveAt(t.at, parentDuration);
|
|
1563
1582
|
const tEnd = tStart + t.duration;
|
|
1564
1583
|
const fromSeq = fromEntry.seq;
|
|
1565
|
-
const fromStart =
|
|
1584
|
+
const fromStart = chunkQHIOOK5S_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
1566
1585
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
1567
1586
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
1568
1587
|
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
1588
|
}
|
|
1570
1589
|
const toSeq = toEntry.seq;
|
|
1571
|
-
const toStart =
|
|
1590
|
+
const toStart = chunkQHIOOK5S_cjs.resolveAt(toSeq.at, parentDuration);
|
|
1572
1591
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
1573
1592
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
1574
1593
|
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 +1647,7 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
1628
1647
|
delete inner.at;
|
|
1629
1648
|
delete inner.duration;
|
|
1630
1649
|
const m = inner.mask;
|
|
1631
|
-
const carriesMatte = m !== void 0 &&
|
|
1650
|
+
const carriesMatte = m !== void 0 && chunkMJMOPWMK_cjs.maskSourceOf(m).kind === "refs";
|
|
1632
1651
|
if (carriesMatte) delete inner.mask;
|
|
1633
1652
|
return {
|
|
1634
1653
|
...carriesMatte ? { mask: m } : {},
|
|
@@ -1883,7 +1902,49 @@ function rejectReservedNameCollision(filters, seqName) {
|
|
|
1883
1902
|
}
|
|
1884
1903
|
}
|
|
1885
1904
|
|
|
1905
|
+
// src/core/canvasCheck.ts
|
|
1906
|
+
var isCanvas = (s) => typeof s.checkDeterminism === "function";
|
|
1907
|
+
var describeDiff = (d) => `${d.t} s${d.pixels >= 0 ? ` (${d.pixels} channel values differ, by up to ${d.maxDiff} of 255)` : ""}`;
|
|
1908
|
+
function canvasReport(root) {
|
|
1909
|
+
const out = [];
|
|
1910
|
+
const visit = (seq) => {
|
|
1911
|
+
if (isCanvas(seq)) {
|
|
1912
|
+
const length = seq.duration ?? 0;
|
|
1913
|
+
const moments = [0.15, 0.4, 0.65, 0.9].map((f) => Math.round(f * length * 1e3) / 1e3);
|
|
1914
|
+
const { differs, drawMs, threw } = seq.checkDeterminism(moments);
|
|
1915
|
+
const name = chunk3SAS3ZE5_cjs.describeLayer(seq.spec);
|
|
1916
|
+
const problem = threw.length ? `${name} could not draw at ${threw.map((t) => `${t} s`).join(", ")} (its draw threw, or the layer failed to build): it shows a magenta checkerboard there; the warning above says why, so the layer cannot be called deterministic` : differs.length ? `${name} does not draw the same picture for the same time (checked at ${differs.map(describeDiff).join(", ")}; drawn in two orders after one draw that was thrown away): usually its draw uses Math.random, Date.now or state that outlives the call (a value it keeps from the last call), so playback, a seek and an export would not agree: use info.random() (seeded) and derive everything from t. If it uses none of these, look at the canvases it draws from: make sprites and masks with info.canvas(w, h) (not document.createElement) and draw them into the picture before the strokes that depend on them` : "";
|
|
1917
|
+
out.push({ name: seq.spec.name ?? name, moments, drawMs, ok: !differs.length && !threw.length, problem });
|
|
1918
|
+
}
|
|
1919
|
+
if (seq instanceof chunkMJMOPWMK_cjs.CompositionSequence) walk2(seq);
|
|
1920
|
+
};
|
|
1921
|
+
const walk2 = (comp) => {
|
|
1922
|
+
for (const { seq } of comp.layers()) {
|
|
1923
|
+
visit(seq);
|
|
1924
|
+
const mask = seq.maskSequence;
|
|
1925
|
+
if (mask) visit(mask);
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
walk2(root);
|
|
1929
|
+
return out;
|
|
1930
|
+
}
|
|
1931
|
+
var canvasProblems = (root) => canvasReport(root).filter((r) => !r.ok).map((r) => r.problem);
|
|
1932
|
+
|
|
1886
1933
|
// src/core/inspect.ts
|
|
1934
|
+
function chainOf(node) {
|
|
1935
|
+
const chain = [];
|
|
1936
|
+
for (let n = node; n && n.parent; n = n.parent) {
|
|
1937
|
+
const i = n.parent.children?.indexOf(n);
|
|
1938
|
+
if (i === void 0 || i < 0) return null;
|
|
1939
|
+
chain.unshift(i);
|
|
1940
|
+
}
|
|
1941
|
+
return chain.length ? chain : null;
|
|
1942
|
+
}
|
|
1943
|
+
function drawnAfter(a, b) {
|
|
1944
|
+
if (!a || !b) return null;
|
|
1945
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) if (a[i] !== b[i]) return a[i] > b[i];
|
|
1946
|
+
return null;
|
|
1947
|
+
}
|
|
1887
1948
|
var FAINT = 0.3;
|
|
1888
1949
|
var intersection = (a, b) => {
|
|
1889
1950
|
const w = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
@@ -1907,8 +1968,8 @@ function motionOf(keyframes, local, lives, keys = (k) => GEOMETRY.has(k)) {
|
|
|
1907
1968
|
let length = 0;
|
|
1908
1969
|
if (typeof kf.duration === "number") length = kf.duration;
|
|
1909
1970
|
else if (kf.duration === "auto") {
|
|
1910
|
-
const sp =
|
|
1911
|
-
length = sp ? Math.round(
|
|
1971
|
+
const sp = chunkQHIOOK5S_cjs.parseSpring(kf.ease);
|
|
1972
|
+
length = sp ? Math.round(chunkQHIOOK5S_cjs.springDuration(sp) * 1e3) / 1e3 : 0.5;
|
|
1912
1973
|
}
|
|
1913
1974
|
if (!(length > 0)) continue;
|
|
1914
1975
|
const kat = kf.at ?? 0;
|
|
@@ -1927,7 +1988,11 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1927
1988
|
const scene = /* @__PURE__ */ new Map();
|
|
1928
1989
|
const scaledToNothing = /* @__PURE__ */ new Set();
|
|
1929
1990
|
const hasMotion = /* @__PURE__ */ new Set();
|
|
1930
|
-
const
|
|
1991
|
+
const kinds = /* @__PURE__ */ new Map();
|
|
1992
|
+
const specs = /* @__PURE__ */ new Map();
|
|
1993
|
+
const chains = /* @__PURE__ */ new Map();
|
|
1994
|
+
const chainAlpha = /* @__PURE__ */ new Map();
|
|
1995
|
+
const walk2 = (comp, prefix, insideThreeD, parentVisible, parentScene, parentMotion = NO_MOTION, parentZero = false, parentAlpha = 1) => {
|
|
1931
1996
|
const blending = /* @__PURE__ */ new Set();
|
|
1932
1997
|
const now = comp.childTime(time);
|
|
1933
1998
|
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 +2036,14 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1971
2036
|
if (threeD) info.depthBlur = Number(depthBlur.toFixed(2));
|
|
1972
2037
|
if (threeD && light !== void 0) info.light = Number(light.toFixed(2));
|
|
1973
2038
|
layers.push(info);
|
|
2039
|
+
chainAlpha.set(info, parentAlpha * alpha);
|
|
2040
|
+
chains.set(info, chainOf(display));
|
|
2041
|
+
specs.set(info, seq.spec);
|
|
2042
|
+
kinds.set(info, seq.spec.type === "shape" ? String(seq.spec.shape) : seq.spec.type);
|
|
1974
2043
|
if (motion.ever) hasMotion.add(info);
|
|
1975
2044
|
let shown = bounds ? clip(bounds, view) : null;
|
|
1976
2045
|
const maskTarget = seq.maskSequence?.target;
|
|
1977
|
-
const maskSrc =
|
|
2046
|
+
const maskSrc = chunkMJMOPWMK_cjs.maskSourceOf(seq.spec.mask);
|
|
1978
2047
|
if (shown && maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert)) {
|
|
1979
2048
|
const m = maskTarget.getBounds();
|
|
1980
2049
|
shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
|
|
@@ -1983,7 +2052,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1983
2052
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1984
2053
|
if (group) scene.set(info, group);
|
|
1985
2054
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1986
|
-
if (seq instanceof
|
|
2055
|
+
if (seq instanceof chunkMJMOPWMK_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
|
|
1987
2056
|
});
|
|
1988
2057
|
};
|
|
1989
2058
|
walk2(root, "", false, true);
|
|
@@ -2019,6 +2088,42 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
2019
2088
|
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
2089
|
}
|
|
2021
2090
|
}
|
|
2091
|
+
const FILLED = /* @__PURE__ */ new Set(["rect", "circle", "ellipse", "image", "video"]);
|
|
2092
|
+
for (const t of texts) {
|
|
2093
|
+
const tb = seen.get(t);
|
|
2094
|
+
if (!tb) continue;
|
|
2095
|
+
const area = tb.width * tb.height;
|
|
2096
|
+
if (!(area > 0)) continue;
|
|
2097
|
+
for (const o of layers) {
|
|
2098
|
+
if (o === t || o.type === "text" || !o.visible || !o.bounds) continue;
|
|
2099
|
+
if (o.path.startsWith(t.path + "/") || t.path.startsWith(o.path + "/")) continue;
|
|
2100
|
+
const kind = kinds.get(o) ?? o.type, spec = specs.get(o) ?? {};
|
|
2101
|
+
const initial = spec.initial ?? {};
|
|
2102
|
+
const hairline = (kind === "line" || kind === "rect") && Math.min(o.bounds.width, o.bounds.height) < 12 && Math.max(o.bounds.width, o.bounds.height) >= 40;
|
|
2103
|
+
const soft = spec.blendMode !== void 0 && spec.blendMode !== "normal" || Array.isArray(spec.filters) && spec.filters.length > 0;
|
|
2104
|
+
const filled = kind === "image" || kind === "video" || initial.fillColor !== void 0 || spec.fillGradient !== void 0 || initial.fillGradient !== void 0;
|
|
2105
|
+
if (o.threeD || t.threeD) continue;
|
|
2106
|
+
const over = drawnAfter(chains.get(o) ?? null, chains.get(t) ?? null) ?? layers.indexOf(o) > layers.indexOf(t);
|
|
2107
|
+
const opacity = chainAlpha.get(o) ?? o.alpha;
|
|
2108
|
+
const hides = FILLED.has(kind) && !hairline && filled && !soft && over && opacity >= 0.8;
|
|
2109
|
+
const cuts = hairline && !soft && over && opacity >= FAINT;
|
|
2110
|
+
if (!hides && !cuts) continue;
|
|
2111
|
+
const st = scene.get(t), so = scene.get(o);
|
|
2112
|
+
if (st && so && st !== so) continue;
|
|
2113
|
+
const ob = seen.get(o);
|
|
2114
|
+
if (!ob) continue;
|
|
2115
|
+
const covered = intersection(tb, ob) / area;
|
|
2116
|
+
if (cuts) {
|
|
2117
|
+
const horizontal = ob.width >= ob.height;
|
|
2118
|
+
const mid = horizontal ? ob.y + ob.height / 2 : ob.x + ob.width / 2;
|
|
2119
|
+
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;
|
|
2120
|
+
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);
|
|
2121
|
+
if (mid < lo || mid > hi || along < 0.3 * (horizontal ? tb.width : tb.height)) continue;
|
|
2122
|
+
} else if (covered < 0.1) continue;
|
|
2123
|
+
const word = kind === "image" || kind === "video" ? kind : "shape";
|
|
2124
|
+
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)`);
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2022
2127
|
const mode = opts.layers ?? "all";
|
|
2023
2128
|
const listed = mode === "none" ? [] : mode === "visible" ? layers.filter((l) => l.visible) : layers;
|
|
2024
2129
|
return { frame, time, canvas, summary: { layers: layers.length, visible: layers.filter((l) => l.visible).length }, issues, layers: listed };
|
|
@@ -2031,7 +2136,7 @@ var round = (n) => Math.round(n * 1e6) / 1e6;
|
|
|
2031
2136
|
var family = (name) => name.replace(/\d+/g, "#");
|
|
2032
2137
|
function detailOf(seq) {
|
|
2033
2138
|
const s = seq.spec;
|
|
2034
|
-
const spans =
|
|
2139
|
+
const spans = chunkQHIOOK5S_cjs.spansMeta.get(seq.spec)?.preview;
|
|
2035
2140
|
if (spans) return spans.length > 60 ? spans.slice(0, 57) + "\u2026" : spans;
|
|
2036
2141
|
if (typeof s.text === "string") return s.text.length > 60 ? s.text.slice(0, 57) + "\u2026" : s.text;
|
|
2037
2142
|
if (typeof s.asset === "string") return `asset \u201C${s.asset}\u201D`;
|
|
@@ -2047,10 +2152,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
|
|
|
2047
2152
|
const start = parentStart + (seq.at ?? 0);
|
|
2048
2153
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
2049
2154
|
const span = end - start;
|
|
2050
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
2155
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkQHIOOK5S_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
2051
2156
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
|
|
2052
2157
|
const inner = [];
|
|
2053
|
-
const isComp = seq instanceof
|
|
2158
|
+
const isComp = seq instanceof chunkMJMOPWMK_cjs.CompositionSequence;
|
|
2054
2159
|
if (isComp) {
|
|
2055
2160
|
const label = seq.remapLabel();
|
|
2056
2161
|
walk(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
@@ -2209,7 +2314,7 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
|
2209
2314
|
}
|
|
2210
2315
|
|
|
2211
2316
|
// src/core/vars.ts
|
|
2212
|
-
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...
|
|
2317
|
+
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunkQHIOOK5S_cjs.EXPRESSION_NAMES];
|
|
2213
2318
|
var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2214
2319
|
var isPlain = (v) => !!v && typeof v === "object" && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
2215
2320
|
function normalizeVars(raw, where, warn = (m) => console.warn(m)) {
|
|
@@ -2748,8 +2853,8 @@ var Movie = class {
|
|
|
2748
2853
|
this.stops = normalizeStops(applyVars(options.composition, this._vars)?.stops, this.duration, this.frameRate);
|
|
2749
2854
|
this._posterFrame = poster.frame;
|
|
2750
2855
|
this.background = options.background ?? "#000000";
|
|
2751
|
-
this.timeline =
|
|
2752
|
-
|
|
2856
|
+
this.timeline = chunkQHIOOK5S_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2857
|
+
chunkQHIOOK5S_cjs.lengthen(this.timeline, this.duration);
|
|
2753
2858
|
const baseAppOptions = {
|
|
2754
2859
|
width: this.width,
|
|
2755
2860
|
height: this.height,
|
|
@@ -2843,8 +2948,8 @@ var Movie = class {
|
|
|
2843
2948
|
height: sizeWins ? height : spec.height ?? height,
|
|
2844
2949
|
duration: spec.duration ?? this.duration
|
|
2845
2950
|
} : void 0;
|
|
2846
|
-
await
|
|
2847
|
-
if (
|
|
2951
|
+
await chunkQHIOOK5S_cjs.ensureFilterLibrary(seededComposition);
|
|
2952
|
+
if (chunkJN7JHNZR_cjs.usesAdvancedBlend(seededComposition)) await chunkJN7JHNZR_cjs.enableAdvancedBlend(this.app.renderer);
|
|
2848
2953
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
2849
2954
|
const rootSeqSpec = {
|
|
2850
2955
|
type: "composition",
|
|
@@ -2854,7 +2959,7 @@ var Movie = class {
|
|
|
2854
2959
|
...userComposition
|
|
2855
2960
|
};
|
|
2856
2961
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
2857
|
-
const sequence = new
|
|
2962
|
+
const sequence = new chunkMJMOPWMK_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
2858
2963
|
lp?.begin("build", countLayers(rootSeqSpec));
|
|
2859
2964
|
try {
|
|
2860
2965
|
await sequence.build();
|
|
@@ -2990,8 +3095,8 @@ var Movie = class {
|
|
|
2990
3095
|
if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
|
|
2991
3096
|
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged);
|
|
2992
3097
|
alive();
|
|
2993
|
-
const timeline =
|
|
2994
|
-
|
|
3098
|
+
const timeline = chunkQHIOOK5S_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
3099
|
+
chunkQHIOOK5S_cjs.lengthen(timeline, this.duration);
|
|
2995
3100
|
sequence.bindTimeline(timeline);
|
|
2996
3101
|
const hadSound = this.audioBuffer !== null;
|
|
2997
3102
|
const audio = await this._mixSound(sequence, this._ensureAudioContext());
|
|
@@ -3288,6 +3393,16 @@ var Movie = class {
|
|
|
3288
3393
|
await this.gotoFrame(f, true);
|
|
3289
3394
|
return inspectScene(this._rootSequence, f, f / this.frameRate, { width: this.width, height: this.height }, opts);
|
|
3290
3395
|
}
|
|
3396
|
+
/** The canvas layers whose same frame is not the same picture (what `check` reports as a problem): one sentence each. */
|
|
3397
|
+
canvasProblems() {
|
|
3398
|
+
this._requireReady("canvasProblems");
|
|
3399
|
+
return canvasProblems(this._rootSequence);
|
|
3400
|
+
}
|
|
3401
|
+
/** Every canvas layer as the determinism check saw it: the moments drawn, the usual time of a draw in ms, and whether the same time gave the same picture (`check` prints it even when all pass). */
|
|
3402
|
+
canvasReport() {
|
|
3403
|
+
this._requireReady("canvasReport");
|
|
3404
|
+
return canvasReport(this._rootSequence);
|
|
3405
|
+
}
|
|
3291
3406
|
/**
|
|
3292
3407
|
* Every layer as a row with absolute start / end / keyframe times (seconds), plus the transition windows. Runs of
|
|
3293
3408
|
* similar layers (`pop-1` … `pop-12`) are one row with a `parts` span each. Read it, or draw it with `timelineChart()`.
|
|
@@ -3705,7 +3820,7 @@ function countLayers(spec) {
|
|
|
3705
3820
|
n += 1 + countLayers(s);
|
|
3706
3821
|
const spans = s.spans;
|
|
3707
3822
|
if (Array.isArray(spans)) n += spans.length;
|
|
3708
|
-
const src =
|
|
3823
|
+
const src = chunkMJMOPWMK_cjs.maskSourceOf(mask);
|
|
3709
3824
|
if (src.kind === "inline") n += 1 + countLayers(src.spec);
|
|
3710
3825
|
}
|
|
3711
3826
|
return n;
|
|
@@ -3718,7 +3833,7 @@ function measureText(text, style = {}) {
|
|
|
3718
3833
|
return { width: m.width, height: m.height, lines: text.split("\n").length };
|
|
3719
3834
|
}
|
|
3720
3835
|
function splitText(text, style = {}, opts = {}) {
|
|
3721
|
-
chunkTWZNOUM7_cjs.warnUnknownOptions("splitText()", opts, ["by", "x", "y", "align"]);
|
|
3836
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("splitText()", opts, ["by", "x", "y", "align", "vertical"]);
|
|
3722
3837
|
let by = opts.by ?? "chars";
|
|
3723
3838
|
if (!BY.includes(by)) {
|
|
3724
3839
|
const g = chunkTWZNOUM7_cjs.suggestName(String(by), BY);
|
|
@@ -3737,6 +3852,7 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3737
3852
|
}
|
|
3738
3853
|
if (text === "") return [];
|
|
3739
3854
|
const ts = new pixi_js.TextStyle(style);
|
|
3855
|
+
if (opts.vertical) return splitVertical(text, style, ts, x0, y0, align, by);
|
|
3740
3856
|
const lineHeight = pixi_js.CanvasTextMetrics.measureText("M", ts).lineHeight ?? pixi_js.CanvasTextMetrics.measureText("M", ts).height;
|
|
3741
3857
|
const sentinel = widthOf("|", ts);
|
|
3742
3858
|
const out = [];
|
|
@@ -3760,11 +3876,41 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
3760
3876
|
});
|
|
3761
3877
|
return out;
|
|
3762
3878
|
}
|
|
3879
|
+
var PUNCT = new Set("\u3001\u3002\uFF0C\uFF0E\uFF64\uFF61");
|
|
3880
|
+
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");
|
|
3881
|
+
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");
|
|
3882
|
+
function splitVertical(text, style, ts, right, top, align, by) {
|
|
3883
|
+
if (by !== "chars") console.warn(`pixi-effects: splitText(): vertical text has only a "chars" form (by "${by}" has no vertical layout); using "chars"`);
|
|
3884
|
+
const em = typeof style.fontSize === "number" ? style.fontSize : Number(ts.fontSize) || 26;
|
|
3885
|
+
const spacing = typeof style.letterSpacing === "number" ? style.letterSpacing : 0;
|
|
3886
|
+
const cell = em + spacing;
|
|
3887
|
+
const lineHeight = pixi_js.CanvasTextMetrics.measureText("M", ts).lineHeight ?? pixi_js.CanvasTextMetrics.measureText("M", ts).height;
|
|
3888
|
+
const out = [];
|
|
3889
|
+
text.split("\n").forEach((line, lineNo) => {
|
|
3890
|
+
const chars = Array.from(line);
|
|
3891
|
+
const start = align === "center" ? top - chars.length * cell / 2 : align === "right" ? top - chars.length * cell : top;
|
|
3892
|
+
const column = right - lineHeight / 2 - lineNo * lineHeight;
|
|
3893
|
+
chars.forEach((ch, i) => {
|
|
3894
|
+
if (/\s/.test(ch)) return;
|
|
3895
|
+
let cx = column, cy = start + i * cell + cell / 2;
|
|
3896
|
+
if (PUNCT.has(ch)) {
|
|
3897
|
+
cx += 0.5 * em;
|
|
3898
|
+
cy -= 0.5 * em;
|
|
3899
|
+
} else if (SMALL.has(ch)) {
|
|
3900
|
+
cx += 0.1 * em;
|
|
3901
|
+
cy -= 0.1 * em;
|
|
3902
|
+
}
|
|
3903
|
+
const width = widthOf(ch, ts);
|
|
3904
|
+
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 });
|
|
3905
|
+
});
|
|
3906
|
+
});
|
|
3907
|
+
return out;
|
|
3908
|
+
}
|
|
3763
3909
|
|
|
3764
3910
|
// src/presets/_ease.ts
|
|
3765
3911
|
function parseEase2(name) {
|
|
3766
|
-
|
|
3767
|
-
return
|
|
3912
|
+
chunkQHIOOK5S_cjs.checkEase(name, "a preset");
|
|
3913
|
+
return chunkQHIOOK5S_cjs.parseEase(name);
|
|
3768
3914
|
}
|
|
3769
3915
|
|
|
3770
3916
|
// src/presets/kenBurns.ts
|
|
@@ -3899,17 +4045,17 @@ function orbit(opts) {
|
|
|
3899
4045
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
3900
4046
|
}
|
|
3901
4047
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
3902
|
-
const fixedR = opts.radius ??
|
|
4048
|
+
const fixedR = opts.radius ?? chunkQHIOOK5S_cjs.homeDistance(height, fov ?? chunkQHIOOK5S_cjs.DEFAULT_FOV);
|
|
3903
4049
|
const start = opts.start ?? -degrees / 2;
|
|
3904
4050
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
3905
4051
|
const easeFn = parseEase2(ease);
|
|
3906
4052
|
const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
|
|
3907
4053
|
const pos = (i) => {
|
|
3908
4054
|
const p = i / steps;
|
|
3909
|
-
const a = (start + degrees * easeFn(p)) *
|
|
4055
|
+
const a = (start + degrees * easeFn(p)) * chunkQHIOOK5S_cjs.DEG;
|
|
3910
4056
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
3911
4057
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
3912
|
-
const R =
|
|
4058
|
+
const R = chunkQHIOOK5S_cjs.homeDistance(height, f);
|
|
3913
4059
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
3914
4060
|
};
|
|
3915
4061
|
const keyframes = [];
|
|
@@ -3964,7 +4110,7 @@ function particles(opts) {
|
|
|
3964
4110
|
const round2 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3965
4111
|
const out = [];
|
|
3966
4112
|
for (let i = 0; i < count; i++) {
|
|
3967
|
-
const r =
|
|
4113
|
+
const r = chunkQHIOOK5S_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
3968
4114
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
3969
4115
|
const born = at + r() * emit;
|
|
3970
4116
|
const lifetime = pick(life);
|
|
@@ -3977,7 +4123,7 @@ function particles(opts) {
|
|
|
3977
4123
|
const turn = spin ? pick(spin) : 0;
|
|
3978
4124
|
const startAngle = spin ? r() * 360 : 0;
|
|
3979
4125
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
3980
|
-
const n0 = sway ?
|
|
4126
|
+
const n0 = sway ? chunkQHIOOK5S_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
3981
4127
|
const at_ = (t) => {
|
|
3982
4128
|
const axis = (p0, v0, acc) => {
|
|
3983
4129
|
if (drag > 0) {
|
|
@@ -3986,7 +4132,7 @@ function particles(opts) {
|
|
|
3986
4132
|
}
|
|
3987
4133
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
3988
4134
|
};
|
|
3989
|
-
const sw = sway ? swayAmp * (
|
|
4135
|
+
const sw = sway ? swayAmp * (chunkQHIOOK5S_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
3990
4136
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
3991
4137
|
};
|
|
3992
4138
|
const kfs = [];
|
|
@@ -4048,7 +4194,7 @@ function followPath(opts) {
|
|
|
4048
4194
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
4049
4195
|
const segments = [];
|
|
4050
4196
|
let total = 0;
|
|
4051
|
-
for (const line of
|
|
4197
|
+
for (const line of chunkQHIOOK5S_cjs.flattenSvgPath(d)) {
|
|
4052
4198
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
4053
4199
|
for (let i = 2; i < p.length; i += 2) {
|
|
4054
4200
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -4098,6 +4244,45 @@ function followPath(opts) {
|
|
|
4098
4244
|
return out;
|
|
4099
4245
|
}
|
|
4100
4246
|
|
|
4247
|
+
// src/core/pathSample.ts
|
|
4248
|
+
function samplePath(d) {
|
|
4249
|
+
if (typeof d !== "string" || d.trim() === "") throw new Error('samplePath(): d must be SVG path data, e.g. "M 40 300 C 200 20 400 20 560 300"');
|
|
4250
|
+
const lines = chunkQHIOOK5S_cjs.flattenSvgPath(d);
|
|
4251
|
+
const segments = [];
|
|
4252
|
+
let length = 0;
|
|
4253
|
+
for (const line of lines) {
|
|
4254
|
+
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
4255
|
+
for (let i = 2; i < p.length; i += 2) {
|
|
4256
|
+
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
4257
|
+
if (len === 0) continue;
|
|
4258
|
+
segments.push({ x0: p[i - 2], y0: p[i - 1], x1: p[i], y1: p[i + 1], start: length, len });
|
|
4259
|
+
length += len;
|
|
4260
|
+
}
|
|
4261
|
+
}
|
|
4262
|
+
if (!(length > 0)) throw new Error(`samplePath(): the path "${d}" has no length (it needs at least two different points)`);
|
|
4263
|
+
const find = (s) => {
|
|
4264
|
+
let lo = 0, hi = segments.length - 1;
|
|
4265
|
+
while (lo < hi) {
|
|
4266
|
+
const mid = lo + hi >> 1;
|
|
4267
|
+
if (segments[mid].start + segments[mid].len < s) lo = mid + 1;
|
|
4268
|
+
else hi = mid;
|
|
4269
|
+
}
|
|
4270
|
+
return segments[lo];
|
|
4271
|
+
};
|
|
4272
|
+
return {
|
|
4273
|
+
length,
|
|
4274
|
+
at(u) {
|
|
4275
|
+
const s = Math.min(Math.max(Number.isFinite(u) ? u : 0, 0), 1) * length;
|
|
4276
|
+
const g = find(s);
|
|
4277
|
+
const t = Math.min(Math.max((s - g.start) / g.len, 0), 1);
|
|
4278
|
+
return { x: g.x0 + (g.x1 - g.x0) * t, y: g.y0 + (g.y1 - g.y0) * t, angle: Math.atan2(g.y1 - g.y0, g.x1 - g.x0) };
|
|
4279
|
+
},
|
|
4280
|
+
trim(start = 0, end = 1) {
|
|
4281
|
+
return chunkQHIOOK5S_cjs.trimPolylines(lines, start, end).map((l) => l.closed ? [...l.pts, l.pts[0], l.pts[1]] : l.pts);
|
|
4282
|
+
}
|
|
4283
|
+
};
|
|
4284
|
+
}
|
|
4285
|
+
|
|
4101
4286
|
// src/presets/cameraPath.ts
|
|
4102
4287
|
var KEYS4 = ["points", "at", "duration", "ease", "look", "lookAhead", "smooth", "from", "to", "frameRate"];
|
|
4103
4288
|
var MAX_STEPS2 = 4e3;
|
|
@@ -4202,7 +4387,7 @@ function distances(n, from, grid, seed) {
|
|
|
4202
4387
|
if (n === 0) return [];
|
|
4203
4388
|
if (from === "random") {
|
|
4204
4389
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
4205
|
-
const r =
|
|
4390
|
+
const r = chunkQHIOOK5S_cjs.random(seed);
|
|
4206
4391
|
for (let i = n - 1; i > 0; i--) {
|
|
4207
4392
|
const j = Math.floor(r() * (i + 1));
|
|
4208
4393
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -4264,7 +4449,7 @@ function wiggle(opts) {
|
|
|
4264
4449
|
to[n] = p.around;
|
|
4265
4450
|
return;
|
|
4266
4451
|
}
|
|
4267
|
-
const off = (
|
|
4452
|
+
const off = (chunkQHIOOK5S_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
4268
4453
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
4269
4454
|
});
|
|
4270
4455
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -4275,7 +4460,7 @@ function wiggle(opts) {
|
|
|
4275
4460
|
// src/presets/animateText.ts
|
|
4276
4461
|
var TWEEN_KEYS = ["preset", "from", "to", "duration", "ease"];
|
|
4277
4462
|
var TIME_KEYS = ["at", "delay", "start", "begin", "time"];
|
|
4278
|
-
var KEYS5 = ["by", "x", "y", "align", "name", "at", "duration", "in", "out", "stagger", "idle", "styleFor"];
|
|
4463
|
+
var KEYS5 = ["by", "x", "y", "align", "vertical", "name", "at", "duration", "in", "out", "stagger", "idle", "styleFor"];
|
|
4279
4464
|
var PRESETS = {
|
|
4280
4465
|
rise: { from: { y: 40, alpha: 0 }, duration: 0.5, ease: "back.out(2)" },
|
|
4281
4466
|
drop: { from: { y: -50, alpha: 0 }, duration: 0.7, ease: "bounce.out" },
|
|
@@ -4288,14 +4473,14 @@ var PRESETS = {
|
|
|
4288
4473
|
var PRESET_NAMES = Object.keys(PRESETS);
|
|
4289
4474
|
function animateText(text, style, options) {
|
|
4290
4475
|
chunkTWZNOUM7_cjs.warnUnknownOptions("animateText()", options, KEYS5);
|
|
4291
|
-
const { by = "chars", x = 0, y = 0, align = "left", name = "text", at = 0, duration, idle, styleFor } = options;
|
|
4476
|
+
const { by = "chars", x = 0, y = 0, align = "left", vertical = false, name = "text", at = 0, duration, idle, styleFor } = options;
|
|
4292
4477
|
for (const [n, v] of [["x", x], ["y", y]]) {
|
|
4293
4478
|
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
4294
4479
|
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
4480
|
}
|
|
4296
4481
|
}
|
|
4297
4482
|
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 });
|
|
4483
|
+
const pieces = splitText(text, style, { by, x, y, align, ...vertical ? { vertical } : {} });
|
|
4299
4484
|
if (pieces.length === 0) return [];
|
|
4300
4485
|
const lineHeight = measureText("M", style).height;
|
|
4301
4486
|
const inTween = options.in === false ? null : resolveTween(options.in ?? "rise", "in");
|
|
@@ -4314,12 +4499,12 @@ function animateText(text, style, options) {
|
|
|
4314
4499
|
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
4500
|
}
|
|
4316
4501
|
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 };
|
|
4502
|
+
const cx = p.cx ?? p.x + p.width / 2, cy = p.cy ?? p.y + lineHeight / 2;
|
|
4503
|
+
const rest = { x: cx, y: cy, alpha: 1, scale: 1, scaleX: 1, scaleY: 1, rotation: p.rotation ?? 0 };
|
|
4319
4504
|
const start = at + delays[i];
|
|
4320
4505
|
const len = end - start;
|
|
4321
4506
|
const keyframes = [];
|
|
4322
|
-
const place = (key, v) => key === "x" || key === "y" ? rest[key] + v : v;
|
|
4507
|
+
const place = (key, v) => key === "x" || key === "y" || key === "rotation" ? rest[key] + v : v;
|
|
4323
4508
|
if (inTween) {
|
|
4324
4509
|
keyframes.push({
|
|
4325
4510
|
at: 0,
|
|
@@ -4358,7 +4543,7 @@ function animateText(text, style, options) {
|
|
|
4358
4543
|
style: styleFor ? { ...style, ...styleFor(p) } : style,
|
|
4359
4544
|
at: start,
|
|
4360
4545
|
duration: len,
|
|
4361
|
-
initial: { x: cx, y: cy, anchorX: 0.5, anchorY: 0.5 },
|
|
4546
|
+
initial: { x: cx, y: cy, anchorX: 0.5, anchorY: 0.5, ...rest.rotation !== 0 ? { rotation: rest.rotation } : {} },
|
|
4362
4547
|
keyframes
|
|
4363
4548
|
};
|
|
4364
4549
|
});
|
|
@@ -4718,9 +4903,10 @@ exports.parseEase = parseEase2;
|
|
|
4718
4903
|
exports.particles = particles;
|
|
4719
4904
|
exports.react = react;
|
|
4720
4905
|
exports.resolveLoader = resolveLoader;
|
|
4906
|
+
exports.samplePath = samplePath;
|
|
4721
4907
|
exports.splitText = splitText;
|
|
4722
4908
|
exports.stagger = stagger;
|
|
4723
4909
|
exports.wiggle = wiggle;
|
|
4724
4910
|
exports.withFade = withFade;
|
|
4725
|
-
//# sourceMappingURL=chunk-
|
|
4726
|
-
//# sourceMappingURL=chunk-
|
|
4911
|
+
//# sourceMappingURL=chunk-E26M4NTL.cjs.map
|
|
4912
|
+
//# sourceMappingURL=chunk-E26M4NTL.cjs.map
|