pixi-effects 0.40.0 → 0.41.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +5 -5
  3. package/ai/chat-template.html +3 -3
  4. package/ai/tools/check.mjs +19 -2
  5. package/dist/Composition-N6BOROJ2.cjs +16 -0
  6. package/dist/{Composition-C3UEVHQG.cjs.map → Composition-N6BOROJ2.cjs.map} +1 -1
  7. package/dist/Composition-YGBQX3HZ.js +7 -0
  8. package/dist/{Composition-KRWH72MA.js.map → Composition-YGBQX3HZ.js.map} +1 -1
  9. package/dist/Controller.d.cts +1 -1
  10. package/dist/Controller.d.ts +1 -1
  11. package/dist/{Movie-CG6Jy1tx.d.ts → Movie-CwqRLOzE.d.ts} +47 -1
  12. package/dist/{Movie-CMq4KFmc.d.cts → Movie-DWtxRiJ2.d.cts} +47 -1
  13. package/dist/{Spans-TWO4VN5H.js → Spans-6L2ZVECX.js} +4 -4
  14. package/dist/{Spans-TWO4VN5H.js.map → Spans-6L2ZVECX.js.map} +1 -1
  15. package/dist/{Spans-APNJHCYO.cjs → Spans-XTIWYSNO.cjs} +9 -9
  16. package/dist/{Spans-APNJHCYO.cjs.map → Spans-XTIWYSNO.cjs.map} +1 -1
  17. package/dist/{chunk-27PYJ4JY.cjs → chunk-3HZV3UHU.cjs} +67 -63
  18. package/dist/chunk-3HZV3UHU.cjs.map +1 -0
  19. package/dist/{chunk-LMWXR5OC.js → chunk-4QVQ5UJJ.js} +4 -4
  20. package/dist/{chunk-LMWXR5OC.js.map → chunk-4QVQ5UJJ.js.map} +1 -1
  21. package/dist/{chunk-26Z544SH.js → chunk-ICI6ACHY.js} +7 -3
  22. package/dist/chunk-ICI6ACHY.js.map +1 -0
  23. package/dist/{chunk-LEL7UNYQ.cjs → chunk-RN5FWGGM.cjs} +136 -39
  24. package/dist/chunk-RN5FWGGM.cjs.map +1 -0
  25. package/dist/{chunk-7EI2N7WO.cjs → chunk-X62H3RBG.cjs} +4 -4
  26. package/dist/{chunk-7EI2N7WO.cjs.map → chunk-X62H3RBG.cjs.map} +1 -1
  27. package/dist/{chunk-CT5CZVT5.js → chunk-Y2N6U3X5.js} +101 -4
  28. package/dist/chunk-Y2N6U3X5.js.map +1 -0
  29. package/dist/index.cjs +33 -33
  30. package/dist/index.d.cts +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +3 -3
  33. package/dist/loader.css +1 -1
  34. package/dist/present.cjs +3 -3
  35. package/dist/present.d.cts +1 -1
  36. package/dist/present.d.ts +1 -1
  37. package/dist/present.js +3 -3
  38. package/dist/three.cjs +52 -6
  39. package/dist/three.cjs.map +1 -1
  40. package/dist/three.d.cts +16 -1
  41. package/dist/three.d.ts +16 -1
  42. package/dist/three.js +49 -3
  43. package/dist/three.js.map +1 -1
  44. package/docs/api.md +17 -0
  45. package/docs/dsl.md +1 -1
  46. package/llms-full.txt +44 -3
  47. package/package.json +1 -1
  48. package/skills/pixi-effects/SKILL.md +2 -2
  49. package/skills/pixi-effects/reference/cheatsheet.md +1 -0
  50. package/skills/pixi-effects/reference/recipes.md +23 -0
  51. package/skills/pixi-effects/template.html +6 -6
  52. package/dist/Composition-C3UEVHQG.cjs +0 -16
  53. package/dist/Composition-KRWH72MA.js +0 -7
  54. package/dist/chunk-26Z544SH.js.map +0 -1
  55. package/dist/chunk-27PYJ4JY.cjs.map +0 -1
  56. package/dist/chunk-CT5CZVT5.js.map +0 -1
  57. package/dist/chunk-LEL7UNYQ.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk27PYJ4JY_cjs = require('./chunk-27PYJ4JY.cjs');
