pixi-effects 0.3.0 → 0.4.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 (45) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +6 -6
  3. package/ai/SKILL.md +3 -1
  4. package/ai/reference/cheatsheet.md +6 -5
  5. package/ai/reference/pitfalls.md +24 -3
  6. package/ai/template.html +3 -3
  7. package/dist/{Base-Ba4Ta4ap.d.ts → Base-5R7C5pHR.d.cts} +7 -1
  8. package/dist/{Base-BDw6dKRB.d.cts → Base-DhY9oMxr.d.ts} +7 -1
  9. package/dist/Composition-D7RCAGEA.cjs +13 -0
  10. package/dist/{Composition-6FDH5OPM.cjs.map → Composition-D7RCAGEA.cjs.map} +1 -1
  11. package/dist/Composition-RGTRZ2JX.js +4 -0
  12. package/dist/{Composition-FEYAUMFI.js.map → Composition-RGTRZ2JX.js.map} +1 -1
  13. package/dist/Controller.d.cts +2 -2
  14. package/dist/Controller.d.ts +2 -2
  15. package/dist/{Movie-W8ISiEBB.d.cts → Movie-CghFXprP.d.cts} +1 -1
  16. package/dist/{Movie-DMpaT67V.d.ts → Movie-DRZtIGU7.d.ts} +1 -1
  17. package/dist/{chunk-SIRVULFF.cjs → chunk-6BQ6IEW2.cjs} +119 -36
  18. package/dist/chunk-6BQ6IEW2.cjs.map +1 -0
  19. package/dist/{chunk-DIJG2RSF.js → chunk-A574IA4F.js} +44 -6
  20. package/dist/chunk-A574IA4F.js.map +1 -0
  21. package/dist/{chunk-ZL262ZRM.cjs → chunk-QGBOC5YL.cjs} +56 -18
  22. package/dist/chunk-QGBOC5YL.cjs.map +1 -0
  23. package/dist/{chunk-PN5A6QA7.js → chunk-ZQX7WIYL.js} +119 -37
  24. package/dist/chunk-ZQX7WIYL.js.map +1 -0
  25. package/dist/index.cjs +58 -16
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +4 -4
  28. package/dist/index.d.ts +4 -4
  29. package/dist/index.js +50 -8
  30. package/dist/index.js.map +1 -1
  31. package/dist/three.cjs +5 -5
  32. package/dist/three.d.cts +2 -2
  33. package/dist/three.d.ts +2 -2
  34. package/dist/three.js +1 -1
  35. package/dist/{types-3c8Vymgw.d.cts → types-CRE9WKd4.d.cts} +6 -0
  36. package/dist/{types-3c8Vymgw.d.ts → types-CRE9WKd4.d.ts} +6 -0
  37. package/docs/dsl.md +12 -1
  38. package/llms-full.txt +45 -10
  39. package/package.json +2 -1
  40. package/dist/Composition-6FDH5OPM.cjs +0 -13
  41. package/dist/Composition-FEYAUMFI.js +0 -4
  42. package/dist/chunk-DIJG2RSF.js.map +0 -1
  43. package/dist/chunk-PN5A6QA7.js.map +0 -1
  44. package/dist/chunk-SIRVULFF.cjs.map +0 -1
  45. package/dist/chunk-ZL262ZRM.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkZL262ZRM_cjs = require('./chunk-ZL262ZRM.cjs');
4
- var chunkSIRVULFF_cjs = require('./chunk-SIRVULFF.cjs');
3
+ var chunkQGBOC5YL_cjs = require('./chunk-QGBOC5YL.cjs');
4
+ var chunk6BQ6IEW2_cjs = require('./chunk-6BQ6IEW2.cjs');
5
5
  var PIXI = require('pixi.js');
6
6
  var gsap = require('gsap');
7
7
  var PixiPlugin = require('gsap/PixiPlugin');
@@ -521,6 +521,15 @@ var TransitionMaskFilter = class extends PIXI.Filter {
521
521
  };
522
522
 
523
523
  // src/core/Transitions.ts
