pixi-effects 0.22.0 → 0.26.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 (92) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +17 -15
  3. package/ai/CHAT.md +2 -2
  4. package/ai/chat-template.html +3 -3
  5. package/ai/tools/check.mjs +10 -3
  6. package/ai/tools/pixi-effects.mjs +48 -0
  7. package/ai/tools/render.mjs +3 -3
  8. package/ai/tools/view.mjs +3 -3
  9. package/dist/{Base-gu-5X0Cv.d.ts → Base-BgnRXbtJ.d.ts} +1 -1
  10. package/dist/{Base-BzlPgd-D.d.cts → Base-DHVKqA46.d.cts} +1 -1
  11. package/dist/Composition-2GJSCHPP.cjs +16 -0
  12. package/dist/{Composition-BK5SH6J7.cjs.map → Composition-2GJSCHPP.cjs.map} +1 -1
  13. package/dist/Composition-C4FSWJZF.js +7 -0
  14. package/dist/{Composition-Q5TVG3HM.js.map → Composition-C4FSWJZF.js.map} +1 -1
  15. package/dist/Controller.cjs +2 -2
  16. package/dist/Controller.d.cts +2 -2
  17. package/dist/Controller.d.ts +2 -2
  18. package/dist/Controller.js +1 -1
  19. package/dist/{Movie--_TJvdJa.d.ts → Movie-DP5p1r4E.d.ts} +5 -1
  20. package/dist/{Movie-DMxOoTdW.d.cts → Movie-DXReF4-W.d.cts} +5 -1
  21. package/dist/Presenter.cjs +2 -2
  22. package/dist/Presenter.d.cts +2 -2
  23. package/dist/Presenter.d.ts +2 -2
  24. package/dist/Presenter.js +1 -1
  25. package/dist/{blendModes-HCP5XTNP.js → blendModes-G3NOAU3T.js} +5 -5
  26. package/dist/{blendModes-HCP5XTNP.js.map → blendModes-G3NOAU3T.js.map} +1 -1
  27. package/dist/{blendModes-5E4G2ZZQ.cjs → blendModes-YV43K6E7.cjs} +6 -6
  28. package/dist/{blendModes-5E4G2ZZQ.cjs.map → blendModes-YV43K6E7.cjs.map} +1 -1
  29. package/dist/{chunk-K4JVI5HK.cjs → chunk-3DLYAPK7.cjs} +7 -9
  30. package/dist/{chunk-K4JVI5HK.cjs.map → chunk-3DLYAPK7.cjs.map} +1 -1
  31. package/dist/{chunk-YEPDQ7I3.js → chunk-AXZUKNXF.js} +6 -6
  32. package/dist/{chunk-YEPDQ7I3.js.map → chunk-AXZUKNXF.js.map} +1 -1
  33. package/dist/{chunk-NHICCDTC.js → chunk-BXOCEZ4U.js} +12 -3
  34. package/dist/chunk-BXOCEZ4U.js.map +1 -0
  35. package/dist/{chunk-IFZOI3JQ.cjs → chunk-DP37TTMO.cjs} +842 -40
  36. package/dist/chunk-DP37TTMO.cjs.map +1 -0
  37. package/dist/{chunk-BPTW7L25.cjs → chunk-ECA2WNRX.cjs} +23 -9
  38. package/dist/chunk-ECA2WNRX.cjs.map +1 -0
  39. package/dist/{chunk-DC4JPY6A.js → chunk-PRZ4U6JN.js} +814 -22
  40. package/dist/chunk-PRZ4U6JN.js.map +1 -0
  41. package/dist/chunk-SY27HZC5.cjs +1727 -0
  42. package/dist/chunk-SY27HZC5.cjs.map +1 -0
  43. package/dist/{chunk-E7RONUZ7.js → chunk-TLYTYBWX.js} +20 -6
  44. package/dist/chunk-TLYTYBWX.js.map +1 -0
  45. package/dist/{chunk-UZTKEYFP.cjs → chunk-TWZNOUM7.cjs} +12 -3
  46. package/dist/chunk-TWZNOUM7.cjs.map +1 -0
  47. package/dist/chunk-XS6GSJCN.js +1724 -0
  48. package/dist/chunk-XS6GSJCN.js.map +1 -0
  49. package/dist/index.cjs +234 -77
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +5 -5
  52. package/dist/index.d.ts +5 -5
  53. package/dist/index.js +173 -16
  54. package/dist/index.js.map +1 -1
  55. package/dist/loader.css +1 -1
  56. package/dist/{music-FUN7N225.js → music-AF4VTFAF.js} +3 -3
  57. package/dist/{music-FUN7N225.js.map → music-AF4VTFAF.js.map} +1 -1
  58. package/dist/{music-GEAH2XCT.cjs → music-KB7YZLHP.cjs} +7 -7
  59. package/dist/{music-GEAH2XCT.cjs.map → music-KB7YZLHP.cjs.map} +1 -1
  60. package/dist/{sfx-2DYTYNYW.cjs → sfx-2O6UQEUP.cjs} +8 -8
  61. package/dist/{sfx-2DYTYNYW.cjs.map → sfx-2O6UQEUP.cjs.map} +1 -1
  62. package/dist/{sfx-3IDAJ3UZ.js → sfx-VUKARHDX.js} +3 -3
  63. package/dist/{sfx-3IDAJ3UZ.js.map → sfx-VUKARHDX.js.map} +1 -1
  64. package/dist/three.cjs +7 -7
  65. package/dist/three.d.cts +2 -2
  66. package/dist/three.d.ts +2 -2
  67. package/dist/three.js +3 -3
  68. package/dist/{types-DBbZVKGS.d.cts → types-CoT0ypcx.d.cts} +60 -4
  69. package/dist/{types-DBbZVKGS.d.ts → types-CoT0ypcx.d.ts} +60 -4
  70. package/docs/api.md +2 -2
  71. package/docs/dsl.md +140 -7
  72. package/llms-full.txt +328 -39
  73. package/llms.txt +6 -5
  74. package/package.json +3 -3
  75. package/{ai → skills/pixi-effects}/SKILL.md +16 -12
  76. package/{ai → skills/pixi-effects}/reference/cheatsheet.md +10 -7
  77. package/{ai → skills/pixi-effects}/reference/pitfalls.md +22 -4
  78. package/{ai → skills/pixi-effects}/reference/recipes.md +133 -2
  79. package/{ai/tools → skills/pixi-effects/scripts}/save-image.py +1 -1
  80. package/{ai → skills/pixi-effects}/template.html +6 -6
  81. package/dist/Composition-BK5SH6J7.cjs +0 -16
  82. package/dist/Composition-Q5TVG3HM.js +0 -7
  83. package/dist/chunk-BPTW7L25.cjs.map +0 -1
  84. package/dist/chunk-DC4JPY6A.js.map +0 -1
  85. package/dist/chunk-E7RONUZ7.js.map +0 -1
  86. package/dist/chunk-IFZOI3JQ.cjs.map +0 -1
  87. package/dist/chunk-MHOO2CVU.cjs +0 -840
  88. package/dist/chunk-MHOO2CVU.cjs.map +0 -1
  89. package/dist/chunk-NHICCDTC.js.map +0 -1
  90. package/dist/chunk-UQDEDYVM.js +0 -838
  91. package/dist/chunk-UQDEDYVM.js.map +0 -1
  92. package/dist/chunk-UZTKEYFP.cjs.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoaderOption, M as MotionBlurOptions, g as MotionBlurSpec, h as Movie, i as MovieErrorEvent, j as MovieOptions, O as OnionSkinOptions, P as ProgressEvent, R as RenderOptions, k as ReviewOptions, l as ReviewReport, S as SnapshotOptions, m as SoundMeasure, n as StopEvent, o as StopImage, p as StopImagesOptions, T as TimelineData, q as TimelineHtmlOptions, r as TimelineRow, s as TimelineSvgOptions, t as TimelineTransition, V as VolumeEvent, u as dismissLoader, v as failLoader, w as resolveLoader } from './Movie-DMxOoTdW.cjs';
