pixi-effects 0.40.0 → 0.42.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 +17 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +19 -2
- package/dist/Composition-N6BOROJ2.cjs +16 -0
- package/dist/{Composition-C3UEVHQG.cjs.map → Composition-N6BOROJ2.cjs.map} +1 -1
- package/dist/Composition-YGBQX3HZ.js +7 -0
- package/dist/{Composition-KRWH72MA.js.map → Composition-YGBQX3HZ.js.map} +1 -1
- package/dist/Controller.d.cts +1 -1
- package/dist/Controller.d.ts +1 -1
- package/dist/{Movie-CMq4KFmc.d.cts → Movie-BHGhg-fJ.d.cts} +88 -1
- package/dist/{Movie-CG6Jy1tx.d.ts → Movie-CBVFZ1kg.d.ts} +88 -1
- package/dist/{Spans-TWO4VN5H.js → Spans-6L2ZVECX.js} +4 -4
- package/dist/{Spans-TWO4VN5H.js.map → Spans-6L2ZVECX.js.map} +1 -1
- package/dist/{Spans-APNJHCYO.cjs → Spans-XTIWYSNO.cjs} +9 -9
- package/dist/{Spans-APNJHCYO.cjs.map → Spans-XTIWYSNO.cjs.map} +1 -1
- package/dist/{chunk-27PYJ4JY.cjs → chunk-3HZV3UHU.cjs} +67 -63
- package/dist/chunk-3HZV3UHU.cjs.map +1 -0
- package/dist/{chunk-LMWXR5OC.js → chunk-4QVQ5UJJ.js} +4 -4
- package/dist/{chunk-LMWXR5OC.js.map → chunk-4QVQ5UJJ.js.map} +1 -1
- package/dist/{chunk-26Z544SH.js → chunk-ICI6ACHY.js} +7 -3
- package/dist/chunk-ICI6ACHY.js.map +1 -0
- package/dist/{chunk-CT5CZVT5.js → chunk-NFJKBWYO.js} +243 -4
- package/dist/chunk-NFJKBWYO.js.map +1 -0
- package/dist/{chunk-LEL7UNYQ.cjs → chunk-WVZLAIKK.cjs} +278 -39
- package/dist/chunk-WVZLAIKK.cjs.map +1 -0
- package/dist/{chunk-7EI2N7WO.cjs → chunk-X62H3RBG.cjs} +4 -4
- package/dist/{chunk-7EI2N7WO.cjs.map → chunk-X62H3RBG.cjs.map} +1 -1
- package/dist/index.cjs +33 -33
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/loader.css +1 -1
- package/dist/present.cjs +3 -3
- package/dist/present.d.cts +1 -1
- package/dist/present.d.ts +1 -1
- package/dist/present.js +3 -3
- package/dist/three.cjs +86 -7
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +27 -1
- package/dist/three.d.ts +27 -1
- package/dist/three.js +83 -4
- package/dist/three.js.map +1 -1
- package/docs/api.md +37 -0
- package/docs/dsl.md +1 -1
- package/llms-full.txt +173 -3
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +3 -2
- package/skills/pixi-effects/reference/cheatsheet.md +3 -0
- package/skills/pixi-effects/reference/recipes.md +129 -0
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Composition-C3UEVHQG.cjs +0 -16
- package/dist/Composition-KRWH72MA.js +0 -7
- package/dist/chunk-26Z544SH.js.map +0 -1
- package/dist/chunk-27PYJ4JY.cjs.map +0 -1
- package/dist/chunk-CT5CZVT5.js.map +0 -1
- package/dist/chunk-LEL7UNYQ.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunk3HZV3UHU_cjs = require('./chunk-3HZV3UHU.cjs');
|
|
4
|
+
var chunkX62H3RBG_cjs = require('./chunk-X62H3RBG.cjs');
|
|
5
5
|
var chunkLQDDDIC4_cjs = require('./chunk-LQDDDIC4.cjs');
|
|
6
6
|
var chunkJN7JHNZR_cjs = require('./chunk-JN7JHNZR.cjs');
|
|
7
7
|
var chunk3SAS3ZE5_cjs = require('./chunk-3SAS3ZE5.cjs');
|
|
@@ -1105,8 +1105,8 @@ function expandTransitions(spec) {
|
|
|
1105
1105
|
}
|
|
1106
1106
|
const transitions = out.transitions;
|
|
1107
1107
|
const sequences = out.sequences ?? [];
|
|
1108
|
-
const remap = out.duration !== void 0 ?
|
|
1109
|
-
const parentDuration = remap ?
|
|
1108
|
+
const remap = out.duration !== void 0 ? chunkX62H3RBG_cjs.timeRemapOf(out) : null;
|
|
1109
|
+
const parentDuration = remap ? chunkX62H3RBG_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
|
|
1110
1110
|
const compW = out.width;
|
|
1111
1111
|
const compH = out.height;
|
|
1112
1112
|
const threeDByName = new Set(sequences.filter((s) => s.name && s.threeD).map((s) => s.name));
|
|
@@ -1174,16 +1174,16 @@ function expandTransitions(spec) {
|
|
|
1174
1174
|
if (toUses > 1) {
|
|
1175
1175
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
1176
1176
|
}
|
|
1177
|
-
const tStart =
|
|
1177
|
+
const tStart = chunkX62H3RBG_cjs.resolveAt(t.at, parentDuration);
|
|
1178
1178
|
const tEnd = tStart + t.duration;
|
|
1179
1179
|
const fromSeq = fromEntry.seq;
|
|
1180
|
-
const fromStart =
|
|
1180
|
+
const fromStart = chunkX62H3RBG_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
1181
1181
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
1182
1182
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
1183
1183
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
1184
1184
|
}
|
|
1185
1185
|
const toSeq = toEntry.seq;
|
|
1186
|
-
const toStart =
|
|
1186
|
+
const toStart = chunkX62H3RBG_cjs.resolveAt(toSeq.at, parentDuration);
|
|
1187
1187
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
1188
1188
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
1189
1189
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
@@ -1243,7 +1243,7 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
1243
1243
|
delete inner.at;
|
|
1244
1244
|
delete inner.duration;
|
|
1245
1245
|
const m = inner.mask;
|
|
1246
|
-
const carriesMatte = m !== void 0 &&
|
|
1246
|
+
const carriesMatte = m !== void 0 && chunk3HZV3UHU_cjs.maskSourceOf(m).kind === "refs";
|
|
1247
1247
|
if (carriesMatte) delete inner.mask;
|
|
1248
1248
|
return {
|
|
1249
1249
|
...carriesMatte ? { mask: m } : {},
|
|
@@ -1513,7 +1513,7 @@ function canvasReport(root) {
|
|
|
1513
1513
|
const problem = threw.length ? `${name} could not draw at ${threw.map((t) => `${t} s`).join(", ")} (its ${kind === "three" ? "update or render threw" : "draw threw"}, or the layer failed to build): ${kind === "three" ? "the warning above says why" : "it shows a magenta checkerboard there; the warning above says why"}, so the layer cannot be called deterministic` : differs.length ? `${name} does not draw the same picture for the same time (checked at ${differs.map(describeDiff).join(", ")}; drawn in two orders after one draw that was thrown away): ` + (kind === "three" ? "usually its update uses Math.random, Date.now, a clock, or state that builds up from call to call: a mixer advanced with mixer.update(dt) is one (pose a clip with mixer.setTime(t), or threeGltf(url).pose(t)), and so is a value moved by the time since the last call. A skinned model of your own (not loaded by threeGltf) that moves and casts a shadow does it too: three culls a skinned mesh by a bounding sphere that does not follow it, so set mesh.frustumCulled = false. Set every object from t, so playback, a seek and an export agree" : "usually its draw uses Math.random, Date.now or state that outlives the call (a value it keeps from the last call), so playback, a seek and an export would not agree: use info.random() (seeded) and derive everything from t. If it uses none of these, look at the canvases it draws from: make sprites and masks with info.canvas(w, h) (not document.createElement) and draw them into the picture before the strokes that depend on them") : "";
|
|
1514
1514
|
out.push({ name: seq.spec.name ?? name, moments, drawMs, ok: !differs.length && !threw.length, problem, kind });
|
|
1515
1515
|
}
|
|
1516
|
-
if (seq instanceof
|
|
1516
|
+
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence) walk2(seq);
|
|
1517
1517
|
};
|
|
1518
1518
|
const walk2 = (comp) => {
|
|
1519
1519
|
for (const { seq } of comp.layers()) {
|
|
@@ -1565,8 +1565,8 @@ function motionOf(keyframes, local, lives, keys = (k) => GEOMETRY.has(k)) {
|
|
|
1565
1565
|
let length = 0;
|
|
1566
1566
|
if (typeof kf.duration === "number") length = kf.duration;
|
|
1567
1567
|
else if (kf.duration === "auto") {
|
|
1568
|
-
const sp =
|
|
1569
|
-
length = sp ? Math.round(
|
|
1568
|
+
const sp = chunkX62H3RBG_cjs.parseSpring(kf.ease);
|
|
1569
|
+
length = sp ? Math.round(chunkX62H3RBG_cjs.springDuration(sp) * 1e3) / 1e3 : 0.5;
|
|
1570
1570
|
}
|
|
1571
1571
|
if (!(length > 0)) continue;
|
|
1572
1572
|
const kat = kf.at ?? 0;
|
|
@@ -1645,7 +1645,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1645
1645
|
if (motion.ever) hasMotion.add(info);
|
|
1646
1646
|
let shown = bounds ? clip(bounds, view) : null;
|
|
1647
1647
|
const maskTarget = seq.maskSequence?.target;
|
|
1648
|
-
const maskSrc =
|
|
1648
|
+
const maskSrc = chunk3HZV3UHU_cjs.maskSourceOf(seq.spec.mask);
|
|
1649
1649
|
if (shown && maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert)) {
|
|
1650
1650
|
const m = maskTarget.getBounds();
|
|
1651
1651
|
shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
|
|
@@ -1654,7 +1654,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1654
1654
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1655
1655
|
if (group) scene.set(info, group);
|
|
1656
1656
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1657
|
-
if (seq instanceof
|
|
1657
|
+
if (seq instanceof chunk3HZV3UHU_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
|
|
1658
1658
|
});
|
|
1659
1659
|
};
|
|
1660
1660
|
walk2(root, "", false, true);
|
|
@@ -1731,6 +1731,202 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1731
1731
|
return { frame, time, canvas, summary: { layers: layers.length, visible: layers.filter((l) => l.visible).length }, issues, layers: listed };
|
|
1732
1732
|
}
|
|
1733
1733
|
|
|
1734
|
+
// src/core/pick.ts
|
|
1735
|
+
var scratch;
|
|
1736
|
+
var saidBlind = /* @__PURE__ */ new Set();
|
|
1737
|
+
var readResourceAlpha = (resource, x, y) => {
|
|
1738
|
+
try {
|
|
1739
|
+
if (scratch === void 0) {
|
|
1740
|
+
const c = document.createElement("canvas");
|
|
1741
|
+
c.width = c.height = 1;
|
|
1742
|
+
scratch = c.getContext("2d", { willReadFrequently: true });
|
|
1743
|
+
}
|
|
1744
|
+
if (!scratch) return null;
|
|
1745
|
+
scratch.clearRect(0, 0, 1, 1);
|
|
1746
|
+
scratch.drawImage(resource, x, y, 1, 1, 0, 0, 1, 1);
|
|
1747
|
+
return scratch.getImageData(0, 0, 1, 1).data[3] / 255;
|
|
1748
|
+
} catch {
|
|
1749
|
+
return null;
|
|
1750
|
+
}
|
|
1751
|
+
};
|
|
1752
|
+
function pointInQuad(q, x, y) {
|
|
1753
|
+
let pos = 0, neg = 0;
|
|
1754
|
+
for (let i = 0; i < 4; i++) {
|
|
1755
|
+
const ax = q[i * 2], ay = q[i * 2 + 1], bx = q[(i + 1) % 4 * 2], by = q[(i + 1) % 4 * 2 + 1];
|
|
1756
|
+
const cross = (bx - ax) * (y - ay) - (by - ay) * (x - ax);
|
|
1757
|
+
if (cross > 0) pos++;
|
|
1758
|
+
else if (cross < 0) neg++;
|
|
1759
|
+
}
|
|
1760
|
+
return pos === 0 || neg === 0;
|
|
1761
|
+
}
|
|
1762
|
+
function orderOf(node) {
|
|
1763
|
+
const key = [];
|
|
1764
|
+
for (let n = node; n && n.parent; n = n.parent) {
|
|
1765
|
+
key.unshift([n.zIndex ?? 0, Math.max(0, n.parent.children?.indexOf(n) ?? 0)]);
|
|
1766
|
+
}
|
|
1767
|
+
return key;
|
|
1768
|
+
}
|
|
1769
|
+
var above = (a, b) => {
|
|
1770
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
1771
|
+
if (a[i][0] !== b[i][0]) return b[i][0] - a[i][0];
|
|
1772
|
+
if (a[i][1] !== b[i][1]) return b[i][1] - a[i][1];
|
|
1773
|
+
}
|
|
1774
|
+
return b.length - a.length;
|
|
1775
|
+
};
|
|
1776
|
+
function pickScene(root, x, y, opts = {}, deps = {}) {
|
|
1777
|
+
if (opts.alpha !== void 0 && !(opts.alpha >= 0 && opts.alpha <= 1)) throw new Error(`pixi-effects: pick: alpha must be a number from 0 to 1 (a pixel at or below it is not a hit), got ${opts.alpha}`);
|
|
1778
|
+
const readAlpha = deps.readAlpha ?? readResourceAlpha;
|
|
1779
|
+
const found = [];
|
|
1780
|
+
const names = (list, name, path) => list.some((e) => e === path || name !== void 0 && e === name || path.startsWith(e + "/") || path.split("/").slice(0, -1).includes(e));
|
|
1781
|
+
const wanted = (name, path) => {
|
|
1782
|
+
if (opts.ignore && names(opts.ignore, name, path)) return false;
|
|
1783
|
+
if (opts.only && !names(opts.only, name, path)) return false;
|
|
1784
|
+
return true;
|
|
1785
|
+
};
|
|
1786
|
+
const inside = (b, p) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
|
|
1787
|
+
const walk2 = (comp, prefix, parentVisible) => {
|
|
1788
|
+
comp.layers().forEach(({ seq, display, threeD, carriers, quad }, i) => {
|
|
1789
|
+
const d = display;
|
|
1790
|
+
if (!d) return;
|
|
1791
|
+
const t = seq.target;
|
|
1792
|
+
const name = seq.spec.name;
|
|
1793
|
+
const path = prefix + (name ?? `${seq.spec.type}#${i}`);
|
|
1794
|
+
const alpha = (t?.alpha ?? 1) * carriers.reduce((a, c) => a * (c.target?.alpha ?? 1), 1);
|
|
1795
|
+
const alive = (threeD ? d.visible : t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true);
|
|
1796
|
+
const visible = parentVisible && alive && alpha > 0;
|
|
1797
|
+
if (!visible) return;
|
|
1798
|
+
const isComposition = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
|
|
1799
|
+
if (isComposition && !threeD) {
|
|
1800
|
+
walk2(seq, path + "/", visible);
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
if (!wanted(name, path)) return;
|
|
1804
|
+
const point = { x, y };
|
|
1805
|
+
let hit = null;
|
|
1806
|
+
if (threeD) {
|
|
1807
|
+
if (quad && pointInQuad(quad, d.toLocal(point).x, d.toLocal(point).y)) hit = { name, path, type: seq.spec.type, kind: "card", point };
|
|
1808
|
+
} else {
|
|
1809
|
+
const local = d.toLocal(point);
|
|
1810
|
+
const lb = d.getLocalBounds();
|
|
1811
|
+
if (inside(lb, local)) {
|
|
1812
|
+
const three = typeof seq.pickAt === "function" ? seq.pickAt((local.x - lb.x) / lb.width, (local.y - lb.y) / lb.height) : void 0;
|
|
1813
|
+
if (three) {
|
|
1814
|
+
const planeOf = seq.dragPlane;
|
|
1815
|
+
if (planeOf) {
|
|
1816
|
+
three.grab = (plane = "screen") => {
|
|
1817
|
+
const along = planeOf.call(seq, three.point, plane);
|
|
1818
|
+
return { move: (cx, cy) => {
|
|
1819
|
+
const lp = d.toLocal({ x: cx, y: cy });
|
|
1820
|
+
const b = d.getLocalBounds();
|
|
1821
|
+
return along((lp.x - b.x) / b.width, (lp.y - b.y) / b.height);
|
|
1822
|
+
} };
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1825
|
+
hit = { name, path, type: seq.spec.type, kind: "three", point, three };
|
|
1826
|
+
} else if (three === void 0 && (typeof d.containsPoint !== "function" || d.containsPoint(local))) {
|
|
1827
|
+
let opaque = true;
|
|
1828
|
+
const tex = opts.alpha !== void 0 && seq.spec.type !== "shader" ? d.texture : void 0;
|
|
1829
|
+
if (tex?.source?.resource) {
|
|
1830
|
+
const res = tex.source.resolution ?? 1;
|
|
1831
|
+
const a = readAlpha(tex.source.resource, (tex.frame.x + (local.x - lb.x) / lb.width * tex.frame.width) * res, (tex.frame.y + (local.y - lb.y) / lb.height * tex.frame.height) * res);
|
|
1832
|
+
if (a === null) {
|
|
1833
|
+
if (!saidBlind.has(path)) {
|
|
1834
|
+
saidBlind.add(path);
|
|
1835
|
+
console.warn(`pixi-effects: pick: the picture of layer "${path}" cannot be read for { alpha } (a picture from another origin: load it with crossorigin="anonymous" or from the same site), so the box counts as the picture`);
|
|
1836
|
+
}
|
|
1837
|
+
} else opaque = a > opts.alpha;
|
|
1838
|
+
}
|
|
1839
|
+
if (opaque) hit = { name, path, type: seq.spec.type, kind: "flat", point, local: { x: local.x - lb.x, y: local.y - lb.y } };
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
if (!hit) return;
|
|
1844
|
+
const maskTarget = seq.maskSequence?.target;
|
|
1845
|
+
const maskSrc = chunk3HZV3UHU_cjs.maskSourceOf(seq.spec.mask);
|
|
1846
|
+
if (maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert) && !inside(maskTarget.getBounds(), point)) return;
|
|
1847
|
+
found.push({ hit, order: orderOf(d) });
|
|
1848
|
+
});
|
|
1849
|
+
};
|
|
1850
|
+
walk2(root, "", true);
|
|
1851
|
+
return found.sort((a, b) => above(a.order, b.order)).map((f) => f.hit);
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
// src/core/hover.ts
|
|
1855
|
+
var keyOf = (h) => h ? `${h.path}${h.three ? `#${h.three.object}` : ""}` : null;
|
|
1856
|
+
function startHover(host, opts = {}) {
|
|
1857
|
+
const { canvas } = host;
|
|
1858
|
+
const request = host.requestFrame ?? ((fn) => requestAnimationFrame(fn));
|
|
1859
|
+
const cancel = host.cancelFrame ?? ((id) => cancelAnimationFrame(id));
|
|
1860
|
+
const cursor = opts.cursor === true ? "pointer" : opts.cursor || "";
|
|
1861
|
+
const pickOpts = {};
|
|
1862
|
+
if (opts.only) pickOpts.only = opts.only;
|
|
1863
|
+
if (opts.ignore) pickOpts.ignore = opts.ignore;
|
|
1864
|
+
let current = null;
|
|
1865
|
+
let last = null;
|
|
1866
|
+
let loop = null;
|
|
1867
|
+
let said = false;
|
|
1868
|
+
const call = (fn, hit) => {
|
|
1869
|
+
if (!fn) return;
|
|
1870
|
+
try {
|
|
1871
|
+
fn(hit);
|
|
1872
|
+
} catch (err) {
|
|
1873
|
+
if (!said) {
|
|
1874
|
+
said = true;
|
|
1875
|
+
console.warn("pixi-effects: movie.hover: a handler threw (said once) \u2014", err);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
};
|
|
1879
|
+
const setCursor = (on) => {
|
|
1880
|
+
if (cursor) canvas.style.cursor = on ? cursor : "";
|
|
1881
|
+
};
|
|
1882
|
+
const evaluate = () => {
|
|
1883
|
+
if (!last) return;
|
|
1884
|
+
const [x, y] = host.point(last);
|
|
1885
|
+
const hit = host.pick(x, y, pickOpts);
|
|
1886
|
+
if (keyOf(hit) === keyOf(current)) {
|
|
1887
|
+
current = hit ?? current;
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
const was = current;
|
|
1891
|
+
current = hit;
|
|
1892
|
+
if (was) call(opts.onLeave, was);
|
|
1893
|
+
if (hit) call(opts.onEnter, hit);
|
|
1894
|
+
setCursor(!!hit);
|
|
1895
|
+
};
|
|
1896
|
+
const tick = () => {
|
|
1897
|
+
loop = null;
|
|
1898
|
+
if (last) {
|
|
1899
|
+
evaluate();
|
|
1900
|
+
loop = request(tick);
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
const onMove = (event) => {
|
|
1904
|
+
last = event;
|
|
1905
|
+
evaluate();
|
|
1906
|
+
if (loop === null) loop = request(tick);
|
|
1907
|
+
};
|
|
1908
|
+
const onLeave = () => {
|
|
1909
|
+
last = null;
|
|
1910
|
+
if (loop !== null) {
|
|
1911
|
+
cancel(loop);
|
|
1912
|
+
loop = null;
|
|
1913
|
+
}
|
|
1914
|
+
const was = current;
|
|
1915
|
+
current = null;
|
|
1916
|
+
if (was) call(opts.onLeave, was);
|
|
1917
|
+
setCursor(false);
|
|
1918
|
+
};
|
|
1919
|
+
canvas.addEventListener("pointermove", onMove);
|
|
1920
|
+
canvas.addEventListener("pointerdown", onMove);
|
|
1921
|
+
canvas.addEventListener("pointerleave", onLeave);
|
|
1922
|
+
return () => {
|
|
1923
|
+
canvas.removeEventListener("pointermove", onMove);
|
|
1924
|
+
canvas.removeEventListener("pointerdown", onMove);
|
|
1925
|
+
canvas.removeEventListener("pointerleave", onLeave);
|
|
1926
|
+
onLeave();
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1734
1930
|
// src/core/timelineChart.ts
|
|
1735
1931
|
var GROUP_MIN = 4;
|
|
1736
1932
|
var MAX_KEYS = 200;
|
|
@@ -1738,7 +1934,7 @@ var round = (n) => Math.round(n * 1e6) / 1e6;
|
|
|
1738
1934
|
var family = (name) => name.replace(/\d+/g, "#");
|
|
1739
1935
|
function detailOf(seq) {
|
|
1740
1936
|
const s = seq.spec;
|
|
1741
|
-
const spans =
|
|
1937
|
+
const spans = chunkX62H3RBG_cjs.spansMeta.get(seq.spec)?.preview;
|
|
1742
1938
|
if (spans) return spans.length > 60 ? spans.slice(0, 57) + "\u2026" : spans;
|
|
1743
1939
|
if (typeof s.text === "string") return s.text.length > 60 ? s.text.slice(0, 57) + "\u2026" : s.text;
|
|
1744
1940
|
if (typeof s.asset === "string") return `asset \u201C${s.asset}\u201D`;
|
|
@@ -1754,10 +1950,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
|
|
|
1754
1950
|
const start = parentStart + (seq.at ?? 0);
|
|
1755
1951
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
1756
1952
|
const span = end - start;
|
|
1757
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
1953
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkX62H3RBG_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
1758
1954
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
|
|
1759
1955
|
const inner = [];
|
|
1760
|
-
const isComp = seq instanceof
|
|
1956
|
+
const isComp = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
|
|
1761
1957
|
if (isComp) {
|
|
1762
1958
|
const label = seq.remapLabel();
|
|
1763
1959
|
walk(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
|
|
@@ -1916,7 +2112,7 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
|
1916
2112
|
}
|
|
1917
2113
|
|
|
1918
2114
|
// src/core/vars.ts
|
|
1919
|
-
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...
|
|
2115
|
+
var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunkX62H3RBG_cjs.EXPRESSION_NAMES];
|
|
1920
2116
|
var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1921
2117
|
var isPlain = (v) => !!v && typeof v === "object" && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
|
|
1922
2118
|
function normalizeVars(raw, where, warn = (m) => console.warn(m)) {
|
|
@@ -2455,8 +2651,8 @@ var Movie = class {
|
|
|
2455
2651
|
this.stops = normalizeStops(applyVars(options.composition, this._vars)?.stops, this.duration, this.frameRate);
|
|
2456
2652
|
this._posterFrame = poster.frame;
|
|
2457
2653
|
this.background = options.background ?? "#000000";
|
|
2458
|
-
this.timeline =
|
|
2459
|
-
|
|
2654
|
+
this.timeline = chunkX62H3RBG_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2655
|
+
chunkX62H3RBG_cjs.lengthen(this.timeline, this.duration);
|
|
2460
2656
|
const baseAppOptions = {
|
|
2461
2657
|
width: this.width,
|
|
2462
2658
|
height: this.height,
|
|
@@ -2550,7 +2746,7 @@ var Movie = class {
|
|
|
2550
2746
|
height: sizeWins ? height : spec.height ?? height,
|
|
2551
2747
|
duration: spec.duration ?? this.duration
|
|
2552
2748
|
} : void 0;
|
|
2553
|
-
await
|
|
2749
|
+
await chunkX62H3RBG_cjs.ensureFilterLibrary(seededComposition);
|
|
2554
2750
|
if (chunkJN7JHNZR_cjs.usesAdvancedBlend(seededComposition)) await chunkJN7JHNZR_cjs.enableAdvancedBlend(this.app.renderer);
|
|
2555
2751
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
2556
2752
|
const rootSeqSpec = {
|
|
@@ -2561,7 +2757,7 @@ var Movie = class {
|
|
|
2561
2757
|
...userComposition
|
|
2562
2758
|
};
|
|
2563
2759
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
2564
|
-
const sequence = new
|
|
2760
|
+
const sequence = new chunk3HZV3UHU_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
2565
2761
|
lp?.begin("build", countLayers(rootSeqSpec));
|
|
2566
2762
|
try {
|
|
2567
2763
|
await sequence.build();
|
|
@@ -2697,8 +2893,8 @@ var Movie = class {
|
|
|
2697
2893
|
if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
|
|
2698
2894
|
sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged);
|
|
2699
2895
|
alive();
|
|
2700
|
-
const timeline =
|
|
2701
|
-
|
|
2896
|
+
const timeline = chunkX62H3RBG_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
|
|
2897
|
+
chunkX62H3RBG_cjs.lengthen(timeline, this.duration);
|
|
2702
2898
|
sequence.bindTimeline(timeline);
|
|
2703
2899
|
const hadSound = this.audioBuffer !== null;
|
|
2704
2900
|
const audio = await this._mixSound(sequence, this._ensureAudioContext());
|
|
@@ -2785,6 +2981,14 @@ var Movie = class {
|
|
|
2785
2981
|
await this._goto(frame);
|
|
2786
2982
|
this.emit("seeked", { frame: this.currentFrame, totalFrames: this.totalFrames });
|
|
2787
2983
|
}
|
|
2984
|
+
/**
|
|
2985
|
+
* Draw the frame on screen again, quietly (no `seeking` / `seeked`). For a paused movie when something outside it that a layer reads has changed: a `three` layer whose `update` reads the page's own
|
|
2986
|
+
* state (a dragged object's place) shows it after `await movie.redraw()`. A playing movie needs no call: the next frame draws it.
|
|
2987
|
+
*/
|
|
2988
|
+
async redraw() {
|
|
2989
|
+
this._requireReady("redraw");
|
|
2990
|
+
await this._quietly(() => this.gotoFrame(this.currentFrame, true));
|
|
2991
|
+
}
|
|
2788
2992
|
/** Run `fn` with `seeking` / `seeked` silenced: the movie is moving its own playhead, not answering a seek. */
|
|
2789
2993
|
async _quietly(fn) {
|
|
2790
2994
|
this._quiet++;
|
|
@@ -2988,6 +3192,41 @@ var Movie = class {
|
|
|
2988
3192
|
* Where every layer is drawn at `frame` (canvas pixels, visibility) plus `issues` — text that is off
|
|
2989
3193
|
* the canvas, cut by an edge, empty, or overlapping other text. Seeks there and stays there.
|
|
2990
3194
|
*/
|
|
3195
|
+
/**
|
|
3196
|
+
* What is under the canvas point (x, y) (canvas pixels: the movie's own `width` x `height`; `canvasPoint(event)` makes them from a pointer event) at the frame on screen: the layer on
|
|
3197
|
+
* top, or null. A flat layer is hit by its own shape, a `threeD` card by its projected quad, a `three` layer by a ray through its camera (`hit.three` has the object). It reads the
|
|
3198
|
+
* frame as the last draw left it, so after `await movie.snapshot(frame)` or any seek it answers for that frame. `opts.only` / `opts.ignore`: layer names or paths.
|
|
3199
|
+
*/
|
|
3200
|
+
pick(x, y, opts = {}) {
|
|
3201
|
+
return this.pickAll(x, y, opts)[0] ?? null;
|
|
3202
|
+
}
|
|
3203
|
+
/** Every layer under the canvas point, the one on top first (see `pick`). */
|
|
3204
|
+
pickAll(x, y, opts = {}) {
|
|
3205
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.pick()", opts, ["only", "ignore", "alpha"]);
|
|
3206
|
+
this._requireReady("pick");
|
|
3207
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) throw new Error(`pixi-effects: movie.pick(x, y) needs two numbers (canvas pixels), got ${x}, ${y}. For a pointer event: movie.pick(...movie.canvasPoint(event))`);
|
|
3208
|
+
return pickScene(this._rootSequence, x, y, opts);
|
|
3209
|
+
}
|
|
3210
|
+
/**
|
|
3211
|
+
* Which layer the pointer is over, as callbacks: `onEnter(hit)` when the layer (or, in a `three` layer, the object) under the pointer changes to another, `onLeave(hit)` for the one it
|
|
3212
|
+
* left (also when the pointer leaves the picture). While the pointer rests inside, it is asked again on every frame, so a picture that moves under a still pointer is followed.
|
|
3213
|
+
* `{ only, ignore }` as for `pick`; `cursor: true` (or a CSS cursor) shows it while something is hovered. Returns the function that stops it. A page-side tool: an exported video has no pointer.
|
|
3214
|
+
*/
|
|
3215
|
+
hover(opts = {}) {
|
|
3216
|
+
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.hover()", opts, ["onEnter", "onLeave", "cursor", "only", "ignore"]);
|
|
3217
|
+
this._requireReady("hover");
|
|
3218
|
+
const canvas = this.app?.canvas;
|
|
3219
|
+
if (!canvas) throw new Error("pixi-effects: movie.hover needs the movie's canvas");
|
|
3220
|
+
return startHover({ canvas, pick: (x, y, o) => this.pick(x, y, o), point: (e) => this.canvasPoint(e) }, opts);
|
|
3221
|
+
}
|
|
3222
|
+
/** A pointer event's place in canvas pixels (the canvas may be shown larger or smaller than its own size): `movie.pick(...movie.canvasPoint(event))`. */
|
|
3223
|
+
canvasPoint(event) {
|
|
3224
|
+
this._requireReady("canvasPoint");
|
|
3225
|
+
const canvas = this.app?.canvas;
|
|
3226
|
+
if (!canvas) throw new Error("pixi-effects: movie.canvasPoint needs the movie's canvas");
|
|
3227
|
+
const r = canvas.getBoundingClientRect();
|
|
3228
|
+
return [(event.clientX - r.left) * this.width / (r.width || this.width), (event.clientY - r.top) * this.height / (r.height || this.height)];
|
|
3229
|
+
}
|
|
2991
3230
|
async inspect(frame = this.currentFrame, opts = { layers: "visible" }) {
|
|
2992
3231
|
chunkTWZNOUM7_cjs.warnUnknownOptions("movie.inspect()", opts, ["layers"]);
|
|
2993
3232
|
this._requireReady("inspect");
|
|
@@ -3422,7 +3661,7 @@ function countLayers(spec) {
|
|
|
3422
3661
|
n += 1 + countLayers(s);
|
|
3423
3662
|
const spans = s.spans;
|
|
3424
3663
|
if (Array.isArray(spans)) n += spans.length;
|
|
3425
|
-
const src =
|
|
3664
|
+
const src = chunk3HZV3UHU_cjs.maskSourceOf(mask);
|
|
3426
3665
|
if (src.kind === "inline") n += 1 + countLayers(src.spec);
|
|
3427
3666
|
}
|
|
3428
3667
|
return n;
|
|
@@ -3511,8 +3750,8 @@ function splitVertical(text, style, ts, right, top, align, by) {
|
|
|
3511
3750
|
|
|
3512
3751
|
// src/presets/_ease.ts
|
|
3513
3752
|
function parseEase2(name) {
|
|
3514
|
-
|
|
3515
|
-
return
|
|
3753
|
+
chunkX62H3RBG_cjs.checkEase(name, "a preset");
|
|
3754
|
+
return chunkX62H3RBG_cjs.parseEase(name);
|
|
3516
3755
|
}
|
|
3517
3756
|
|
|
3518
3757
|
// src/presets/kenBurns.ts
|
|
@@ -3647,17 +3886,17 @@ function orbit(opts) {
|
|
|
3647
3886
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
3648
3887
|
}
|
|
3649
3888
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
3650
|
-
const fixedR = opts.radius ??
|
|
3889
|
+
const fixedR = opts.radius ?? chunkX62H3RBG_cjs.homeDistance(height, fov ?? chunkX62H3RBG_cjs.DEFAULT_FOV);
|
|
3651
3890
|
const start = opts.start ?? -degrees / 2;
|
|
3652
3891
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
3653
3892
|
const easeFn = parseEase2(ease);
|
|
3654
3893
|
const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
|
|
3655
3894
|
const pos = (i) => {
|
|
3656
3895
|
const p = i / steps;
|
|
3657
|
-
const a = (start + degrees * easeFn(p)) *
|
|
3896
|
+
const a = (start + degrees * easeFn(p)) * chunkX62H3RBG_cjs.DEG;
|
|
3658
3897
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
3659
3898
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
3660
|
-
const R =
|
|
3899
|
+
const R = chunkX62H3RBG_cjs.homeDistance(height, f);
|
|
3661
3900
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
3662
3901
|
};
|
|
3663
3902
|
const keyframes = [];
|
|
@@ -3712,7 +3951,7 @@ function particles(opts) {
|
|
|
3712
3951
|
const round2 = (v) => Math.round(v * 1e6) / 1e6;
|
|
3713
3952
|
const out = [];
|
|
3714
3953
|
for (let i = 0; i < count; i++) {
|
|
3715
|
-
const r =
|
|
3954
|
+
const r = chunkX62H3RBG_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
3716
3955
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
3717
3956
|
const born = at + r() * emit;
|
|
3718
3957
|
const lifetime = pick(life);
|
|
@@ -3725,7 +3964,7 @@ function particles(opts) {
|
|
|
3725
3964
|
const turn = spin ? pick(spin) : 0;
|
|
3726
3965
|
const startAngle = spin ? r() * 360 : 0;
|
|
3727
3966
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
3728
|
-
const n0 = sway ?
|
|
3967
|
+
const n0 = sway ? chunkX62H3RBG_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
3729
3968
|
const at_ = (t) => {
|
|
3730
3969
|
const axis = (p0, v0, acc) => {
|
|
3731
3970
|
if (drag > 0) {
|
|
@@ -3734,7 +3973,7 @@ function particles(opts) {
|
|
|
3734
3973
|
}
|
|
3735
3974
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
3736
3975
|
};
|
|
3737
|
-
const sw = sway ? swayAmp * (
|
|
3976
|
+
const sw = sway ? swayAmp * (chunkX62H3RBG_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
3738
3977
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
3739
3978
|
};
|
|
3740
3979
|
const kfs = [];
|
|
@@ -3796,7 +4035,7 @@ function followPath(opts) {
|
|
|
3796
4035
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
3797
4036
|
const segments = [];
|
|
3798
4037
|
let total = 0;
|
|
3799
|
-
for (const line of
|
|
4038
|
+
for (const line of chunkX62H3RBG_cjs.flattenSvgPath(d)) {
|
|
3800
4039
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
3801
4040
|
for (let i = 2; i < p.length; i += 2) {
|
|
3802
4041
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -3849,7 +4088,7 @@ function followPath(opts) {
|
|
|
3849
4088
|
// src/core/pathSample.ts
|
|
3850
4089
|
function samplePath(d) {
|
|
3851
4090
|
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"');
|
|
3852
|
-
const lines =
|
|
4091
|
+
const lines = chunkX62H3RBG_cjs.flattenSvgPath(d);
|
|
3853
4092
|
const segments = [];
|
|
3854
4093
|
let length = 0;
|
|
3855
4094
|
for (const line of lines) {
|
|
@@ -3880,7 +4119,7 @@ function samplePath(d) {
|
|
|
3880
4119
|
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) };
|
|
3881
4120
|
},
|
|
3882
4121
|
trim(start = 0, end = 1) {
|
|
3883
|
-
return
|
|
4122
|
+
return chunkX62H3RBG_cjs.trimPolylines(lines, start, end).map((l) => l.closed ? [...l.pts, l.pts[0], l.pts[1]] : l.pts);
|
|
3884
4123
|
}
|
|
3885
4124
|
};
|
|
3886
4125
|
}
|
|
@@ -3989,7 +4228,7 @@ function distances(n, from, grid, seed) {
|
|
|
3989
4228
|
if (n === 0) return [];
|
|
3990
4229
|
if (from === "random") {
|
|
3991
4230
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
3992
|
-
const r =
|
|
4231
|
+
const r = chunkX62H3RBG_cjs.random(seed);
|
|
3993
4232
|
for (let i = n - 1; i > 0; i--) {
|
|
3994
4233
|
const j = Math.floor(r() * (i + 1));
|
|
3995
4234
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -4051,7 +4290,7 @@ function wiggle(opts) {
|
|
|
4051
4290
|
to[n] = p.around;
|
|
4052
4291
|
return;
|
|
4053
4292
|
}
|
|
4054
|
-
const off = (
|
|
4293
|
+
const off = (chunkX62H3RBG_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
4055
4294
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
4056
4295
|
});
|
|
4057
4296
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -4510,5 +4749,5 @@ exports.splitText = splitText;
|
|
|
4510
4749
|
exports.stagger = stagger;
|
|
4511
4750
|
exports.wiggle = wiggle;
|
|
4512
4751
|
exports.withFade = withFade;
|
|
4513
|
-
//# sourceMappingURL=chunk-
|
|
4514
|
-
//# sourceMappingURL=chunk-
|
|
4752
|
+
//# sourceMappingURL=chunk-WVZLAIKK.cjs.map
|
|
4753
|
+
//# sourceMappingURL=chunk-WVZLAIKK.cjs.map
|