524
+ var windows = /* @__PURE__ */ new WeakMap();
525
+ function transitionWindowsOf(spec) {
526
+ return windows.get(spec) ?? [];
527
+ }
528
+ function carryTransitionWindows(from, to) {
529
+ const w = windows.get(from);
530
+ if (w) windows.set(to, w);
531
+ return to;
532
+ }
524
533
  function expandTransitions(spec) {
525
534
  const out = {
526
535
  ...spec,
@@ -617,20 +626,23 @@ function expandTransitions(spec) {
617
626
  if (toUses > 1) {
618
627
  throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
619
628
  }
620
- const tStart = chunkSIRVULFF_cjs.resolveAt(t.at, parentDuration);
629
+ const tStart = chunk6BQ6IEW2_cjs.resolveAt(t.at, parentDuration);
621
630
  const tEnd = tStart + t.duration;
622
631
  const fromSeq = fromEntry.seq;
623
- const fromStart = chunkSIRVULFF_cjs.resolveAt(fromSeq.at, parentDuration);
632
+ const fromStart = chunk6BQ6IEW2_cjs.resolveAt(fromSeq.at, parentDuration);
624
633
  const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
625
634
  if (tStart < fromStart || tEnd > fromEnd) {
626
635
  throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
627
636
  }
628
637
  const toSeq = toEntry.seq;
629
- const toStart = chunkSIRVULFF_cjs.resolveAt(toSeq.at, parentDuration);
638
+ const toStart = chunk6BQ6IEW2_cjs.resolveAt(toSeq.at, parentDuration);
630
639
  const toEnd = toStart + (toSeq.duration ?? parentDuration);
631
640
  if (tStart < toStart || tEnd > toEnd) {
632
641
  throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
633
642
  }
643
+ const record = windows.get(out) ?? [];
644
+ record.push({ from: t.from, to: t.to, start: tStart, end: tEnd });
645
+ windows.set(out, record);
634
646
  const abs = { ...t, at: tStart };
635
647
  const nFrom = keyframeCount(fromEntry.seq);
636
648
  const nTo = keyframeCount(toEntry.seq);
@@ -924,10 +936,25 @@ var intersection = (a, b) => {
924
936
  const h = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
925
937
  return w > 0 && h > 0 ? w * h : 0;
926
938
  };
939
+ var clip = (a, b) => {
940
+ const x = Math.max(a.x, b.x), y = Math.max(a.y, b.y);
941
+ const w = Math.min(a.x + a.width, b.x + b.width) - x, h = Math.min(a.y + a.height, b.y + b.height) - y;
942
+ return w > 0 && h > 0 ? { x, y, width: w, height: h } : null;
943
+ };
927
944
  function inspectScene(root, frame, time, canvas, opts = {}) {
928
945
  const layers = [];
929
946
  const view = { x: 0, y: 0, width: canvas.width, height: canvas.height };
930
- const walk = (comp, prefix, insideThreeD, parentVisible) => {
947
+ const seen = /* @__PURE__ */ new Map();
948
+ const scene = /* @__PURE__ */ new Map();
949
+ const walk = (comp, prefix, insideThreeD, parentVisible, parentScene) => {
950
+ const blending = /* @__PURE__ */ new Set();
951
+ for (const w of transitionWindowsOf(comp.spec)) {
952
+ const start = (comp.absoluteStart ?? 0) + w.start, end = (comp.absoluteStart ?? 0) + w.end;
953
+ if (time >= start - 1e-9 && time <= end + 1e-9) {
954
+ blending.add(w.from);
955
+ blending.add(w.to);
956
+ }
957
+ }
931
958
  comp.layers().forEach(({ seq, display, threeD }, i) => {
932
959
  const t = seq.target;
933
960
  const name = seq.spec.name;
@@ -947,10 +974,20 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
947
974
  onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
948
975
  if (area === 0) onCanvas = "none";
949
976
  }
950
- const keys = chunkSIRVULFF_cjs.collectPropKeys(seq.spec);
977
+ const keys = chunk6BQ6IEW2_cjs.collectPropKeys(seq.spec);
951
978
  const moving = (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
952
- layers.push({ path: prefix + label, name, type: seq.spec.type, threeD, visible, alpha, moving, bounds, onCanvas });
953
- if (seq instanceof chunkZL262ZRM_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible);
979
+ const info = { path: prefix + label, name, type: seq.spec.type, threeD, visible, alpha, moving, bounds, onCanvas };
980
+ layers.push(info);
981
+ let shown = bounds ? clip(bounds, view) : null;
982
+ const maskTarget = seq.maskSequence?.target;
983
+ if (shown && maskTarget && !seq.spec.maskInverted) {
984
+ const m = maskTarget.getBounds();
985
+ shown = clip(shown, { x: m.x, y: m.y, width: m.width, height: m.height });
986
+ }
987
+ seen.set(info, shown);
988
+ const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
989
+ if (group) scene.set(info, group);
990
+ if (seq instanceof chunkQGBOC5YL_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible, group);
954
991
  });
955
992
  };
956
993
  walk(root, "", false, true);
@@ -961,7 +998,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
961
998
  const who = `text layer "${l.path}"`;
962
999
  if (b.width < 1 || b.height < 1) {
963
1000
  issues.push(`${who} has no size (empty text, or not drawn yet)`);
964
- } else if (l.moving) ; else if (l.onCanvas === "none") {
1001
+ } else if (l.moving || scene.has(l)) ; else if (l.onCanvas === "none") {
965
1002
  issues.push(`${who} is entirely outside the canvas (at ${Math.round(b.x)},${Math.round(b.y)}, ${Math.round(b.width)}\xD7${Math.round(b.height)})`);
966
1003
  } else if (l.onCanvas === "partial") {
967
1004
  const over = [];
@@ -974,7 +1011,10 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
974
1011
  }
975
1012
  for (let i = 0; i < texts.length; i++) {
976
1013
  for (let j = i + 1; j < texts.length; j++) {
977
- const a = texts[i].bounds, b = texts[j].bounds;
1014
+ const a = seen.get(texts[i]), b = seen.get(texts[j]);
1015
+ if (!a || !b) continue;
1016
+ const sa = scene.get(texts[i]), sb = scene.get(texts[j]);
1017
+ if (sa && sb && sa !== sb) continue;
978
1018
  const smaller = Math.min(a.width * a.height, b.width * b.height);
979
1019
  if (smaller <= 0) continue;
980
1020
  const share = intersection(a, b) / smaller;
@@ -1174,7 +1214,8 @@ var Movie = class {
1174
1214
  duration: this.duration,
1175
1215
  ...userComposition
1176
1216
  };
1177
- const composition = new chunkZL262ZRM_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
1217
+ if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
1218
+ const composition = new chunkQGBOC5YL_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
1178
1219
  await composition.build();
1179
1220
  this._rootSequence = composition;
1180
1221
  if (composition.target) root.addChild(composition.target);
@@ -1281,6 +1322,7 @@ var Movie = class {
1281
1322
  _renderNow() {
1282
1323
  const app = this.app;
1283
1324
  if (!app?.renderer) return;
1325
+ this._rootSequence?.syncFrame();
1284
1326
  PIXI.Culler.shared.cull(app.stage, app.renderer.screen, false);
1285
1327
  app.renderer.render({ container: app.stage });
1286
1328
  }
@@ -1549,17 +1591,17 @@ function orbit(opts) {
1549
1591
  throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
1550
1592
  }
1551
1593
  const [cx, cy] = opts.center ?? [width / 2, height / 2];
1552
- const fixedR = opts.radius ?? chunkSIRVULFF_cjs.homeDistance(height, fov ?? chunkSIRVULFF_cjs.DEFAULT_FOV);
1594
+ const fixedR = opts.radius ?? chunk6BQ6IEW2_cjs.homeDistance(height, fov ?? chunk6BQ6IEW2_cjs.DEFAULT_FOV);
1553
1595
  const start = opts.start ?? -degrees / 2;
1554
1596
  const steps = Math.max(1, Math.round(duration * stepsPerSecond));
1555
1597
  const easeFn = parseEase(ease);
1556
1598
  const dollyEase = dolly ? parseEase(dolly.ease ?? ease) : null;
1557
1599
  const pos = (i) => {
1558
1600
  const p = i / steps;
1559
- const a = (start + degrees * easeFn(p)) * chunkSIRVULFF_cjs.DEG;
1601
+ const a = (start + degrees * easeFn(p)) * chunk6BQ6IEW2_cjs.DEG;
1560
1602
  if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
1561
1603
  const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
1562
- const R = chunkSIRVULFF_cjs.homeDistance(height, f);
1604
+ const R = chunk6BQ6IEW2_cjs.homeDistance(height, f);
1563
1605
  return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
1564
1606
  };
1565
1607
  const keyframes = [];
@@ -1608,7 +1650,7 @@ function withFade(spec, opts) {
1608
1650
 
1609
1651
  Object.defineProperty(exports, "registerSequenceType", {
1610
1652
  enumerable: true,
1611
- get: function () { return chunkSIRVULFF_cjs.registerSequenceType; }
1653
+ get: function () { return chunk6BQ6IEW2_cjs.registerSequenceType; }
1612
1654
  });
1613
1655
  exports.Movie = Movie;
1614
1656
  exports.kenBurns = kenBurns;