2
- import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-DBbZVKGS.cjs';
3
- export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioMusicSpec, h as AudioSequenceSpec, i as AudioSfxSpec, B as BlendModeName, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CrossfadeTransition, n as CustomFilterSpec, D as DipTransition, o as DissolveTransition, E as EllipseShapeSpec, p as Expr, F as FilterSpec, G as GradientSpec, q as IrisTransition, L as LineShapeSpec, r as MusicDrum, s as MusicDrums, t as MusicInstrument, u as MusicLevel, v as MusicTrack, N as NullSequenceSpec, w as PathShapeSpec, x as PolygonShapeSpec, y as PropValue, R as RectShapeSpec, z as SfxKnobs, H as SfxOptions, J as SfxPreset, O as SfxVoice, Q as ShapeSequenceSpec, U as SlideTransition, V as Stop, W as StopSpec, X as TransitionCommon, Y as VideoSequenceSpec, Z as WipeTransition, _ as ZoomTransition, $ as normalizeStops, a0 as pictureStops } from './types-DBbZVKGS.cjs';
4
- import { S as Sequence } from './Base-BzlPgd-D.cjs';
1
+ export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoaderOption, M as MotionBlurOptions, g as MotionBlurSpec, h as Movie, i as MovieErrorEvent, j as MovieOptions, O as OnionSkinOptions, P as ProgressEvent, R as RenderOptions, k as ReviewOptions, l as ReviewReport, S as SnapshotOptions, m as SoundMeasure, n as StopEvent, o as StopImage, p as StopImagesOptions, T as TimelineData, q as TimelineHtmlOptions, r as TimelineRow, s as TimelineSvgOptions, t as TimelineTransition, V as VolumeEvent, u as dismissLoader, v as failLoader, w as resolveLoader } from './Movie-DXReF4-W.cjs';
2
+ import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-CoT0ypcx.cjs';
3
+ export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioMusicSpec, h as AudioSequenceSpec, i as AudioSfxSpec, B as BlendModeName, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CrossfadeTransition, n as CustomFilterSpec, D as DipTransition, o as DissolveTransition, E as EllipseShapeSpec, p as Expr, F as FilterSpec, G as GradientSpec, q as IrisTransition, L as LightSequenceSpec, r as LineShapeSpec, s as LumaTransition, t as MaskRefSpec, u as MatteRefSpec, v as MusicDrum, w as MusicDrums, x as MusicInstrument, y as MusicLevel, z as MusicTrack, N as NullSequenceSpec, H as PathShapeSpec, J as PolygonShapeSpec, O as PropValue, R as RectShapeSpec, Q as SfxKnobs, U as SfxOptions, V as SfxPreset, W as SfxVoice, X as ShaderSequenceSpec, Y as ShapeSequenceSpec, Z as SlideTransition, _ as Stop, $ as StopSpec, a0 as TransitionCommon, a1 as VideoSequenceSpec, a2 as WipeTransition, a3 as ZoomTransition, a4 as normalizeStops, a5 as pictureStops } from './types-CoT0ypcx.cjs';
4
+ import { S as Sequence } from './Base-DHVKqA46.cjs';
5
5
  import 'pixi.js';
