pixi-effects 0.5.0 → 0.6.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 (48) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -6
  3. package/ai/reference/cheatsheet.md +3 -1
  4. package/ai/reference/pitfalls.md +1 -0
  5. package/ai/reference/recipes.md +36 -1
  6. package/ai/template.html +3 -3
  7. package/dist/{Base-DnRAxroQ.d.cts → Base-4vNLl4tH.d.cts} +1 -1
  8. package/dist/{Base-CPSFBkPm.d.ts → Base-CD4AoT5-.d.ts} +1 -1
  9. package/dist/Composition-7SO5WYHU.js +4 -0
  10. package/dist/{Composition-TUCRSMJU.js.map → Composition-7SO5WYHU.js.map} +1 -1
  11. package/dist/Composition-Y5VZSDDP.cjs +13 -0
  12. package/dist/{Composition-63EXHNJJ.cjs.map → Composition-Y5VZSDDP.cjs.map} +1 -1
  13. package/dist/Controller.cjs +10 -2
  14. package/dist/Controller.cjs.map +1 -1
  15. package/dist/Controller.d.cts +3 -2
  16. package/dist/Controller.d.ts +3 -2
  17. package/dist/Controller.js +10 -2
  18. package/dist/Controller.js.map +1 -1
  19. package/dist/{Movie-VyDiUYOj.d.ts → Movie-CADDBfpl.d.cts} +3 -1
  20. package/dist/{Movie-CuU_aaCm.d.cts → Movie-Ch2SUI1h.d.ts} +3 -1
  21. package/dist/{chunk-23M5QTWW.cjs → chunk-4AGJF5RK.cjs} +21 -21
  22. package/dist/{chunk-23M5QTWW.cjs.map → chunk-4AGJF5RK.cjs.map} +1 -1
  23. package/dist/{chunk-UBPZLGLU.js → chunk-7IJHJXDI.js} +241 -37
  24. package/dist/chunk-7IJHJXDI.js.map +1 -0
  25. package/dist/{chunk-5Q5XZG7Z.js → chunk-B2FTJLNB.js} +3 -3
  26. package/dist/{chunk-5Q5XZG7Z.js.map → chunk-B2FTJLNB.js.map} +1 -1
  27. package/dist/{chunk-2RR43OIN.cjs → chunk-KQM2ZZMK.cjs} +241 -37
  28. package/dist/chunk-KQM2ZZMK.cjs.map +1 -0
  29. package/dist/index.cjs +58 -19
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +4 -4
  32. package/dist/index.d.ts +4 -4
  33. package/dist/index.js +49 -10
  34. package/dist/index.js.map +1 -1
  35. package/dist/three.cjs +5 -5
  36. package/dist/three.d.cts +2 -2
  37. package/dist/three.d.ts +2 -2
  38. package/dist/three.js +1 -1
  39. package/dist/{types-7VtTEKUW.d.cts → types-DrW9QeKU.d.cts} +22 -6
  40. package/dist/{types-7VtTEKUW.d.ts → types-DrW9QeKU.d.ts} +22 -6
  41. package/docs/api.md +1 -0
  42. package/docs/dsl.md +26 -7
  43. package/llms-full.txt +67 -9
  44. package/package.json +1 -1
  45. package/dist/Composition-63EXHNJJ.cjs +0 -13
  46. package/dist/Composition-TUCRSMJU.js +0 -4
  47. package/dist/chunk-2RR43OIN.cjs.map +0 -1
  48. package/dist/chunk-UBPZLGLU.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkUQBGW5DO_cjs = require('./chunk-UQBGW5DO.cjs');
4
- var chunk23M5QTWW_cjs = require('./chunk-23M5QTWW.cjs');
5
- var chunk2RR43OIN_cjs = require('./chunk-2RR43OIN.cjs');
4
+ var chunk4AGJF5RK_cjs = require('./chunk-4AGJF5RK.cjs');
5
+ var chunkKQM2ZZMK_cjs = require('./chunk-KQM2ZZMK.cjs');
6
6
  var PIXI = require('pixi.js');
7
7
  var gsap = require('gsap');
8
8
  var PixiPlugin = require('gsap/PixiPlugin');