4
- var chunk7EI2N7WO_cjs = require('./chunk-7EI2N7WO.cjs');
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 ? chunk7EI2N7WO_cjs.timeRemapOf(out) : null;
1109
- const parentDuration = remap ? chunk7EI2N7WO_cjs.contentLength(remap, out.duration) : out.duration ?? Infinity;
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 = chunk7EI2N7WO_cjs.resolveAt(t.at, parentDuration);
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 = chunk7EI2N7WO_cjs.resolveAt(fromSeq.at, parentDuration);
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 = chunk7EI2N7WO_cjs.resolveAt(toSeq.at, parentDuration);
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 && chunk27PYJ4JY_cjs.maskSourceOf(m).kind === "refs";
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 chunk27PYJ4JY_cjs.CompositionSequence) walk2(seq);
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 = chunk7EI2N7WO_cjs.parseSpring(kf.ease);
1569
- length = sp ? Math.round(chunk7EI2N7WO_cjs.springDuration(sp) * 1e3) / 1e3 : 0.5;
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 = chunk27PYJ4JY_cjs.maskSourceOf(seq.spec.mask);
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 chunk27PYJ4JY_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, motion, zero, parentAlpha * alpha);
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,80 @@ 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
+ function pointInQuad(q, x, y) {
1736
+ let pos = 0, neg = 0;
1737
+ for (let i = 0; i < 4; i++) {
1738
+ const ax = q[i * 2], ay = q[i * 2 + 1], bx = q[(i + 1) % 4 * 2], by = q[(i + 1) % 4 * 2 + 1];
1739
+ const cross = (bx - ax) * (y - ay) - (by - ay) * (x - ax);
1740
+ if (cross > 0) pos++;
1741
+ else if (cross < 0) neg++;
1742
+ }
1743
+ return pos === 0 || neg === 0;
1744
+ }
1745
+ function orderOf(node) {
1746
+ const key = [];
1747
+ for (let n = node; n && n.parent; n = n.parent) {
1748
+ key.unshift([n.zIndex ?? 0, Math.max(0, n.parent.children?.indexOf(n) ?? 0)]);
1749
+ }
1750
+ return key;
1751
+ }
1752
+ var above = (a, b) => {
1753
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
1754
+ if (a[i][0] !== b[i][0]) return b[i][0] - a[i][0];
1755
+ if (a[i][1] !== b[i][1]) return b[i][1] - a[i][1];
1756
+ }
1757
+ return b.length - a.length;
1758
+ };
1759
+ function pickScene(root, x, y, opts = {}) {
1760
+ const found = [];
1761
+ const wanted = (name, path) => {
1762
+ if (opts.ignore && (opts.ignore.includes(path) || name !== void 0 && opts.ignore.includes(name))) return false;
1763
+ if (opts.only && !(opts.only.includes(path) || name !== void 0 && opts.only.includes(name))) return false;
1764
+ return true;
1765
+ };
1766
+ const inside = (b, p) => p.x >= b.x && p.x <= b.x + b.width && p.y >= b.y && p.y <= b.y + b.height;
1767
+ const walk2 = (comp, prefix, parentVisible) => {
1768
+ comp.layers().forEach(({ seq, display, threeD, carriers, quad }, i) => {
1769
+ const d = display;
1770
+ if (!d) return;
1771
+ const t = seq.target;
1772
+ const name = seq.spec.name;
1773
+ const path = prefix + (name ?? `${seq.spec.type}#${i}`);
1774
+ const alpha = (t?.alpha ?? 1) * carriers.reduce((a, c) => a * (c.target?.alpha ?? 1), 1);
1775
+ const alive = (threeD ? d.visible : t?.renderable ?? true) && carriers.every((c) => c.target?.renderable ?? true);
1776
+ const visible = parentVisible && alive && alpha > 0;
1777
+ if (!visible) return;
1778
+ const isComposition = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
1779
+ if (isComposition && !threeD) {
1780
+ walk2(seq, path + "/", visible);
1781
+ return;
1782
+ }
1783
+ if (!wanted(name, path)) return;
1784
+ const point = { x, y };
1785
+ let hit = null;
1786
+ if (threeD) {
1787
+ if (quad && pointInQuad(quad, d.toLocal(point).x, d.toLocal(point).y)) hit = { name, path, type: seq.spec.type, kind: "card", point };
1788
+ } else {
1789
+ const local = d.toLocal(point);
1790
+ const lb = d.getLocalBounds();
1791
+ if (inside(lb, local)) {
1792
+ const three = typeof seq.pickAt === "function" ? seq.pickAt((local.x - lb.x) / lb.width, (local.y - lb.y) / lb.height) : void 0;
1793
+ if (three) hit = { name, path, type: seq.spec.type, kind: "three", point, three };
1794
+ else if (three === void 0 && (typeof d.containsPoint !== "function" || d.containsPoint(local))) hit = { name, path, type: seq.spec.type, kind: "flat", point, local: { x: local.x - lb.x, y: local.y - lb.y } };
1795
+ }
1796
+ }
1797
+ if (!hit) return;
1798
+ const maskTarget = seq.maskSequence?.target;
1799
+ const maskSrc = chunk3HZV3UHU_cjs.maskSourceOf(seq.spec.mask);
1800
+ if (maskTarget && !(maskSrc.kind === "inline" && maskSrc.invert) && !inside(maskTarget.getBounds(), point)) return;
1801
+ found.push({ hit, order: orderOf(d) });
1802
+ });
1803
+ };
1804
+ walk2(root, "", true);
1805
+ return found.sort((a, b) => above(a.order, b.order)).map((f) => f.hit);
1806
+ }
1807
+
1734
1808
  // src/core/timelineChart.ts
