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.
- package/CHANGELOG.md +37 -0
- package/README.md +17 -15
- package/ai/CHAT.md +2 -2
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +10 -3
- package/ai/tools/pixi-effects.mjs +48 -0
- package/ai/tools/render.mjs +3 -3
- package/ai/tools/view.mjs +3 -3
- package/dist/{Base-gu-5X0Cv.d.ts → Base-BgnRXbtJ.d.ts} +1 -1
- package/dist/{Base-BzlPgd-D.d.cts → Base-DHVKqA46.d.cts} +1 -1
- package/dist/Composition-2GJSCHPP.cjs +16 -0
- package/dist/{Composition-BK5SH6J7.cjs.map → Composition-2GJSCHPP.cjs.map} +1 -1
- package/dist/Composition-C4FSWJZF.js +7 -0
- package/dist/{Composition-Q5TVG3HM.js.map → Composition-C4FSWJZF.js.map} +1 -1
- package/dist/Controller.cjs +2 -2
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Controller.js +1 -1
- package/dist/{Movie--_TJvdJa.d.ts → Movie-DP5p1r4E.d.ts} +5 -1
- package/dist/{Movie-DMxOoTdW.d.cts → Movie-DXReF4-W.d.cts} +5 -1
- package/dist/Presenter.cjs +2 -2
- package/dist/Presenter.d.cts +2 -2
- package/dist/Presenter.d.ts +2 -2
- package/dist/Presenter.js +1 -1
- package/dist/{blendModes-HCP5XTNP.js → blendModes-G3NOAU3T.js} +5 -5
- package/dist/{blendModes-HCP5XTNP.js.map → blendModes-G3NOAU3T.js.map} +1 -1
- package/dist/{blendModes-5E4G2ZZQ.cjs → blendModes-YV43K6E7.cjs} +6 -6
- package/dist/{blendModes-5E4G2ZZQ.cjs.map → blendModes-YV43K6E7.cjs.map} +1 -1
- package/dist/{chunk-K4JVI5HK.cjs → chunk-3DLYAPK7.cjs} +7 -9
- package/dist/{chunk-K4JVI5HK.cjs.map → chunk-3DLYAPK7.cjs.map} +1 -1
- package/dist/{chunk-YEPDQ7I3.js → chunk-AXZUKNXF.js} +6 -6
- package/dist/{chunk-YEPDQ7I3.js.map → chunk-AXZUKNXF.js.map} +1 -1
- package/dist/{chunk-NHICCDTC.js → chunk-BXOCEZ4U.js} +12 -3
- package/dist/chunk-BXOCEZ4U.js.map +1 -0
- package/dist/{chunk-IFZOI3JQ.cjs → chunk-DP37TTMO.cjs} +842 -40
- package/dist/chunk-DP37TTMO.cjs.map +1 -0
- package/dist/{chunk-BPTW7L25.cjs → chunk-ECA2WNRX.cjs} +23 -9
- package/dist/chunk-ECA2WNRX.cjs.map +1 -0
- package/dist/{chunk-DC4JPY6A.js → chunk-PRZ4U6JN.js} +814 -22
- package/dist/chunk-PRZ4U6JN.js.map +1 -0
- package/dist/chunk-SY27HZC5.cjs +1727 -0
- package/dist/chunk-SY27HZC5.cjs.map +1 -0
- package/dist/{chunk-E7RONUZ7.js → chunk-TLYTYBWX.js} +20 -6
- package/dist/chunk-TLYTYBWX.js.map +1 -0
- package/dist/{chunk-UZTKEYFP.cjs → chunk-TWZNOUM7.cjs} +12 -3
- package/dist/chunk-TWZNOUM7.cjs.map +1 -0
- package/dist/chunk-XS6GSJCN.js +1724 -0
- package/dist/chunk-XS6GSJCN.js.map +1 -0
- package/dist/index.cjs +234 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +173 -16
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/{music-FUN7N225.js → music-AF4VTFAF.js} +3 -3
- package/dist/{music-FUN7N225.js.map → music-AF4VTFAF.js.map} +1 -1
- package/dist/{music-GEAH2XCT.cjs → music-KB7YZLHP.cjs} +7 -7
- package/dist/{music-GEAH2XCT.cjs.map → music-KB7YZLHP.cjs.map} +1 -1
- package/dist/{sfx-2DYTYNYW.cjs → sfx-2O6UQEUP.cjs} +8 -8
- package/dist/{sfx-2DYTYNYW.cjs.map → sfx-2O6UQEUP.cjs.map} +1 -1
- package/dist/{sfx-3IDAJ3UZ.js → sfx-VUKARHDX.js} +3 -3
- package/dist/{sfx-3IDAJ3UZ.js.map → sfx-VUKARHDX.js.map} +1 -1
- package/dist/three.cjs +7 -7
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +3 -3
- package/dist/{types-DBbZVKGS.d.cts → types-CoT0ypcx.d.cts} +60 -4
- package/dist/{types-DBbZVKGS.d.ts → types-CoT0ypcx.d.ts} +60 -4
- package/docs/api.md +2 -2
- package/docs/dsl.md +140 -7
- package/llms-full.txt +328 -39
- package/llms.txt +6 -5
- package/package.json +3 -3
- package/{ai → skills/pixi-effects}/SKILL.md +16 -12
- package/{ai → skills/pixi-effects}/reference/cheatsheet.md +10 -7
- package/{ai → skills/pixi-effects}/reference/pitfalls.md +22 -4
- package/{ai → skills/pixi-effects}/reference/recipes.md +133 -2
- package/{ai/tools → skills/pixi-effects/scripts}/save-image.py +1 -1
- package/{ai → skills/pixi-effects}/template.html +6 -6
- package/dist/Composition-BK5SH6J7.cjs +0 -16
- package/dist/Composition-Q5TVG3HM.js +0 -7
- package/dist/chunk-BPTW7L25.cjs.map +0 -1
- package/dist/chunk-DC4JPY6A.js.map +0 -1
- package/dist/chunk-E7RONUZ7.js.map +0 -1
- package/dist/chunk-IFZOI3JQ.cjs.map +0 -1
- package/dist/chunk-MHOO2CVU.cjs +0 -840
- package/dist/chunk-MHOO2CVU.cjs.map +0 -1
- package/dist/chunk-NHICCDTC.js.map +0 -1
- package/dist/chunk-UQDEDYVM.js +0 -838
- package/dist/chunk-UQDEDYVM.js.map +0 -1
- 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-
|
|
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-
|
|
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
|
|
4
|
-
import { S as Sequence } from './Base-
|
|
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
|
|
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-
|
|
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
|
|
4
|
-
import { S as Sequence } from './Base-
|
|
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-
|
|
2
|
-
import { ensureFilterLibrary, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, rand, DEG, timeRemapOf, contentLength, resolveAt, checkEase } from './chunk-
|
|
3
|
-
export { noise, rand, random, registerSequenceType } from './chunk-
|
|
4
|
-
import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-
|
|
5
|
-
import { collectPropKeys } from './chunk-
|
|
6
|
-
import { warnUnknownOptions, suggestName } from './chunk-
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -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-
|
|
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-
|
|
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"}`);
|