@@ -819,16 +819,16 @@ function expandTransitions(spec) {
819
819
  if (toUses > 1) {
820
820
  throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
821
821
  }
822
- const tStart = chunk2RR43OIN_cjs.resolveAt(t.at, parentDuration);
822
+ const tStart = chunkKQM2ZZMK_cjs.resolveAt(t.at, parentDuration);
823
823
  const tEnd = tStart + t.duration;
824
824
  const fromSeq = fromEntry.seq;
825
- const fromStart = chunk2RR43OIN_cjs.resolveAt(fromSeq.at, parentDuration);
825
+ const fromStart = chunkKQM2ZZMK_cjs.resolveAt(fromSeq.at, parentDuration);
826
826
  const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
827
827
  if (tStart < fromStart || tEnd > fromEnd) {
828
828
  throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
829
829
  }
830
830
  const toSeq = toEntry.seq;
831
- const toStart = chunk2RR43OIN_cjs.resolveAt(toSeq.at, parentDuration);
831
+ const toStart = chunkKQM2ZZMK_cjs.resolveAt(toSeq.at, parentDuration);
832
832
  const toEnd = toStart + (toSeq.duration ?? parentDuration);
833
833
  if (tStart < toStart || tEnd > toEnd) {
834
834
  throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
@@ -1168,7 +1168,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
1168
1168
  onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
1169
1169
  if (area === 0) onCanvas = "none";
1170
1170
  }
1171
- const keys = chunk2RR43OIN_cjs.collectPropKeys(seq.spec);
1171
+ const keys = chunkKQM2ZZMK_cjs.collectPropKeys(seq.spec);
1172
1172
  const moving = parentMoving || (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
1173
1173
  const scale = t?.scale;
1174
1174
  const zero = parentZero || !!scale && (scale.x === 0 || scale.y === 0);
@@ -1183,8 +1183,8 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
1183
1183
  seen.set(info, shown);
1184
1184
  const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
1185
1185
  if (group) scene.set(info, group);
1186
- if (zero) scaledToNothing.add(info);
1187
- if (seq instanceof chunk23M5QTWW_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible, group, moving, zero);
1186
+ if (zero || seq.showsNothingYet) scaledToNothing.add(info);
1187
+ if (seq instanceof chunk4AGJF5RK_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible, group, moving, zero);
1188
1188
  });
1189
1189
  };
1190
1190
  walk(root, "", false, true);
@@ -1244,6 +1244,35 @@ function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
1244
1244
  return { cols, rows, cellW, cellH, width: cols * cellW, height: rows * (cellH + labelH), positions };
1245
1245
  }
1246
1246
 
1247
+ // src/core/startWhenRunning.ts
1248
+ function startWhenRunning(ctx, start, gesture) {
1249
+ if (ctx.state === "running") {
1250
+ start();
1251
+ return () => {
1252
+ };
1253
+ }
1254
+ let done = false;
1255
+ const resume = () => {
1256
+ ctx.resume?.()?.catch(() => {
1257
+ });
1258
+ };
1259
+ const stop = () => {
1260
+ done = true;
1261
+ ctx.removeEventListener("statechange", onState);
1262
+ for (const e of GESTURES) gesture?.removeEventListener(e, resume, true);
1263
+ };
1264
+ const onState = () => {
1265
+ if (done || ctx.state !== "running") return;
1266
+ stop();
1267
+ start();
1268
+ };
1269
+ ctx.addEventListener("statechange", onState);
1270
+ for (const e of GESTURES) gesture?.addEventListener(e, resume, true);
1271
+ resume();
1272
+ return stop;
1273
+ }
1274
+ var GESTURES = ["pointerdown", "mousedown", "touchend", "keydown"];
1275
+
1247
1276
  // src/core/Movie.ts
1248
1277
  PIXI.extensions.add(PIXI.CullerPlugin);
1249
1278
  gsap.gsap.registerPlugin(PixiPlugin.PixiPlugin);