1735
1809
  var GROUP_MIN = 4;
1736
1810
  var MAX_KEYS = 200;
@@ -1738,7 +1812,7 @@ var round = (n) => Math.round(n * 1e6) / 1e6;
1738
1812
  var family = (name) => name.replace(/\d+/g, "#");
1739
1813
  function detailOf(seq) {
1740
1814
  const s = seq.spec;
1741
- const spans = chunk7EI2N7WO_cjs.spansMeta.get(seq.spec)?.preview;
1815
+ const spans = chunkX62H3RBG_cjs.spansMeta.get(seq.spec)?.preview;
1742
1816
  if (spans) return spans.length > 60 ? spans.slice(0, 57) + "\u2026" : spans;
1743
1817
  if (typeof s.text === "string") return s.text.length > 60 ? s.text.slice(0, 57) + "\u2026" : s.text;
1744
1818
  if (typeof s.asset === "string") return `asset \u201C${s.asset}\u201D`;
@@ -1754,10 +1828,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions, lo
1754
1828
  const start = parentStart + (seq.at ?? 0);
1755
1829
  const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
1756
1830
  const span = end - start;
1757
- const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunk7EI2N7WO_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
1831
+ 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
1832
  const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq), ...local ? { local } : {} };
1759
1833
  const inner = [];
1760
- const isComp = seq instanceof chunk27PYJ4JY_cjs.CompositionSequence;
1834
+ const isComp = seq instanceof chunk3HZV3UHU_cjs.CompositionSequence;
1761
1835
  if (isComp) {
1762
1836
  const label = seq.remapLabel();
1763
1837
  walk(seq, label ? 0 : start, label ? seq.contentSpan : end, depth + 1, prefix + name + "/", inner, transitions, label ? `${name} ${label}` : local);
@@ -1916,7 +1990,7 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
1916
1990
  }
1917
1991
 
1918
1992
  // src/core/vars.ts
1919
- var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunk7EI2N7WO_cjs.EXPRESSION_NAMES];
1993
+ var RESERVED_NAMES = ["w", "h", "W", "H", "GW", "GH", "t", "d", "T", "contain", "cover", "value", ...chunkX62H3RBG_cjs.EXPRESSION_NAMES];
1920
1994
  var NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