6
6
  import 'gsap';
7
7
 
@@ -610,7 +610,7 @@ type DeckTransition = TransitionSpec extends infer T ? (T extends TransitionSpec
610
610
  interface DeckOptions {
611
611
  pages: DeckPage[];
612
612
  /**
613
- * A transition between every two pages: `{ kind: 'crossfade' | 'slide' | 'wipe' | 'iris' | 'dip' | 'zoom' | 'dissolve', duration, …its own options }` (see Transitions). The next page starts
613
+ * A transition between every two pages: `{ kind: 'crossfade' | 'slide' | 'wipe' | 'iris' | 'dip' | 'zoom' | 'dissolve' | 'luma', duration, …its own options }` (see Transitions). The next page starts
614
614
  * `duration` seconds before the current one ends, and the transition plays across the overlap.
615
615
  */
616
616
  transition?: DeckTransition;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoaderOption, M as MotionBlurOptions, g as MotionBlurSpec, h as Movie, i as MovieErrorEvent, j as MovieOptions, O as OnionSkinOptions, P as ProgressEvent, R as RenderOptions, k as ReviewOptions, l as ReviewReport, S as SnapshotOptions, m as SoundMeasure, n as StopEvent, o as StopImage, p as StopImagesOptions, T as TimelineData, q as TimelineHtmlOptions, r as TimelineRow, s as TimelineSvgOptions, t as TimelineTransition, V as VolumeEvent, u as dismissLoader, v as failLoader, w as resolveLoader } from './Movie--_TJvdJa.js';
2
- import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-DBbZVKGS.js';
3
- export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioMusicSpec, h as AudioSequenceSpec, i as AudioSfxSpec, B as BlendModeName, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CrossfadeTransition, n as CustomFilterSpec, D as DipTransition, o as DissolveTransition, E as EllipseShapeSpec, p as Expr, F as FilterSpec, G as GradientSpec, q as IrisTransition, L as LineShapeSpec, r as MusicDrum, s as MusicDrums, t as MusicInstrument, u as MusicLevel, v as MusicTrack, N as NullSequenceSpec, w as PathShapeSpec, x as PolygonShapeSpec, y as PropValue, R as RectShapeSpec, z as SfxKnobs, H as SfxOptions, J as SfxPreset, O as SfxVoice, Q as ShapeSequenceSpec, U as SlideTransition, V as Stop, W as StopSpec, X as TransitionCommon, Y as VideoSequenceSpec, Z as WipeTransition, _ as ZoomTransition, $ as normalizeStops, a0 as pictureStops } from './types-DBbZVKGS.js';
4
- import { S as Sequence } from './Base-gu-5X0Cv.js';
1
+ export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FontReport, c as FrameEvent, I as InspectOptions, d as InspectReport, e as IssueGroup, L as LayerInfo, f as LoaderOption, M as MotionBlurOptions, g as MotionBlurSpec, h as Movie, i as MovieErrorEvent, j as MovieOptions, O as OnionSkinOptions, P as ProgressEvent, R as RenderOptions, k as ReviewOptions, l as ReviewReport, S as SnapshotOptions, m as SoundMeasure, n as StopEvent, o as StopImage, p as StopImagesOptions, T as TimelineData, q as TimelineHtmlOptions, r as TimelineRow, s as TimelineSvgOptions, t as TimelineTransition, V as VolumeEvent, u as dismissLoader, v as failLoader, w as resolveLoader } from './Movie-DP5p1r4E.js';
2
+ import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, M as MusicOptions, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-CoT0ypcx.js';
3
+ export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioMusicSpec, h as AudioSequenceSpec, i as AudioSfxSpec, B as BlendModeName, j as ChromaKeyFilterSpec, k as CircleShapeSpec, l as CompositionSequenceSpec, m as CrossfadeTransition, n as CustomFilterSpec, D as DipTransition, o as DissolveTransition, E as EllipseShapeSpec, p as Expr, F as FilterSpec, G as GradientSpec, q as IrisTransition, L as LightSequenceSpec, r as LineShapeSpec, s as LumaTransition, t as MaskRefSpec, u as MatteRefSpec, v as MusicDrum, w as MusicDrums, x as MusicInstrument, y as MusicLevel, z as MusicTrack, N as NullSequenceSpec, H as PathShapeSpec, J as PolygonShapeSpec, O as PropValue, R as RectShapeSpec, Q as SfxKnobs, U as SfxOptions, V as SfxPreset, W as SfxVoice, X as ShaderSequenceSpec, Y as ShapeSequenceSpec, Z as SlideTransition, _ as Stop, $ as StopSpec, a0 as TransitionCommon, a1 as VideoSequenceSpec, a2 as WipeTransition, a3 as ZoomTransition, a4 as normalizeStops, a5 as pictureStops } from './types-CoT0ypcx.js';
4
+ import { S as Sequence } from './Base-BgnRXbtJ.js';
5
5
  import 'pixi.js';