@@ -1256,6 +1285,7 @@ var Movie = class {
1256
1285
  audioBuffer = null;
1257
1286
  audioSource = null;
1258
1287
  gainNode = null;
1288
+ _cancelAudioStart = null;
1259
1289
  _volume = 1;
1260
1290
  _muted = false;
1261
1291
  isPlaying = false;
@@ -1358,7 +1388,7 @@ var Movie = class {
1358
1388
  ...userComposition
1359
1389
  };
1360
1390
  if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
1361
- const composition = new chunk23M5QTWW_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
1391
+ const composition = new chunk4AGJF5RK_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
1362
1392
  await composition.build();
1363
1393
  this._rootSequence = composition;
1364
1394
  if (composition.target) root.addChild(composition.target);
@@ -1493,6 +1523,7 @@ var Movie = class {
1493
1523
  play() {
1494
1524
  if (this._initState !== "ready") return;
1495
1525
  if (this.currentFrame >= this.totalFrames) this.currentFrame = 0;
1526
+ const wasPlaying = this.isPlaying;
1496
1527
  this.isPlaying = true;
1497
1528
  const startTime = performance.now() - this.currentFrame / this.frameRate * 1e3;
1498
1529
  let inFlight = false;
@@ -1522,17 +1553,25 @@ var Movie = class {
1522
1553
  this._raf = requestAnimationFrame(tick);
1523
1554
  if (this.audioBuffer) {
1524
1555
  const ctx = this._ensureAudioContext();
1525
- this.audioSource = ctx.createBufferSource();
1526
- this.audioSource.buffer = this.audioBuffer;
1527
- this.gainNode = ctx.createGain();
1528
- this.gainNode.gain.value = this._muted ? 0 : this._volume;
1529
- this.audioSource.connect(this.gainNode).connect(ctx.destination);
1530
- this.audioSource.start(0, this.currentFrame / this.frameRate);
1556
+ const buffer = this.audioBuffer;
1557
+ this._cancelAudioStart?.();
1558
+ this._cancelAudioStart = startWhenRunning(ctx, () => {
1559
+ if (!this.isPlaying) return;
1560
+ this.audioSource = ctx.createBufferSource();
1561
+ this.audioSource.buffer = buffer;
1562
+ this.gainNode = ctx.createGain();
1563
+ this.gainNode.gain.value = this._muted ? 0 : this._volume;
1564
+ this.audioSource.connect(this.gainNode).connect(ctx.destination);
1565
+ this.audioSource.start(0, Math.min(this.currentFrame / this.frameRate, buffer.duration));
1566
+ }, typeof window !== "undefined" ? window : void 0);
1531
1567
  }
1568
+ if (!wasPlaying) this.emit("play");
1532
1569
  }
1533
1570
  pause() {
1534
1571
  const wasPlaying = this.isPlaying;
1535
1572
  this.isPlaying = false;
1573
+ this._cancelAudioStart?.();
1574
+ this._cancelAudioStart = null;
1536
1575
  if (this._raf) {
1537
1576
  cancelAnimationFrame(this._raf);
1538
1577
  this._raf = null;
@@ -1794,17 +1833,17 @@ function orbit(opts) {
1794
1833
  throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
1795
1834
  }
1796
1835
  const [cx, cy] = opts.center ?? [width / 2, height / 2];
1797
- const fixedR = opts.radius ?? chunk2RR43OIN_cjs.homeDistance(height, fov ?? chunk2RR43OIN_cjs.DEFAULT_FOV);
1836
+ const fixedR = opts.radius ?? chunkKQM2ZZMK_cjs.homeDistance(height, fov ?? chunkKQM2ZZMK_cjs.DEFAULT_FOV);
1798
1837
  const start = opts.start ?? -degrees / 2;
1799
1838
  const steps = Math.max(1, Math.round(duration * stepsPerSecond));
1800
1839
  const easeFn = parseEase(ease);
1801
1840
  const dollyEase = dolly ? parseEase(dolly.ease ?? ease) : null;
1802
1841
  const pos = (i) => {
1803
1842
  const p = i / steps;
1804
- const a = (start + degrees * easeFn(p)) * chunk2RR43OIN_cjs.DEG;
1843
+ const a = (start + degrees * easeFn(p)) * chunkKQM2ZZMK_cjs.DEG;
1805
1844
  if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
1806
1845
  const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
1807
- const R = chunk2RR43OIN_cjs.homeDistance(height, f);
1846
+ const R = chunkKQM2ZZMK_cjs.homeDistance(height, f);
1808
1847
  return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
1809
1848
  };
1810
1849
  const keyframes = [];
@@ -1853,7 +1892,7 @@ function withFade(spec, opts) {
1853
1892
 
1854
1893
  Object.defineProperty(exports, "registerSequenceType", {
1855
1894
  enumerable: true,
1856
- get: function () { return chunk2RR43OIN_cjs.registerSequenceType; }
1895
+ get: function () { return chunkKQM2ZZMK_cjs.registerSequenceType; }
1857
1896
  });
1858
1897
  exports.Movie = Movie;
1859
1898
  exports.kenBurns = kenBurns;