1921
1995
  var isPlain = (v) => !!v && typeof v === "object" && (Object.getPrototypeOf(v) === Object.prototype || Object.getPrototypeOf(v) === null);
1922
1996
  function normalizeVars(raw, where, warn = (m) => console.warn(m)) {
@@ -2455,8 +2529,8 @@ var Movie = class {
2455
2529
  this.stops = normalizeStops(applyVars(options.composition, this._vars)?.stops, this.duration, this.frameRate);
2456
2530
  this._posterFrame = poster.frame;
2457
2531
  this.background = options.background ?? "#000000";
2458
- this.timeline = chunk7EI2N7WO_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
2459
- chunk7EI2N7WO_cjs.lengthen(this.timeline, this.duration);
2532
+ this.timeline = chunkX62H3RBG_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
2533
+ chunkX62H3RBG_cjs.lengthen(this.timeline, this.duration);
2460
2534
  const baseAppOptions = {
2461
2535
  width: this.width,
2462
2536
  height: this.height,
@@ -2550,7 +2624,7 @@ var Movie = class {
2550
2624
  height: sizeWins ? height : spec.height ?? height,
2551
2625
  duration: spec.duration ?? this.duration
2552
2626
  } : void 0;
2553
- await chunk7EI2N7WO_cjs.ensureFilterLibrary(seededComposition);
2627
+ await chunkX62H3RBG_cjs.ensureFilterLibrary(seededComposition);
2554
2628
  if (chunkJN7JHNZR_cjs.usesAdvancedBlend(seededComposition)) await chunkJN7JHNZR_cjs.enableAdvancedBlend(this.app.renderer);
2555
2629
  const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
2556
2630
  const rootSeqSpec = {
@@ -2561,7 +2635,7 @@ var Movie = class {
2561
2635
  ...userComposition
2562
2636
  };
2563
2637
  if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
2564
- const sequence = new chunk27PYJ4JY_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
2638
+ const sequence = new chunk3HZV3UHU_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
2565
2639
  lp?.begin("build", countLayers(rootSeqSpec));
2566
2640
  try {
2567
2641
  await sequence.build();
@@ -2697,8 +2771,8 @@ var Movie = class {
2697
2771
  if (!changed) return { reason, ms: 0, audio: "none", frame: this.currentFrame, playing: this.isPlaying, unchanged: true };
2698
2772
  sequence = await this._construct(composition, vars, width, height, void 0, this._resized || sizeChanged);
2699
2773
  alive();
2700
- const timeline = chunk7EI2N7WO_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
2701
- chunk7EI2N7WO_cjs.lengthen(timeline, this.duration);
2774
+ const timeline = chunkX62H3RBG_cjs.createTimeline({ paused: true, defaults: { ease: "none" } });
2775
+ chunkX62H3RBG_cjs.lengthen(timeline, this.duration);
2702
2776
  sequence.bindTimeline(timeline);
2703
2777
  const hadSound = this.audioBuffer !== null;
2704
2778
  const audio = await this._mixSound(sequence, this._ensureAudioContext());
@@ -2988,6 +3062,29 @@ var Movie = class {
2988
3062
  * Where every layer is drawn at `frame` (canvas pixels, visibility) plus `issues` — text that is off
2989
3063
  * the canvas, cut by an edge, empty, or overlapping other text. Seeks there and stays there.
2990
3064
  */
3065
+ /**
3066
+ * 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
3067
+ * 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
3068
+ * 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.
3069
+ */
3070
+ pick(x, y, opts = {}) {
3071
+ return this.pickAll(x, y, opts)[0] ?? null;
3072
+ }
3073
+ /** Every layer under the canvas point, the one on top first (see `pick`). */
3074
+ pickAll(x, y, opts = {}) {
3075
+ chunkTWZNOUM7_cjs.warnUnknownOptions("movie.pick()", opts, ["only", "ignore"]);
3076
+ this._requireReady("pick");
3077
+ 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))`);
3078
+ return pickScene(this._rootSequence, x, y, opts);
3079
+ }
3080
+ /** 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))`. */
3081
+ canvasPoint(event) {
3082
+ this._requireReady("canvasPoint");
3083
+ const canvas = this.app?.canvas;
3084
+ if (!canvas) throw new Error("pixi-effects: movie.canvasPoint needs the movie's canvas");
3085
+ const r = canvas.getBoundingClientRect();
3086
+ return [(event.clientX - r.left) * this.width / (r.width || this.width), (event.clientY - r.top) * this.height / (r.height || this.height)];
3087
+ }
2991
3088
  async inspect(frame = this.currentFrame, opts = { layers: "visible" }) {
2992
3089
  chunkTWZNOUM7_cjs.warnUnknownOptions("movie.inspect()", opts, ["layers"]);
2993
3090
  this._requireReady("inspect");
@@ -3422,7 +3519,7 @@ function countLayers(spec) {
3422
3519
  n += 1 + countLayers(s);
3423
3520
  const spans = s.spans;
3424
3521
  if (Array.isArray(spans)) n += spans.length;
3425
- const src = chunk27PYJ4JY_cjs.maskSourceOf(mask);
3522
+ const src = chunk3HZV3UHU_cjs.maskSourceOf(mask);
3426
3523
  if (src.kind === "inline") n += 1 + countLayers(src.spec);
3427
3524
  }
3428
3525
  return n;
@@ -3511,8 +3608,8 @@ function splitVertical(text, style, ts, right, top, align, by) {
3511
3608
 
3512
3609
  // src/presets/_ease.ts
3513
3610
  function parseEase2(name) {
3514
- chunk7EI2N7WO_cjs.checkEase(name, "a preset");
3515
- return chunk7EI2N7WO_cjs.parseEase(name);
3611
+ chunkX62H3RBG_cjs.checkEase(name, "a preset");
3612
+ return chunkX62H3RBG_cjs.parseEase(name);
3516
3613
  }
3517
3614
 
3518
3615
  // src/presets/kenBurns.ts
@@ -3647,17 +3744,17 @@ function orbit(opts) {
3647
3744
  throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
3648
3745
  }
3649
3746
  const [cx, cy] = opts.center ?? [width / 2, height / 2];
3650
- const fixedR = opts.radius ?? chunk7EI2N7WO_cjs.homeDistance(height, fov ?? chunk7EI2N7WO_cjs.DEFAULT_FOV);
3747
+ const fixedR = opts.radius ?? chunkX62H3RBG_cjs.homeDistance(height, fov ?? chunkX62H3RBG_cjs.DEFAULT_FOV);
3651
3748
  const start = opts.start ?? -degrees / 2;
3652
3749
  const steps = Math.max(1, Math.round(duration * stepsPerSecond));
3653
3750
  const easeFn = parseEase2(ease);
3654
3751
  const dollyEase = dolly ? parseEase2(dolly.ease ?? ease) : null;
3655
3752
  const pos = (i) => {
3656
3753
  const p = i / steps;
3657
- const a = (start + degrees * easeFn(p)) * chunk7EI2N7WO_cjs.DEG;
3754
+ const a = (start + degrees * easeFn(p)) * chunkX62H3RBG_cjs.DEG;
3658
3755
  if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
3659
3756
  const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
3660
- const R = chunk7EI2N7WO_cjs.homeDistance(height, f);
3757
+ const R = chunkX62H3RBG_cjs.homeDistance(height, f);
3661
3758
  return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
3662
3759
  };
3663
3760
  const keyframes = [];
@@ -3712,7 +3809,7 @@ function particles(opts) {
3712
3809
  const round2 = (v) => Math.round(v * 1e6) / 1e6;
3713
3810
  const out = [];
3714
3811
  for (let i = 0; i < count; i++) {
3715
- const r = chunk7EI2N7WO_cjs.random(seed * 1000003 + i * 7919 + 17);
3812
+ const r = chunkX62H3RBG_cjs.random(seed * 1000003 + i * 7919 + 17);
3716
3813
  const pick = ([a2, b]) => a2 + r() * (b - a2);
3717
3814
  const born = at + r() * emit;
3718
3815
  const lifetime = pick(life);
@@ -3725,7 +3822,7 @@ function particles(opts) {
3725
3822
  const turn = spin ? pick(spin) : 0;
3726
3823
  const startAngle = spin ? r() * 360 : 0;
3727
3824
  const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
3728
- const n0 = sway ? chunk7EI2N7WO_cjs.noise(0, seed * 1000003 + i) : 0;
3825
+ const n0 = sway ? chunkX62H3RBG_cjs.noise(0, seed * 1000003 + i) : 0;
3729
3826
  const at_ = (t) => {
3730
3827
  const axis = (p0, v0, acc) => {
3731
3828
  if (drag > 0) {
@@ -3734,7 +3831,7 @@ function particles(opts) {
3734
3831
  }
3735
3832
  return p0 + v0 * t + 0.5 * acc * t * t;
3736
3833
  };
3737
- const sw = sway ? swayAmp * (chunk7EI2N7WO_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
3834
+ const sw = sway ? swayAmp * (chunkX62H3RBG_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
3738
3835
  return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
3739
3836
  };
3740
3837
  const kfs = [];
@@ -3796,7 +3893,7 @@ function followPath(opts) {
3796
3893
  if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
3797
3894
  const segments = [];
3798
3895
  let total = 0;
3799
- for (const line of chunk7EI2N7WO_cjs.flattenSvgPath(d)) {
3896
+ for (const line of chunkX62H3RBG_cjs.flattenSvgPath(d)) {
3800
3897
  const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
3801
3898
  for (let i = 2; i < p.length; i += 2) {
3802
3899
  const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
@@ -3849,7 +3946,7 @@ function followPath(opts) {
3849
3946
  // src/core/pathSample.ts
3850
3947
  function samplePath(d) {
3851
3948
  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 = chunk7EI2N7WO_cjs.flattenSvgPath(d);
3949
+ const lines = chunkX62H3RBG_cjs.flattenSvgPath(d);
3853
3950
  const segments = [];
3854
3951
  let length = 0;
3855
3952
  for (const line of lines) {
@@ -3880,7 +3977,7 @@ function samplePath(d) {
3880
3977
  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
3978
  },
3882
3979
  trim(start = 0, end = 1) {
3883
- return chunk7EI2N7WO_cjs.trimPolylines(lines, start, end).map((l) => l.closed ? [...l.pts, l.pts[0], l.pts[1]] : l.pts);
3980
+ return chunkX62H3RBG_cjs.trimPolylines(lines, start, end).map((l) => l.closed ? [...l.pts, l.pts[0], l.pts[1]] : l.pts);
3884
3981
  }
3885
3982
  };
3886
3983
  }
@@ -3989,7 +4086,7 @@ function distances(n, from, grid, seed) {
3989
4086
  if (n === 0) return [];
3990
4087
  if (from === "random") {
3991
4088
  const order = Array.from({ length: n }, (_, i) => i);
3992
- const r = chunk7EI2N7WO_cjs.random(seed);
4089
+ const r = chunkX62H3RBG_cjs.random(seed);
3993
4090
  for (let i = n - 1; i > 0; i--) {
3994
4091
  const j = Math.floor(r() * (i + 1));
3995
4092
  [order[i], order[j]] = [order[j], order[i]];
@@ -4051,7 +4148,7 @@ function wiggle(opts) {
4051
4148
  to[n] = p.around;
4052
4149
  return;
4053
4150
  }
4054
- const off = (chunk7EI2N7WO_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
4151
+ const off = (chunkX62H3RBG_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
4055
4152
  to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
4056
4153
  });
4057
4154
  out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
@@ -4510,5 +4607,5 @@ exports.splitText = splitText;
4510
4607
  exports.stagger = stagger;
4511
4608
  exports.wiggle = wiggle;
4512
4609
  exports.withFade = withFade;
4513
- //# sourceMappingURL=chunk-LEL7UNYQ.cjs.map
4514
- //# sourceMappingURL=chunk-LEL7UNYQ.cjs.map
4610
+ //# sourceMappingURL=chunk-RN5FWGGM.cjs.map
4611
+ //# sourceMappingURL=chunk-RN5FWGGM.cjs.map