6
6
  import 'gsap';
7
7
 
@@ -610,7 +610,7 @@ type DeckTransition = TransitionSpec extends infer T ? (T extends TransitionSpec
610
610
  interface DeckOptions {
611
611
  pages: DeckPage[];
612
612
  /**
613
- * A transition between every two pages: `{ kind: 'crossfade' | 'slide' | 'wipe' | 'iris' | 'dip' | 'zoom' | 'dissolve', duration, …its own options }` (see Transitions). The next page starts
613
+ * A transition between every two pages: `{ kind: 'crossfade' | 'slide' | 'wipe' | 'iris' | 'dip' | 'zoom' | 'dissolve' | 'luma', duration, …its own options }` (see Transitions). The next page starts
614
614
  * `duration` seconds before the current one ends, and the transition plays across the overlap.
615
615
  */
616
616
  transition?: DeckTransition;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { CompositionSequence } from './chunk-UQDEDYVM.js';
2
- import { ensureFilterLibrary, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, rand, DEG, timeRemapOf, contentLength, resolveAt, checkEase } from './chunk-DC4JPY6A.js';
3
- export { noise, rand, random, registerSequenceType } from './chunk-DC4JPY6A.js';
4
- import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-YEPDQ7I3.js';
5
- import { collectPropKeys } from './chunk-E7RONUZ7.js';
6
- import { warnUnknownOptions, suggestName } from './chunk-NHICCDTC.js';
1
+ import { CompositionSequence, maskSourceOf } from './chunk-XS6GSJCN.js';
2
+ import { ensureFilterLibrary, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, rand, DEG, timeRemapOf, contentLength, resolveAt, checkEase } from './chunk-PRZ4U6JN.js';
3
+ export { noise, rand, random, registerSequenceType } from './chunk-PRZ4U6JN.js';
4
+ import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-AXZUKNXF.js';
5
+ import { collectPropKeys } from './chunk-TLYTYBWX.js';
6
+ import { warnUnknownOptions, suggestName } from './chunk-BXOCEZ4U.js';
7
7
  import * as PIXI from 'pixi.js';
8
- import { extensions, CullerPlugin, Application, Container, Rectangle, Culler, CanvasTextMetrics, TextStyle, Assets, ExtensionType, Filter, UniformGroup, GpuProgram, GlProgram, defaultFilterVert } from 'pixi.js';
8
+ import { extensions, CullerPlugin, Application, Container, Rectangle, Culler, CanvasTextMetrics, TextStyle, Assets, ExtensionType, Filter, Texture, UniformGroup, GpuProgram, GlProgram, defaultFilterVert } from 'pixi.js';
9
9
  import { gsap } from 'gsap';
10
10
  import { PixiPlugin } from 'gsap/PixiPlugin';
11
11
  import { QUALITY_VERY_HIGH, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_VERY_LOW, Output, BufferTarget, CanvasSource, AudioBufferSource, Input, ALL_FORMATS, BlobSource, WavOutputFormat, Conversion, VideoSampleSink, MkvOutputFormat, WebMOutputFormat, MovOutputFormat, Mp4OutputFormat, getFirstEncodableAudioCodec } from 'mediabunny';
@@ -899,10 +899,10 @@ var MODE_CODES = {
899
899
  var GL_FRAGMENT = `
900
900
  in vec2 vTextureCoord;
901
901
  uniform sampler2D uTexture;
902
- uniform vec4 uInputSize; // PIXI-bound: xy = sprite render texture size (with padding)
903
- uniform vec4 uInputClamp; // PIXI-bound: xy = min uv of unpadded content, zw = max uv
904
- uniform vec4 uOutputFrame; // PIXI-bound: xy = sprite top-left on output, zw = bbox size in px
905
- uniform vec4 uGlobalFrame; // PIXI-bound: xy = global frame offset, zw = canvas size in px
902
+ uniform highp vec4 uInputSize; // PIXI-bound: xy = sprite render texture size (with padding)
903
+ uniform highp vec4 uInputClamp; // PIXI-bound: xy = min uv of unpadded content, zw = max uv
904
+ uniform highp vec4 uOutputFrame; // PIXI-bound: xy = sprite top-left on output, zw = bbox size in px
905
+ uniform highp vec4 uGlobalFrame; // PIXI-bound: xy = global frame offset, zw = canvas size in px
906
906
  uniform float uProgress;
907
907
  uniform float uSmoothing;
908
908
  uniform float uMode;
@@ -1220,6 +1220,133 @@ var TransitionMaskFilter = class extends Filter {
1220
1220
  this.resources.transitionUniforms.uniforms.uSeed = v;
1221
1221
  }
1222
1222
  };
1223
+ var LUMA_MAPS = ["linear", "diagonal", "radial"];
1224
+ var GL = `in vec2 vTextureCoord;
1225
+ uniform sampler2D uTexture;
1226
+ uniform sampler2D uMap;
1227
+ uniform highp vec4 uInputClamp;
1228
+ uniform highp vec4 uOutputFrame;
1229
+ uniform highp vec4 uGlobalFrame;
1230
+ uniform float uProgress;
1231
+ uniform float uSoftness;
1232
+ uniform float uInvert;
1233
+ uniform float uFlip;
1234
+ uniform float uMode;
1235
+ out vec4 finalColor;
1236
+ float lumaOf(vec2 cuv, float aspect) {
1237
+ if (uMode > 2.5) { vec2 p = (cuv - 0.5) * vec2(aspect, 1.0); return clamp(length(p) / (0.5 * length(vec2(aspect, 1.0))), 0.0, 1.0); }
1238
+ if (uMode > 1.5) return clamp((cuv.x + cuv.y) * 0.5, 0.0, 1.0);
1239
+ if (uMode > 0.5) return clamp(cuv.x, 0.0, 1.0);
1240
+ return dot(texture(uMap, cuv).rgb, vec3(0.2126, 0.7152, 0.0722));
1241
+ }
1242
+ void main(void) {
1243
+ vec4 raw = texture(uTexture, vTextureCoord);
1244
+ vec2 bboxUV = (vTextureCoord - uInputClamp.xy) / (uInputClamp.zw - uInputClamp.xy);
1245
+ vec2 cuv = (uOutputFrame.xy + bboxUV * uOutputFrame.zw) / uGlobalFrame.zw;
1246
+ float l = lumaOf(cuv, uGlobalFrame.z / uGlobalFrame.w);
1247
+ if (uFlip > 0.5) l = 1.0 - l;
1248
+ float s = max(uSoftness, 0.0001);
1249
+ float ep = uProgress * (1.0 + 2.0 * s) - s;
1250
+ float reveal = 1.0 - smoothstep(ep - s, ep + s, l);
1251
+ if (uInvert > 0.5) reveal = 1.0 - step(0.99, reveal);
1252
+ finalColor = raw * reveal;
1253
+ }`;
1254
+ var WGSL = `
1255
+ struct GlobalFilterUniforms {
1256
+ uInputSize:vec4<f32>, uInputPixel:vec4<f32>, uInputClamp:vec4<f32>, uOutputFrame:vec4<f32>, uGlobalFrame:vec4<f32>, uOutputTexture:vec4<f32>,
1257
+ };
1258
+ struct LumaUniforms { uProgress:f32, uSoftness:f32, uInvert:f32, uFlip:f32, uMode:f32, };
1259
+ @group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;
1260
+ @group(0) @binding(1) var uTexture: texture_2d<f32>;
1261
+ @group(0) @binding(2) var uSampler : sampler;
1262
+ @group(1) @binding(0) var<uniform> lumaUniforms : LumaUniforms;
1263
+ @group(1) @binding(1) var uMap: texture_2d<f32>;
1264
+ @group(1) @binding(2) var uMapSampler : sampler;
1265
+ struct VSOutput {
1266
+ @builtin(position) position: vec4<f32>,
1267
+ @location(0) uv : vec2<f32>,
1268
+ };
1269
+ @vertex
1270
+ fn mainVertex(
1271
+ @location(0) aPosition : vec2<f32>,
1272
+ ) -> VSOutput {
1273
+ var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;
1274
+ position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;
1275
+ position.y = position.y * (2.0 * gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;
1276
+ return VSOutput(vec4<f32>(position, 0.0, 1.0), aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw));
1277
+ }
1278
+ fn lumaOf(cuv: vec2<f32>, aspect: f32) -> f32 {
1279
+ let mode = lumaUniforms.uMode;
1280
+ if (mode > 2.5) {
1281
+ let p = (cuv - vec2<f32>(0.5)) * vec2<f32>(aspect, 1.0);
1282
+ return clamp(length(p) / (0.5 * length(vec2<f32>(aspect, 1.0))), 0.0, 1.0);
1283
+ }
1284
+ if (mode > 1.5) { return clamp((cuv.x + cuv.y) * 0.5, 0.0, 1.0); }
1285
+ if (mode > 0.5) { return clamp(cuv.x, 0.0, 1.0); }
1286
+ let m = textureSampleLevel(uMap, uMapSampler, cuv, 0.0).rgb;
1287
+ return dot(m, vec3<f32>(0.2126, 0.7152, 0.0722));
1288
+ }
1289
+ @fragment
1290
+ fn mainFragment(@location(0) uv : vec2<f32>) -> @location(0) vec4<f32> {
1291
+ let raw = textureSample(uTexture, uSampler, uv);
1292
+ let bboxUV = (uv - gfu.uInputClamp.xy) / (gfu.uInputClamp.zw - gfu.uInputClamp.xy);
1293
+ let cuv = (gfu.uOutputFrame.xy + bboxUV * gfu.uOutputFrame.zw) / gfu.uGlobalFrame.zw;
1294
+ var l = lumaOf(cuv, gfu.uGlobalFrame.z / gfu.uGlobalFrame.w);
1295
+ if (lumaUniforms.uFlip > 0.5) { l = 1.0 - l; }
1296
+ let s = max(lumaUniforms.uSoftness, 0.0001);
1297
+ let ep = lumaUniforms.uProgress * (1.0 + 2.0 * s) - s;
1298
+ var reveal = 1.0 - smoothstep(ep - s, ep + s, l);
1299
+ if (lumaUniforms.uInvert > 0.5) { reveal = 1.0 - step(0.99, reveal); }
1300
+ return raw * reveal;
1301
+ }`;
1302
+ var LumaWipeFilter = class extends Filter {
1303
+ _mapName;
1304
+ _builtIn;
1305
+ _resolved = false;
1306
+ _warned = false;
1307
+ constructor({ map, softness = 0.1, progress = 0, invert = false, flip = false }) {
1308
+ const t = Texture.WHITE;
1309
+ const mode = LUMA_MAPS.indexOf(map) + 1;
1310
+ super({
1311
+ glProgram: GlProgram.from({ vertex: defaultFilterVert, fragment: GL, name: "pe-luma-wipe" }),
1312
+ gpuProgram: GpuProgram.from({ vertex: { source: WGSL, entryPoint: "mainVertex" }, fragment: { source: WGSL, entryPoint: "mainFragment" } }),
1313
+ resources: {
1314
+ lumaUniforms: new UniformGroup({
1315
+ uProgress: { value: progress, type: "f32" },
1316
+ uSoftness: { value: softness, type: "f32" },
1317
+ uInvert: { value: invert ? 1 : 0, type: "f32" },
1318
+ uFlip: { value: flip ? 1 : 0, type: "f32" },
1319
+ uMode: { value: mode, type: "f32" }
1320
+ }),
1321
+ uMap: t.source,
1322
+ uMapSampler: t.source.style
1323
+ }
1324
+ });
1325
+ this._mapName = map;
1326
+ this._builtIn = mode > 0;
1327
+ }
1328
+ get uProgress() {
1329
+ return this.resources.lumaUniforms.uniforms.uProgress;
1330
+ }
1331
+ set uProgress(v) {
1332
+ this.resources.lumaUniforms.uniforms.uProgress = v;
1333
+ }
1334
+ apply(fm, input, output, clear) {
1335
+ if (!this._builtIn && !this._resolved) {
1336
+ const t = Assets.get(this._mapName);
1337
+ if (t) {
1338
+ this.resources.uMap = t.source;
1339
+ this.resources.uMapSampler = t.source.style;
1340
+ this._resolved = true;
1341
+ } else if (!this._warned) {
1342
+ this._warned = true;
1343
+ const guess = suggestName(this._mapName, LUMA_MAPS);
1344
+ console.warn(`pixi-effects: luma transition map "${this._mapName}" is not a built-in map (${LUMA_MAPS.join(", ")}) and no image asset has that name${guess ? `; did you mean "${guess}"?` : ""}; the wipe follows a white map (everything changes at once)`);
1345
+ }
1346
+ }
1347
+ fm.applyFilter(this, input, output, clear);
1348
+ }
1349
+ };
1223
1350
 
1224
1351
  // src/core/Transitions.ts
1225
1352
  var EPS = 1e-6;
@@ -1274,7 +1401,7 @@ function expandTransitions(spec) {
1274
1401
  });
1275
1402
  const masksParticipants = /* @__PURE__ */ new Set();
1276
1403
  for (const t of transitions) {
1277
- if (t.kind === "wipe" || t.kind === "iris" || t.kind === "dissolve" || t.kind === "zoom") {
1404
+ if (t.kind === "wipe" || t.kind === "iris" || t.kind === "dissolve" || t.kind === "zoom" || t.kind === "luma") {
1278
1405
  masksParticipants.add(t.from);
1279
1406
  masksParticipants.add(t.to);
1280
1407
  }
@@ -1371,6 +1498,9 @@ function expandTransitions(spec) {
1371
1498
  case "dissolve":
1372
1499
  expandDissolve(out, abs, fromEntry.seq, toEntry.seq, i);
1373
1500
  break;
1501
+ case "luma":
1502
+ expandLuma(out, abs, fromEntry.seq, toEntry.seq, i);
1503
+ break;
1374
1504
  }
1375
1505
  rebaseNewKeyframes(fromEntry.seq, nFrom, fromStart);
1376
1506
  rebaseNewKeyframes(toEntry.seq, nTo, toStart);
@@ -1394,7 +1524,11 @@ function wrapAsFullComposition(seq, compW, compH) {
1394
1524
  delete inner.name;
1395
1525
  delete inner.at;
1396
1526
  delete inner.duration;
1527
+ const m = inner.mask;
1528
+ const carriesMatte = m !== void 0 && maskSourceOf(m).kind === "refs";
1529
+ if (carriesMatte) delete inner.mask;
1397
1530
  return {
1531
+ ...carriesMatte ? { mask: m } : {},
1398
1532
  type: "composition",
1399
1533
  name: seq.name,
1400
1534
  at: seq.at,
@@ -1621,6 +1755,20 @@ function expandDissolve(comp, t, fromSeq, toSeq, transitionIndex) {
1621
1755
  });
1622
1756
  fromSeq.filterArea = fullArea;
1623
1757
  }
1758
+ function expandLuma(comp, t, fromSeq, toSeq, transitionIndex) {
1759
+ const ease = t.ease ?? "none";
1760
+ const inName = transitionFilterName(transitionIndex);
1761
+ const outName = `${transitionFilterName(transitionIndex)}-out`;
1762
+ const fullArea = { x: 0, y: 0, width: comp.width ?? 0, height: comp.height ?? 0 };
1763
+ const opts = { map: t.map ?? "linear", softness: t.softness ?? 0.1, flip: t.flip ?? false };
1764
+ for (const [seq, name, invert] of [[toSeq, inName, false], [fromSeq, outName, true]]) {
1765
+ const filters = ensureFilters(seq);
1766
+ rejectReservedNameCollision(filters, seq.name);
1767
+ filters.push({ type: "custom", name, filter: new LumaWipeFilter({ ...opts, invert }) });
1768
+ ensureKeyframes(seq).push({ at: t.at, to: { [`filters.${name}.uProgress`]: 1 }, duration: t.duration, ease });
1769
+ seq.filterArea = fullArea;
1770
+ }
1771
+ }
1624
1772
  var OWN_NAME_PATTERN = /^_pe-transition-\d+(-out)?$/;
1625
1773
  function rejectReservedNameCollision(filters, seqName) {
1626
1774
  for (const f of filters) {
@@ -1660,7 +1808,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
1660
1808
  blending.add(w.to);
1661
1809
  }
1662
1810
  }
1663
- comp.layers().forEach(({ seq, display, threeD, carriers, depthBlur }, i) => {
1811
+ comp.layers().forEach(({ seq, display, threeD, carriers, depthBlur, light }, i) => {
1664
1812
  const t = seq.target;
1665
1813
  const name = seq.spec.name;
1666
1814
  const label = name ?? `${seq.spec.type}#${i}`;
@@ -1692,6 +1840,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
1692
1840
  const zero = parentZero || zeroScale(t) || carriers.some((c) => zeroScale(c.target));
1693
1841
  const info = { path: prefix + label, name, type: seq.spec.type, threeD, visible, alpha, moving, bounds, onCanvas };
1694
1842
  if (threeD) info.depthBlur = Number(depthBlur.toFixed(2));
1843
+ if (threeD && light !== void 0) info.light = Number(light.toFixed(2));
1695
1844
  layers.push(info);
1696
1845
  let shown = bounds ? clip(bounds, view) : null;
1697
1846
  const maskTarget = seq.maskSequence?.target;
@@ -1830,6 +1979,7 @@ var COLORS = {
1830
1979
  composition: "#8ea4c8",
1831
1980
  three: "#ff9f68",
1832
1981
  camera: "#b0b0b0",
1982
+ light: "#b0b0b0",
1833
1983
  null: "#b0b0b0"
1834
1984
  };
1835
1985
  var esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -1950,6 +2100,9 @@ function startWhenRunning(ctx, start, gesture) {
1950
2100
  return stop;
1951
2101
  }
1952
2102
  var GESTURES = ["pointerdown", "mousedown", "touchend", "keydown"];
2103
+ function audioIsBlocked(ctx, hasAudio) {
2104
+ return !!ctx && hasAudio && ctx.state !== "running";
2105
+ }
1953
2106
 
1954
2107
  // src/core/poster.ts
1955
2108
  function normalizePoster(poster, duration, frameRate) {
@@ -2242,6 +2395,10 @@ var Movie = class {
2242
2395
  get isReady() {
2243
2396
  return this._initState === "ready";
2244
2397
  }
2398
+ /** True while the movie has sound but the browser keeps it silent until the viewer taps (iOS Safari, a page nobody has touched): a player can show "tap for sound"; the sound starts at a tap or key press that arrives while play() is pending, or at the next play() made from a tap. */
2399
+ get audioBlocked() {
2400
+ return audioIsBlocked(this._audioContext, !!this.audioBuffer);
2401
+ }
2245
2402
  /** The poster time as a frame number, or null. */
2246
2403
  get posterFrame() {
2247
2404
  return this._posterFrame;
@@ -2323,7 +2480,7 @@ var Movie = class {
2323
2480
  this._rootContainer = root;
2324
2481
  const audioContext = this._ensureAudioContext();
2325
2482
  await loadAssetBundle(options.assets ?? [], audioContext);
2326
- const rootShape = { width: this.width, height: this.height, duration: this.duration };
2483
+ const rootShape = { width: this.width, height: this.height, duration: this.duration, frameRate: this.frameRate };
2327
2484
  const seededComposition = options.composition ? {
2328
2485
  ...options.composition,
2329
2486
  width: options.composition.width ?? this.width,
@@ -3912,7 +4069,7 @@ async function audioEnvelope(source, options = {}) {
3912
4069
 
3913
4070
  // src/audio/musicEnvelope.ts
3914
4071
  async function musicEnvelope(music, options = {}) {
3915
- const { resolveMusic, renderMusic, musicLength, musicBeatTimes, TempoMap } = await import('./music-FUN7N225.js');
4072
+ const { resolveMusic, renderMusic, musicLength, musicBeatTimes, TempoMap } = await import('./music-AF4VTFAF.js');
3916
4073
  const messages = [];
3917
4074
  const m = resolveMusic(music, "musicEnvelope()", (msg) => messages.push(msg));
3918
4075
  if (!m) throw new Error(`pixi-effects: musicEnvelope(): ${messages.join(" ") || "the music has nothing to play"}`);
@@ -3925,7 +4082,7 @@ async function musicEnvelope(music, options = {}) {
3925
4082
 
3926
4083
  // src/audio/musicBuffer.ts
3927
4084
  async function musicBuffer(music, options = {}) {
3928
- const { resolveMusic, renderMusic, musicLength } = await import('./music-FUN7N225.js');
4085
+ const { resolveMusic, renderMusic, musicLength } = await import('./music-AF4VTFAF.js');
3929
4086
  const messages = [];
3930
4087
  const m = resolveMusic(music, "musicBuffer()", (msg) => messages.push(msg));
3931
4088
  if (!m) throw new Error(`pixi-effects: musicBuffer(): ${messages.join(" ") || "the music has nothing to play"}`);