pixi-effects 0.43.0 → 0.44.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 +10 -0
- package/README.md +5 -5
- package/ai/chat-template.html +3 -3
- package/ai/tools/check.mjs +131 -2
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/{Movie-BdUm2Mc9.d.cts → Movie-B3VOAgwc.d.cts} +3 -3
- package/dist/{Movie-B_qQIYV6.d.ts → Movie-CQCVUqRs.d.ts} +3 -3
- package/dist/{chunk-6N5ZBUOU.js → chunk-4MBTYREC.js} +81 -31
- package/dist/chunk-4MBTYREC.js.map +1 -0
- package/dist/{chunk-BEGOKE7Q.cjs → chunk-MAAM45ZX.cjs} +80 -30
- package/dist/chunk-MAAM45ZX.cjs.map +1 -0
- package/dist/index.cjs +25 -25
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -1
- package/dist/loader.css +1 -1
- package/dist/present.cjs +1 -1
- package/dist/present.d.cts +2 -2
- package/dist/present.d.ts +2 -2
- package/dist/present.js +1 -1
- package/dist/three.cjs +86 -16
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +22 -2
- package/dist/three.d.ts +22 -2
- package/dist/three.js +86 -16
- package/dist/three.js.map +1 -1
- package/dist/{types-DiNHtdrS.d.cts → types-C5xo0fzb.d.cts} +74 -2
- package/dist/{types-DiNHtdrS.d.ts → types-C5xo0fzb.d.ts} +74 -2
- package/docs/api.md +4 -2
- package/docs/dsl.md +1 -0
- package/llms-full.txt +9 -6
- package/package.json +1 -1
- package/skills/pixi-effects/SKILL.md +2 -2
- package/skills/pixi-effects/reference/recipes.md +2 -2
- package/skills/pixi-effects/template.html +6 -6
- package/dist/Base-DKFQtqzW.d.ts +0 -60
- package/dist/Base-lb5Uhaqu.d.cts +0 -60
- package/dist/chunk-6N5ZBUOU.js.map +0 -1
- package/dist/chunk-BEGOKE7Q.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TextureSource } from 'pixi.js';
|
|
1
|
+
import { TextureSource, Container } from 'pixi.js';
|
|
2
2
|
|
|
3
3
|
/** What an author writes in `composition.stops`: a time in seconds, or an object. */
|
|
4
4
|
interface StopSpec {
|
|
@@ -120,6 +120,76 @@ interface SharedGpu {
|
|
|
120
120
|
adopt(source: TextureSource, texture: unknown): void;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Resolves a routed keyframe path to a concrete tween target.
|
|
125
|
+
* `path` is everything after the registered prefix + dot (for
|
|
126
|
+
* `three.cube.rotation.y` under prefix `three`, path = `cube.rotation.y`).
|
|
127
|
+
* Return null to skip the key (the router is expected to have warned).
|
|
128
|
+
*/
|
|
129
|
+
type PathRouter = (path: string) => {
|
|
130
|
+
target: object;
|
|
131
|
+
prop: string;
|
|
132
|
+
} | null;
|
|
133
|
+
type PathRouters = Record<string, PathRouter>;
|
|
134
|
+
|
|
135
|
+
/** Variables available to expression evaluation. */
|
|
136
|
+
interface Scope {
|
|
137
|
+
w: number;
|
|
138
|
+
h: number;
|
|
139
|
+
W: number;
|
|
140
|
+
H: number;
|
|
141
|
+
GW: number;
|
|
142
|
+
GH: number;
|
|
143
|
+
contain: number;
|
|
144
|
+
cover: number;
|
|
145
|
+
t: number;
|
|
146
|
+
d: number;
|
|
147
|
+
T: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
declare abstract class Sequence {
|
|
151
|
+
spec: SequenceSpec;
|
|
152
|
+
parent: CompositionShape | null;
|
|
153
|
+
root: CompositionShape;
|
|
154
|
+
target: Container | null;
|
|
155
|
+
intrinsicWidth: number;
|
|
156
|
+
intrinsicHeight: number;
|
|
157
|
+
at: number;
|
|
158
|
+
duration: number | undefined;
|
|
159
|
+
constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape);
|
|
160
|
+
abstract build(): Promise<void>;
|
|
161
|
+
buildFilters(): void;
|
|
162
|
+
scope(): Scope;
|
|
163
|
+
/**
|
|
164
|
+
* Prefix routers contributed to the keyframe pipeline (e.g. `three.` in
|
|
165
|
+
* pixi-effects/three). Base sequences route nothing extra.
|
|
166
|
+
*/
|
|
167
|
+
protected pathRouters(): PathRouters;
|
|
168
|
+
/**
|
|
169
|
+
* The `initial` and `keyframes` that go onto the display object. A layer whose `time` runs a clock (video, composition) takes `time`
|
|
170
|
+
* out of them: it is not a property of the display object.
|
|
171
|
+
*/
|
|
172
|
+
protected displayProps(): {
|
|
173
|
+
initial: SequenceSpec['initial'];
|
|
174
|
+
keyframes: SequenceSpec['keyframes'];
|
|
175
|
+
};
|
|
176
|
+
destroy(): void;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Keeping a layer's expensive state across a rebuild (`setVars`, `resize`, `rebuild`): the new tree is built while the old one still plays, and a layer that cannot be told apart from
|
|
181
|
+
* one of the old tree (same name, same setup, same size and options) may take over that layer's scene and renderer instead of building its own. Today only the `three` layer does:
|
|
182
|
+
* its setup may load a model, and its renderer owns a graphics context.
|
|
183
|
+
*
|
|
184
|
+
* It is a loan until the swap: the new layer borrows, the old one goes on drawing, and `commitReuse` (called by the movie once the new tree is on stage) makes it the owner. A new tree that
|
|
185
|
+
* is thrown away before that leaves the old layers as they were.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
/** What a layer that can borrow calls. */
|
|
189
|
+
interface ReusePool {
|
|
190
|
+
claim(key: string): Sequence | null;
|
|
191
|
+
}
|
|
192
|
+
|
|
123
193
|
/**
|
|
124
194
|
* pixi-effects public DSL types.
|
|
125
195
|
*
|
|
@@ -877,6 +947,8 @@ interface CompositionShape {
|
|
|
877
947
|
spaceAt?: (t: number) => SpaceNow;
|
|
878
948
|
/** The GPU device PixiJS draws with, on the root shape only and only when PixiJS runs on WebGPU: a `three` layer with `renderer: 'webgpu'` draws on it instead of on a canvas of its own. */
|
|
879
949
|
gpu?: SharedGpu;
|
|
950
|
+
/** The layers of the tree that a rebuild replaces, that a new layer of the same kind may take the state of instead of building its own (`three` layers: see core/reuse.ts). Root shape only. */
|
|
951
|
+
reuse?: ReusePool;
|
|
880
952
|
}
|
|
881
953
|
/** The composition's camera and the lights alive at one moment (what its `camera` and `light` layers say, after their keyframes). */
|
|
882
954
|
interface SpaceNow {
|
|
@@ -885,4 +957,4 @@ interface SpaceNow {
|
|
|
885
957
|
fog: FogState | null;
|
|
886
958
|
}
|
|
887
959
|
|
|
888
|
-
export type
|
|
960
|
+
export { type SfxPreset as $, type AssetSpec as A, type BlendModeName as B, type CompositionSpec as C, type DipTransition as D, type EllipseShapeSpec as E, type FilterSpec as F, type GradientSpec as G, type MaskRefSpec as H, type ImageSequenceSpec as I, type MatteRefSpec as J, type Keyframe as K, type LightSequenceSpec as L, type MusicOptions as M, type MusicDrum as N, type MusicDrums as O, type Props as P, type MusicInstrument as Q, type MusicLevel as R, type SequenceSpec as S, type TransitionSpec as T, type MusicTrack as U, type NullSequenceSpec as V, type PathShapeSpec as W, type PolygonShapeSpec as X, type RectShapeSpec as Y, type SfxKnobs as Z, type SfxOptions as _, type Stop as a, type SfxVoice as a0, type ShaderSequenceSpec as a1, type ShapeSequenceSpec as a2, type SlideTransition as a3, type StopSpec as a4, type TextSpan as a5, type TransitionCommon as a6, type VideoSequenceSpec as a7, type WipeTransition as a8, type ZoomTransition as a9, type SpaceNow as b, type SequenceCommon as c, type PropValue as d, Sequence as e, type PathRouters as f, type CompositionShape as g, type CameraSequenceSpec as h, type TextSequenceSpec as i, type ArcShapeSpec as j, type AudioAssetSpec as k, type AudioMusicSpec as l, type AudioSequenceSpec as m, type AudioSfxSpec as n, type CanvasInfo as o, type CanvasSequenceSpec as p, type ChromaKeyFilterSpec as q, type CircleShapeSpec as r, type CompositionSequenceSpec as s, type CrossfadeTransition as t, type CustomFilterSpec as u, type DissolveTransition as v, type Expr as w, type IrisTransition as x, type LineShapeSpec as y, type LumaTransition as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TextureSource } from 'pixi.js';
|
|
1
|
+
import { TextureSource, Container } from 'pixi.js';
|
|
2
2
|
|
|
3
3
|
/** What an author writes in `composition.stops`: a time in seconds, or an object. */
|
|
4
4
|
interface StopSpec {
|
|
@@ -120,6 +120,76 @@ interface SharedGpu {
|
|
|
120
120
|
adopt(source: TextureSource, texture: unknown): void;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Resolves a routed keyframe path to a concrete tween target.
|
|
125
|
+
* `path` is everything after the registered prefix + dot (for
|
|
126
|
+
* `three.cube.rotation.y` under prefix `three`, path = `cube.rotation.y`).
|
|
127
|
+
* Return null to skip the key (the router is expected to have warned).
|
|
128
|
+
*/
|
|
129
|
+
type PathRouter = (path: string) => {
|
|
130
|
+
target: object;
|
|
131
|
+
prop: string;
|
|
132
|
+
} | null;
|
|
133
|
+
type PathRouters = Record<string, PathRouter>;
|
|
134
|
+
|
|
135
|
+
/** Variables available to expression evaluation. */
|
|
136
|
+
interface Scope {
|
|
137
|
+
w: number;
|
|
138
|
+
h: number;
|
|
139
|
+
W: number;
|
|
140
|
+
H: number;
|
|
141
|
+
GW: number;
|
|
142
|
+
GH: number;
|
|
143
|
+
contain: number;
|
|
144
|
+
cover: number;
|
|
145
|
+
t: number;
|
|
146
|
+
d: number;
|
|
147
|
+
T: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
declare abstract class Sequence {
|
|
151
|
+
spec: SequenceSpec;
|
|
152
|
+
parent: CompositionShape | null;
|
|
153
|
+
root: CompositionShape;
|
|
154
|
+
target: Container | null;
|
|
155
|
+
intrinsicWidth: number;
|
|
156
|
+
intrinsicHeight: number;
|
|
157
|
+
at: number;
|
|
158
|
+
duration: number | undefined;
|
|
159
|
+
constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape);
|
|
160
|
+
abstract build(): Promise<void>;
|
|
161
|
+
buildFilters(): void;
|
|
162
|
+
scope(): Scope;
|
|
163
|
+
/**
|
|
164
|
+
* Prefix routers contributed to the keyframe pipeline (e.g. `three.` in
|
|
165
|
+
* pixi-effects/three). Base sequences route nothing extra.
|
|
166
|
+
*/
|
|
167
|
+
protected pathRouters(): PathRouters;
|
|
168
|
+
/**
|
|
169
|
+
* The `initial` and `keyframes` that go onto the display object. A layer whose `time` runs a clock (video, composition) takes `time`
|
|
170
|
+
* out of them: it is not a property of the display object.
|
|
171
|
+
*/
|
|
172
|
+
protected displayProps(): {
|
|
173
|
+
initial: SequenceSpec['initial'];
|
|
174
|
+
keyframes: SequenceSpec['keyframes'];
|
|
175
|
+
};
|
|
176
|
+
destroy(): void;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Keeping a layer's expensive state across a rebuild (`setVars`, `resize`, `rebuild`): the new tree is built while the old one still plays, and a layer that cannot be told apart from
|
|
181
|
+
* one of the old tree (same name, same setup, same size and options) may take over that layer's scene and renderer instead of building its own. Today only the `three` layer does:
|
|
182
|
+
* its setup may load a model, and its renderer owns a graphics context.
|
|
183
|
+
*
|
|
184
|
+
* It is a loan until the swap: the new layer borrows, the old one goes on drawing, and `commitReuse` (called by the movie once the new tree is on stage) makes it the owner. A new tree that
|
|
185
|
+
* is thrown away before that leaves the old layers as they were.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
/** What a layer that can borrow calls. */
|
|
189
|
+
interface ReusePool {
|
|
190
|
+
claim(key: string): Sequence | null;
|
|
191
|
+
}
|
|
192
|
+
|
|
123
193
|
/**
|
|
124
194
|
* pixi-effects public DSL types.
|
|
125
195
|
*
|
|
@@ -877,6 +947,8 @@ interface CompositionShape {
|
|
|
877
947
|
spaceAt?: (t: number) => SpaceNow;
|
|
878
948
|
/** The GPU device PixiJS draws with, on the root shape only and only when PixiJS runs on WebGPU: a `three` layer with `renderer: 'webgpu'` draws on it instead of on a canvas of its own. */
|
|
879
949
|
gpu?: SharedGpu;
|
|
950
|
+
/** The layers of the tree that a rebuild replaces, that a new layer of the same kind may take the state of instead of building its own (`three` layers: see core/reuse.ts). Root shape only. */
|
|
951
|
+
reuse?: ReusePool;
|
|
880
952
|
}
|
|
881
953
|
/** The composition's camera and the lights alive at one moment (what its `camera` and `light` layers say, after their keyframes). */
|
|
882
954
|
interface SpaceNow {
|
|
@@ -885,4 +957,4 @@ interface SpaceNow {
|
|
|
885
957
|
fog: FogState | null;
|
|
886
958
|
}
|
|
887
959
|
|
|
888
|
-
export type
|
|
960
|
+
export { type SfxPreset as $, type AssetSpec as A, type BlendModeName as B, type CompositionSpec as C, type DipTransition as D, type EllipseShapeSpec as E, type FilterSpec as F, type GradientSpec as G, type MaskRefSpec as H, type ImageSequenceSpec as I, type MatteRefSpec as J, type Keyframe as K, type LightSequenceSpec as L, type MusicOptions as M, type MusicDrum as N, type MusicDrums as O, type Props as P, type MusicInstrument as Q, type MusicLevel as R, type SequenceSpec as S, type TransitionSpec as T, type MusicTrack as U, type NullSequenceSpec as V, type PathShapeSpec as W, type PolygonShapeSpec as X, type RectShapeSpec as Y, type SfxKnobs as Z, type SfxOptions as _, type Stop as a, type SfxVoice as a0, type ShaderSequenceSpec as a1, type ShapeSequenceSpec as a2, type SlideTransition as a3, type StopSpec as a4, type TextSpan as a5, type TransitionCommon as a6, type VideoSequenceSpec as a7, type WipeTransition as a8, type ZoomTransition as a9, type SpaceNow as b, type SequenceCommon as c, type PropValue as d, Sequence as e, type PathRouters as f, type CompositionShape as g, type CameraSequenceSpec as h, type TextSequenceSpec as i, type ArcShapeSpec as j, type AudioAssetSpec as k, type AudioMusicSpec as l, type AudioSequenceSpec as m, type AudioSfxSpec as n, type CanvasInfo as o, type CanvasSequenceSpec as p, type ChromaKeyFilterSpec as q, type CircleShapeSpec as r, type CompositionSequenceSpec as s, type CrossfadeTransition as t, type CustomFilterSpec as u, type DissolveTransition as v, type Expr as w, type IrisTransition as x, type LineShapeSpec as y, type LumaTransition as z };
|
package/docs/api.md
CHANGED
|
@@ -96,7 +96,7 @@ interface RebuildReport { reason: 'vars' | 'resize' | 'rebuild'; ms: number; aud
|
|
|
96
96
|
- The new composition is built while the old one goes on; at the swap the movie keeps doing what it is doing at that moment: the same frame, playing or paused (a `pause()`, a seek or a `play()` you made during the build is kept), the poster if it was shown. A playing movie whose sound is unchanged (`audio: 'reused'`) is not stopped at all: the frame clock and the sound go on and only the picture is swapped, so rebuilds in a row (a pointer) do not hold the playhead back. When the sound changed, the movie stops and plays on from the same frame with the new sound. A `playUntil()` in flight ends. The canvas changes size at the swap, not before. A `render()` or `peek()` in flight is not interrupted: the swap waits for it.
|
|
97
97
|
- The sound is mixed only when it changed: `audio: 'reused'` means the same mix as before (the mix is the slow part, 0.6 to 0.8 s for a film; the rest takes about 20 ms). A time remap (`warp` / `sourceMap`) turns the cache off.
|
|
98
98
|
- Calls that arrive during a rebuild are joined: at most one rebuild runs and one waits, with the latest values. Safe to call from `pointermove` or `scroll`: a rebuild that leaves the sound alone takes tens of milliseconds (11 to 42 ms on four gallery pieces), one that mixes the sound again 0.6 to 0.8 s, so a slider that changes the sound will lag behind the hand.
|
|
99
|
-
- A rebuild builds every layer again, a `three` layer
|
|
99
|
+
- A rebuild builds every layer again, **except a `three` layer that did not change**: one with a `name`, the same `setup` function, the same size and options keeps its scene, its renderer (and its graphics context) and its texture, so `setup` does not run again and a model is not loaded again (measured on a box scene: 15 ms for a rebuild of a WebGL layer built again, 1 ms kept; WebGPU 7 ms against 1 ms). `update` is the new composition's own and runs on the kept scene. A layer with no `name`, another size or another `setup`, or `reuse: false` is built again (the old one is disposed once, when the swap is done; a rebuild that fails leaves the old one untouched). Put what must follow a variable in `update` or in keyframes, not in `setup`; a `setup` that reads `movie.vars` needs `reuse: false`. A model still loads again when the composition changes (`rebuild({ composition })` with a new `setup` function).
|
|
100
100
|
- A rebuild that fails (a bad expression, a missing asset, a size that is not pixels) rejects, emits `error` with `where: 'rebuild'`, and the movie goes on with what it had. A `destroy()` during a rebuild ends it the same way.
|
|
101
101
|
- To follow a window: observe a CSS-sized box around the canvas, not the canvas itself (the movie sets the canvas's pixel size): `new ResizeObserver(() => movie.resize(Math.round(box.clientWidth * devicePixelRatio), Math.round(box.clientHeight * devicePixelRatio))).observe(box)` (the `liquid-layout` recipe).
|
|
102
102
|
|
|
@@ -182,9 +182,11 @@ interface PickHit {
|
|
|
182
182
|
// options: { only?: string[], ignore?: string[], alpha?: number } layer names or paths; alpha: see below
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
+
The hit is the layer that was drawn at the point, not the group it is in: a card made of a `composition` with a face and a label gives the face (`name: 'face0'`, `path: 'card0/face0'`), and a layer with no name of its own gives no `name` at all. To know which group was hit, read the first segment of the path (`hit.path.split('/')[0]`); `only: ['card0']` asks only about the group (a group's name stands for everything in it).
|
|
186
|
+
|
|
185
187
|
A `three` layer covers its whole picture, but only what its ray meets is a hit: elsewhere the layers below are hit (a title, the background). `only` / `ignore` entries are layer names or paths, and a group's name (a nested composition) stands for everything in it: a card and its label are one target as `only: ['card']`.
|
|
186
188
|
|
|
187
|
-
How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box; a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. **`{ alpha }` looks at the picture, not the box**: `movie.pick(x, y, { alpha: 0.1 })` leaves out a pixel of an image, a video or a `
|
|
189
|
+
How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box (or by their picture with `alpha`); a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. **`{ alpha }` looks at the picture, not the box**: `movie.pick(x, y, { alpha: 0.1 })` leaves out a pixel of an image, a video, a `canvas` layer or the letters of a `text` layer (the gap between letters, the hole of an O: a text layer is its glyphs, drawn again once per text and style with PixiJS's own generator; measured 2026-10-17: it agrees with the picture on over 95 % of the points of three texts, the rest are antialiased edges) whose alpha is at or below 0.1 (a transparent corner of a logo, the clear part of a circle drawn on a canvas); without it the box is the picture and nothing is read. Shapes are always hit by their outline, text and `shader` layers by their box (a shader's WebGL picture cannot be read back safely). A picture that cannot be read (an image from another origin: load it with `crossorigin="anonymous"` or from the same site) stays a hit, with one warning. What is not here: touch with several fingers.
|
|
188
190
|
|
|
189
191
|
**Dragging an object of a `three` layer**: `hit.three.grab(plane)` fixes a plane through the point that was taken (`'screen'` facing the camera, the default; `'floor'` horizontal; `'wall'` with z constant; or a normal `[x, y, z]`), and `grab.move(x, y)` takes the pointer in canvas pixels and gives where its ray meets that plane (`point`) and how far that is from the point taken (`delta`; `null` where the ray never meets the plane: a floor seen edge-on). Move the object by `delta`, from where it was when it was taken, and it follows the pointer exactly. The ray is the layer's own camera's (with `followCamera`, the composition's). The layer's `update` should read where the object is from the page's own state, and the page calls `await movie.redraw()` to draw the frame again while the movie is paused (recipe `drag-3d`).
|
|
190
192
|
|
package/docs/dsl.md
CHANGED
|
@@ -777,6 +777,7 @@ three({
|
|
|
777
777
|
| `setup` | `(ctx: ThreeContext) => Promise<ThreeSetupResult \| void> \| ThreeSetupResult \| void` | builds the scene once. Add objects to `ctx.scene`, position `ctx.camera` (or replace it via `{ camera }`). Async, so `Movie.init` can await GLTF / texture loading. |
|
|
778
778
|
| `followCamera?` | `boolean` | the layer's camera is the composition's `camera` layer (see [below](#living-in-the-compositions-space-followcamera-followlights)). |
|
|
779
779
|
| `followLights?` | `boolean` | the composition's `light` layers become three lights in the scene (see below). |
|
|
780
|
+
| `reuse?` | `boolean` | a rebuild (`setVars`, `resize`, `rebuild`) keeps a layer that did not change (same `name`, `setup`, size, options): its `setup` runs once. Default `true`; `false` runs `setup` at every rebuild (when it reads a value that variables change). |
|
|
780
781
|
| `update?` | `(t: number, ctx: ThreeContext) => void` | optional per-frame hook; `t` is sequence-local time in seconds. |
|
|
781
782
|
| `dispose?` | `(ctx: ThreeContext) => void` | cleanup for user-created GPU resources (geometries, materials, textures). Called from `destroy()`. |
|
|
782
783
|
|
package/llms-full.txt
CHANGED
|
@@ -6,7 +6,7 @@ Concatenation of the skill, cheatsheet, pitfalls, recipes and the DSL / API / me
|
|
|
6
6
|
|
|
7
7
|
<!-- ===== skills/pixi-effects/SKILL.md ===== -->
|
|
8
8
|
|
|
9
|
-
> Written for pixi-effects 0.
|
|
9
|
+
> Written for pixi-effects 0.44.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
|
|
10
10
|
|
|
11
11
|
# pixi-effects — write a video as data
|
|
12
12
|
|
|
@@ -34,7 +34,7 @@ You describe a video as a tree of plain objects; the library plays it in a canva
|
|
|
34
34
|
**Read `reference/direction.md` before writing a composition for a product film, a company introduction, a launch or a data story.** It is renderer-neutral: write `brief.md` (the one sentence to remember, the REAL assets with paths, what must never be invented; if a needed asset is missing, stop and ask), `style-guide.md` (palette and type taken from the real source, a motion rule per class of object) and `shotlist.md` (a row per beat with entry and exit state) next to the page; then build, then review the rendered frames cold. What is specific to this library:
|
|
35
35
|
|
|
36
36
|
- **Time and sound:** pick a tempo whose bar is a round number of seconds (96 bpm: 2.5 s; 120 bpm: 2 s), put every cut on a bar line and every sfx on its beat. `npx pixi-effects check` prints a `music` read-back (bars per track, what starts on which beat, the drum span): verify the sound with it.
|
|
37
|
-
- **Interactive pages (a person clicks, hovers, drags):** `movie.pick(x, y)` says what is under a point, `movie.hover({ onEnter, onLeave })` and the recipes `pick-click`, `drag-drop`, `drag-3d` build on it; `check
|
|
37
|
+
- **Interactive pages (a person clicks, hovers, drags):** `movie.pick(x, y)` says what is under a point, `movie.hover({ onEnter, onLeave })` and the recipes `pick-click`, `drag-drop`, `drag-3d` build on it; **test the page with `check --do "hover Lime; click Lime; drag card > 770,240; wait 1"`**: real mouse and key events on the page (a point is `x,y` in canvas pixels or a layer name, the middle of its box), run after everything else, and the report says per step what was under the pointer, which variables changed (`score 0→1`), whether the page warned, and keeps one picture each in `steps/` (look at them). A step on a layer that is not there, or a point outside the picture, is a problem. To do the same by hand (a browser tool, Chrome's protocol; serve the folder over http: a model, an image or a module beside the page does not load from file://): `const r = canvas.getBoundingClientRect(); canvas.dispatchEvent(new PointerEvent('pointerdown', { clientX: r.left + x * r.width / W, clientY: r.top + y * r.height / H, bubbles: true, pointerId: 1 }))` (then `pointermove`, `pointerup`, with a `settle` of 300 ms after a `setVars` rebuild), and read `movie.vars`, `movie.currentFrame`, `movie.isPlaying`, `movie.pick(x, y)` and the canvas's `style.cursor`. A canvas for touch has `style="touch-action: none"`.
|
|
38
38
|
- **Review:** `check --at 3.5,title@end,50% --pick 640,360` also says what is under that canvas point at each moment (the layers, top first; a three layer names the object) — a layout question you can answer without looking; `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
|
|
39
39
|
- **Formats:** make the formats the human asked for, one if they did not say. When a vertical cut is wanted it is its own composition: one source, a layout function, `?f=9x16` (recipe `two-formats`); `check` and `render` take `--query f=9x16`.
|
|
40
40
|
- Fit a picture into a rectangle with the `photo()` helper of that recipe (`scale: 'cover'` fits the PARENT only); designed pictures (posters, flyers, screenshots) are shown whole, never cropped.
|
|
@@ -1886,11 +1886,11 @@ canvas.addEventListener('click', async (event) => {
|
|
|
1886
1886
|
// after something outside the movie that a layer reads changes while the movie is paused: await movie.redraw();
|
|
1887
1887
|
```
|
|
1888
1888
|
|
|
1889
|
-
`pick` reads the frame as the last draw left it (it takes no time and has no clock). `movie.pick(x, y, { alpha: 0.1 })` looks at the picture and not its box (a transparent corner of a logo, the clear part of a drawn circle: not a hit). Dragging is built on `pick` too: recipes `drag-drop` (a flat layer) and `drag-3d` (an object of a three layer). **Test an interactive page**
|
|
1889
|
+
`pick` reads the frame as the last draw left it (it takes no time and has no clock). `movie.pick(x, y, { alpha: 0.1 })` looks at the picture and not its box (a transparent corner of a logo, the clear part of a drawn circle: not a hit). Dragging is built on `pick` too: recipes `drag-drop` (a flat layer) and `drag-3d` (an object of a three layer). **Test an interactive page** with `check --do "click fox; drag card > 770,240"` (real mouse events, what was under the pointer, the variables that changed, a picture per step: `SKILL.md`, "Interactive pages").
|
|
1890
1890
|
|
|
1891
1891
|
## Drag a layer and drop it on a target (`pick` and variables)
|
|
1892
1892
|
|
|
1893
|
-
A layer whose place is two variables moves when the page sets them: `movie.setVars({ cx, cy })` builds the composition again at the same frame (tens of milliseconds for a light composition; calls that fall behind are joined, so it is safe from `pointermove`). A glow whose `alpha` is a variable is a light that is on or off (`alpha: 'doneLit'`: any number a layer takes can be a variable name; write 0 and 1, not booleans). `pick` says what is taken (`only`) and what lies under it when it is let go (`ignore` the dragged layer). Listen on the window while it is held, so the pointer may leave the canvas. A heavy composition (a
|
|
1893
|
+
A layer whose place is two variables moves when the page sets them: `movie.setVars({ cx, cy })` builds the composition again at the same frame (tens of milliseconds for a light composition; calls that fall behind are joined, so it is safe from `pointermove`). A glow whose `alpha` is a variable is a light that is on or off (`alpha: 'doneLit'`: any number a layer takes can be a variable name; write 0 and 1, not booleans). `pick` says what is taken (`only`) and what lies under it when it is let go (`ignore` the dragged layer). Listen on the window while it is held, so the pointer may leave the canvas. A heavy composition (a long sound, many layers) rebuilds slowly: keep what moves a light layer. A `three` layer with a `name` keeps its scene and model across `setVars` (its `setup` runs once), so its place can be a variable read in `update`; for a paused three scene `await movie.redraw()` is still the lightest (recipe `drag-3d`).
|
|
1894
1894
|
|
|
1895
1895
|
A card with a label is two layers: name the card's group (a `composition` layer, whose children are one target) or pass both names (`only: ['card', 'card-label']`). A zone with a label is two layers as well: ask with `only: ['done', 'trash']` and the labels are not in the way. Which zone is the card over: the zone under the card's middle (`pick(cx, cy)`), not under the pointer.
|
|
1896
1896
|
|
|
@@ -3052,6 +3052,7 @@ three({
|
|
|
3052
3052
|
| `setup` | `(ctx: ThreeContext) => Promise<ThreeSetupResult \| void> \| ThreeSetupResult \| void` | builds the scene once. Add objects to `ctx.scene`, position `ctx.camera` (or replace it via `{ camera }`). Async, so `Movie.init` can await GLTF / texture loading. |
|
|
3053
3053
|
| `followCamera?` | `boolean` | the layer's camera is the composition's `camera` layer (see [below](#living-in-the-compositions-space-followcamera-followlights)). |
|
|
3054
3054
|
| `followLights?` | `boolean` | the composition's `light` layers become three lights in the scene (see below). |
|
|
3055
|
+
| `reuse?` | `boolean` | a rebuild (`setVars`, `resize`, `rebuild`) keeps a layer that did not change (same `name`, `setup`, size, options): its `setup` runs once. Default `true`; `false` runs `setup` at every rebuild (when it reads a value that variables change). |
|
|
3055
3056
|
| `update?` | `(t: number, ctx: ThreeContext) => void` | optional per-frame hook; `t` is sequence-local time in seconds. |
|
|
3056
3057
|
| `dispose?` | `(ctx: ThreeContext) => void` | cleanup for user-created GPU resources (geometries, materials, textures). Called from `destroy()`. |
|
|
3057
3058
|
|
|
@@ -4202,7 +4203,7 @@ interface RebuildReport { reason: 'vars' | 'resize' | 'rebuild'; ms: number; aud
|
|
|
4202
4203
|
- The new composition is built while the old one goes on; at the swap the movie keeps doing what it is doing at that moment: the same frame, playing or paused (a `pause()`, a seek or a `play()` you made during the build is kept), the poster if it was shown. A playing movie whose sound is unchanged (`audio: 'reused'`) is not stopped at all: the frame clock and the sound go on and only the picture is swapped, so rebuilds in a row (a pointer) do not hold the playhead back. When the sound changed, the movie stops and plays on from the same frame with the new sound. A `playUntil()` in flight ends. The canvas changes size at the swap, not before. A `render()` or `peek()` in flight is not interrupted: the swap waits for it.
|
|
4203
4204
|
- The sound is mixed only when it changed: `audio: 'reused'` means the same mix as before (the mix is the slow part, 0.6 to 0.8 s for a film; the rest takes about 20 ms). A time remap (`warp` / `sourceMap`) turns the cache off.
|
|
4204
4205
|
- Calls that arrive during a rebuild are joined: at most one rebuild runs and one waits, with the latest values. Safe to call from `pointermove` or `scroll`: a rebuild that leaves the sound alone takes tens of milliseconds (11 to 42 ms on four gallery pieces), one that mixes the sound again 0.6 to 0.8 s, so a slider that changes the sound will lag behind the hand.
|
|
4205
|
-
- A rebuild builds every layer again, a `three` layer
|
|
4206
|
+
- A rebuild builds every layer again, **except a `three` layer that did not change**: one with a `name`, the same `setup` function, the same size and options keeps its scene, its renderer (and its graphics context) and its texture, so `setup` does not run again and a model is not loaded again (measured on a box scene: 15 ms for a rebuild of a WebGL layer built again, 1 ms kept; WebGPU 7 ms against 1 ms). `update` is the new composition's own and runs on the kept scene. A layer with no `name`, another size or another `setup`, or `reuse: false` is built again (the old one is disposed once, when the swap is done; a rebuild that fails leaves the old one untouched). Put what must follow a variable in `update` or in keyframes, not in `setup`; a `setup` that reads `movie.vars` needs `reuse: false`. A model still loads again when the composition changes (`rebuild({ composition })` with a new `setup` function).
|
|
4206
4207
|
- A rebuild that fails (a bad expression, a missing asset, a size that is not pixels) rejects, emits `error` with `where: 'rebuild'`, and the movie goes on with what it had. A `destroy()` during a rebuild ends it the same way.
|
|
4207
4208
|
- To follow a window: observe a CSS-sized box around the canvas, not the canvas itself (the movie sets the canvas's pixel size): `new ResizeObserver(() => movie.resize(Math.round(box.clientWidth * devicePixelRatio), Math.round(box.clientHeight * devicePixelRatio))).observe(box)` (the `liquid-layout` recipe).
|
|
4208
4209
|
|
|
@@ -4288,9 +4289,11 @@ interface PickHit {
|
|
|
4288
4289
|
// options: { only?: string[], ignore?: string[], alpha?: number } layer names or paths; alpha: see below
|
|
4289
4290
|
```
|
|
4290
4291
|
|
|
4292
|
+
The hit is the layer that was drawn at the point, not the group it is in: a card made of a `composition` with a face and a label gives the face (`name: 'face0'`, `path: 'card0/face0'`), and a layer with no name of its own gives no `name` at all. To know which group was hit, read the first segment of the path (`hit.path.split('/')[0]`); `only: ['card0']` asks only about the group (a group's name stands for everything in it).
|
|
4293
|
+
|
|
4291
4294
|
A `three` layer covers its whole picture, but only what its ray meets is a hit: elsewhere the layers below are hit (a title, the background). `only` / `ignore` entries are layer names or paths, and a group's name (a nested composition) stands for everything in it: a card and its label are one target as `only: ['card']`.
|
|
4292
4295
|
|
|
4293
|
-
How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box; a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. **`{ alpha }` looks at the picture, not the box**: `movie.pick(x, y, { alpha: 0.1 })` leaves out a pixel of an image, a video or a `
|
|
4296
|
+
How a layer is asked: a flat layer by its own shape (a rotated one by its rotated rectangle, a shape by its outline: a circle is hit inside the circle, not at the corners of its box), text, images and video by their box (or by their picture with `alpha`); a `threeD` layer by its projected quad (the card seen from behind is hit too; a `threeD` composition is one card: what is inside it is not asked); a `three` layer by a ray through its camera (with `followCamera` the composition's camera), skipping invisible objects: `hit.three.object` is the name of the object it met (its own, or its nearest ancestor's that has one) and `object3d` the live three object. A layer not alive at the frame, at alpha 0, hidden by a parent, or outside its mask is not hit; a group (a nested composition without `threeD`) is not a target, the layers in it are. **`{ alpha }` looks at the picture, not the box**: `movie.pick(x, y, { alpha: 0.1 })` leaves out a pixel of an image, a video, a `canvas` layer or the letters of a `text` layer (the gap between letters, the hole of an O: a text layer is its glyphs, drawn again once per text and style with PixiJS's own generator; measured 2026-10-17: it agrees with the picture on over 95 % of the points of three texts, the rest are antialiased edges) whose alpha is at or below 0.1 (a transparent corner of a logo, the clear part of a circle drawn on a canvas); without it the box is the picture and nothing is read. Shapes are always hit by their outline, text and `shader` layers by their box (a shader's WebGL picture cannot be read back safely). A picture that cannot be read (an image from another origin: load it with `crossorigin="anonymous"` or from the same site) stays a hit, with one warning. What is not here: touch with several fingers.
|
|
4294
4297
|
|
|
4295
4298
|
**Dragging an object of a `three` layer**: `hit.three.grab(plane)` fixes a plane through the point that was taken (`'screen'` facing the camera, the default; `'floor'` horizontal; `'wall'` with z constant; or a normal `[x, y, z]`), and `grab.move(x, y)` takes the pointer in canvas pixels and gives where its ray meets that plane (`point`) and how far that is from the point taken (`delta`; `null` where the ray never meets the plane: a floor seen edge-on). Move the object by `delta`, from where it was when it was taken, and it follows the pointer exactly. The ray is the layer's own camera's (with `followCamera`, the composition's). The layer's `update` should read where the object is from the page's own state, and the page calls `await movie.redraw()` to draw the frame again while the movie is paused (recipe `drag-3d`).
|
|
4296
4299
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ name: pixi-effects
|
|
|
3
3
|
description: Use when asked to make, animate, preview or export a video, motion graphics, an animated title, a lower third, kinetic type, a promo, a slideshow with transitions, an animated chart or data story, a social clip, a 2.5D / depth scene, or music and sound for a video, written as code in JavaScript or HTML. pixi-effects is a JS library where a video is a plain-object composition (text, shape, image, video, audio and file-free sfx / music, camera, light and shader layers with keyframes) that plays in the browser, is checked by a tool the agent can run, and exports MP4 / WebM / MOV with no server. Not for a project that already uses another video tool (Remotion, Motion Canvas, ffmpeg); follow that tool instead.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
> Written for pixi-effects 0.
|
|
6
|
+
> Written for pixi-effects 0.44.0. Update this skill with `npx skills update`; the newest docs are at https://yjmtmtk.github.io/pixi-effects/
|
|
7
7
|
|
|
8
8
|
# pixi-effects — write a video as data
|
|
9
9
|
|
|
@@ -31,7 +31,7 @@ You describe a video as a tree of plain objects; the library plays it in a canva
|
|
|
31
31
|
**Read `reference/direction.md` before writing a composition for a product film, a company introduction, a launch or a data story.** It is renderer-neutral: write `brief.md` (the one sentence to remember, the REAL assets with paths, what must never be invented; if a needed asset is missing, stop and ask), `style-guide.md` (palette and type taken from the real source, a motion rule per class of object) and `shotlist.md` (a row per beat with entry and exit state) next to the page; then build, then review the rendered frames cold. What is specific to this library:
|
|
32
32
|
|
|
33
33
|
- **Time and sound:** pick a tempo whose bar is a round number of seconds (96 bpm: 2.5 s; 120 bpm: 2 s), put every cut on a bar line and every sfx on its beat. `npx pixi-effects check` prints a `music` read-back (bars per track, what starts on which beat, the drum span): verify the sound with it.
|
|
34
|
-
- **Interactive pages (a person clicks, hovers, drags):** `movie.pick(x, y)` says what is under a point, `movie.hover({ onEnter, onLeave })` and the recipes `pick-click`, `drag-drop`, `drag-3d` build on it; `check
|
|
34
|
+
- **Interactive pages (a person clicks, hovers, drags):** `movie.pick(x, y)` says what is under a point, `movie.hover({ onEnter, onLeave })` and the recipes `pick-click`, `drag-drop`, `drag-3d` build on it; **test the page with `check --do "hover Lime; click Lime; drag card > 770,240; wait 1"`**: real mouse and key events on the page (a point is `x,y` in canvas pixels or a layer name, the middle of its box), run after everything else, and the report says per step what was under the pointer, which variables changed (`score 0→1`), whether the page warned, and keeps one picture each in `steps/` (look at them). A step on a layer that is not there, or a point outside the picture, is a problem. To do the same by hand (a browser tool, Chrome's protocol; serve the folder over http: a model, an image or a module beside the page does not load from file://): `const r = canvas.getBoundingClientRect(); canvas.dispatchEvent(new PointerEvent('pointerdown', { clientX: r.left + x * r.width / W, clientY: r.top + y * r.height / H, bubbles: true, pointerId: 1 }))` (then `pointermove`, `pointerup`, with a `settle` of 300 ms after a `setVars` rebuild), and read `movie.vars`, `movie.currentFrame`, `movie.isPlaying`, `movie.pick(x, y)` and the canvas's `style.cursor`. A canvas for touch has `style="touch-action: none"`.
|
|
35
35
|
- **Review:** `check --at 3.5,title@end,50% --pick 640,360` also says what is under that canvas point at each moment (the layers, top first; a three layer names the object) — a layout question you can answer without looking; `check --at 3.5,title@end,50%` writes the contact sheet and single frames; look at mid-transition frames of the exported file too. Frames are seekable and deterministic here: render the same range twice and compare the frames if you doubt it.
|
|
36
36
|
- **Formats:** make the formats the human asked for, one if they did not say. When a vertical cut is wanted it is its own composition: one source, a layout function, `?f=9x16` (recipe `two-formats`); `check` and `render` take `--query f=9x16`.
|
|
37
37
|
- Fit a picture into a rectangle with the `photo()` helper of that recipe (`scale: 'cover'` fits the PARENT only); designed pictures (posters, flyers, screenshots) are shown whole, never cropped.
|
|
@@ -1416,11 +1416,11 @@ canvas.addEventListener('click', async (event) => {
|
|
|
1416
1416
|
// after something outside the movie that a layer reads changes while the movie is paused: await movie.redraw();
|
|
1417
1417
|
```
|
|
1418
1418
|
|
|
1419
|
-
`pick` reads the frame as the last draw left it (it takes no time and has no clock). `movie.pick(x, y, { alpha: 0.1 })` looks at the picture and not its box (a transparent corner of a logo, the clear part of a drawn circle: not a hit). Dragging is built on `pick` too: recipes `drag-drop` (a flat layer) and `drag-3d` (an object of a three layer). **Test an interactive page**
|
|
1419
|
+
`pick` reads the frame as the last draw left it (it takes no time and has no clock). `movie.pick(x, y, { alpha: 0.1 })` looks at the picture and not its box (a transparent corner of a logo, the clear part of a drawn circle: not a hit). Dragging is built on `pick` too: recipes `drag-drop` (a flat layer) and `drag-3d` (an object of a three layer). **Test an interactive page** with `check --do "click fox; drag card > 770,240"` (real mouse events, what was under the pointer, the variables that changed, a picture per step: `SKILL.md`, "Interactive pages").
|
|
1420
1420
|
|
|
1421
1421
|
## Drag a layer and drop it on a target (`pick` and variables)
|
|
1422
1422
|
|
|
1423
|
-
A layer whose place is two variables moves when the page sets them: `movie.setVars({ cx, cy })` builds the composition again at the same frame (tens of milliseconds for a light composition; calls that fall behind are joined, so it is safe from `pointermove`). A glow whose `alpha` is a variable is a light that is on or off (`alpha: 'doneLit'`: any number a layer takes can be a variable name; write 0 and 1, not booleans). `pick` says what is taken (`only`) and what lies under it when it is let go (`ignore` the dragged layer). Listen on the window while it is held, so the pointer may leave the canvas. A heavy composition (a
|
|
1423
|
+
A layer whose place is two variables moves when the page sets them: `movie.setVars({ cx, cy })` builds the composition again at the same frame (tens of milliseconds for a light composition; calls that fall behind are joined, so it is safe from `pointermove`). A glow whose `alpha` is a variable is a light that is on or off (`alpha: 'doneLit'`: any number a layer takes can be a variable name; write 0 and 1, not booleans). `pick` says what is taken (`only`) and what lies under it when it is let go (`ignore` the dragged layer). Listen on the window while it is held, so the pointer may leave the canvas. A heavy composition (a long sound, many layers) rebuilds slowly: keep what moves a light layer. A `three` layer with a `name` keeps its scene and model across `setVars` (its `setup` runs once), so its place can be a variable read in `update`; for a paused three scene `await movie.redraw()` is still the lightest (recipe `drag-3d`).
|
|
1424
1424
|
|
|
1425
1425
|
A card with a label is two layers: name the card's group (a `composition` layer, whose children are one target) or pass both names (`only: ['card', 'card-label']`). A zone with a label is two layers as well: ask with `only: ['done', 'trash']` and the labels are not in the way. Which zone is the card over: the zone under the card's middle (`pick(cx, cy)`), not under the pointer.
|
|
1426
1426
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>pixi-effects video</title>
|
|
7
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
7
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/loader.css" /> <!-- the loader: HTML + CSS only, so it is on screen at once and keeps moving while the page builds the video -->
|
|
8
8
|
<style>
|
|
9
9
|
body { background: #0d1220; margin: 0; padding: 16px; }
|
|
10
10
|
.stage { position: relative; width: min(960px, 100%); } /* the player and the loader both sit inside this box */
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
"imports": {
|
|
38
38
|
"pixi.js": "https://esm.sh/pixi.js@8.22.0?bundle-deps",
|
|
39
39
|
"mediabunny": "https://esm.sh/mediabunny",
|
|
40
|
-
"pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
41
|
-
"pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
42
|
-
"pixi-effects/present": "https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
43
|
-
"pixi-effects/three": "https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
40
|
+
"pixi-effects": "https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/index.js",
|
|
41
|
+
"pixi-effects/controller": "https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/Controller.js",
|
|
42
|
+
"pixi-effects/present": "https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/present.js",
|
|
43
|
+
"pixi-effects/three": "https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/three.js",
|
|
44
44
|
"pixi-filters": "https://esm.sh/pixi-filters@6.1.5?external=pixi.js",
|
|
45
45
|
"three": "https://esm.sh/three@0.178.0",
|
|
46
46
|
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.178.0/examples/jsm/"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
</script>
|
|
50
|
-
<link rel="modulepreload" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.
|
|
50
|
+
<link rel="modulepreload" href="https://cdn.jsdelivr.net/npm/pixi-effects@0.44.0/dist/index.js" /> <!-- after the import map: the library downloads while the page is parsed -->
|
|
51
51
|
|
|
52
52
|
<script type="module">
|
|
53
53
|
import { Movie, kenBurns, withFade } from 'pixi-effects';
|
package/dist/Base-DKFQtqzW.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Container } from 'pixi.js';
|
|
2
|
-
import { S as SequenceSpec, C as CompositionShape } from './types-DiNHtdrS.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Resolves a routed keyframe path to a concrete tween target.
|
|
6
|
-
* `path` is everything after the registered prefix + dot (for
|
|
7
|
-
* `three.cube.rotation.y` under prefix `three`, path = `cube.rotation.y`).
|
|
8
|
-
* Return null to skip the key (the router is expected to have warned).
|
|
9
|
-
*/
|
|
10
|
-
type PathRouter = (path: string) => {
|
|
11
|
-
target: object;
|
|
12
|
-
prop: string;
|
|
13
|
-
} | null;
|
|
14
|
-
type PathRouters = Record<string, PathRouter>;
|
|
15
|
-
|
|
16
|
-
/** Variables available to expression evaluation. */
|
|
17
|
-
interface Scope {
|
|
18
|
-
w: number;
|
|
19
|
-
h: number;
|
|
20
|
-
W: number;
|
|
21
|
-
H: number;
|
|
22
|
-
GW: number;
|
|
23
|
-
GH: number;
|
|
24
|
-
contain: number;
|
|
25
|
-
cover: number;
|
|
26
|
-
t: number;
|
|
27
|
-
d: number;
|
|
28
|
-
T: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare abstract class Sequence {
|
|
32
|
-
spec: SequenceSpec;
|
|
33
|
-
parent: CompositionShape | null;
|
|
34
|
-
root: CompositionShape;
|
|
35
|
-
target: Container | null;
|
|
36
|
-
intrinsicWidth: number;
|
|
37
|
-
intrinsicHeight: number;
|
|
38
|
-
at: number;
|
|
39
|
-
duration: number | undefined;
|
|
40
|
-
constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape);
|
|
41
|
-
abstract build(): Promise<void>;
|
|
42
|
-
buildFilters(): void;
|
|
43
|
-
scope(): Scope;
|
|
44
|
-
/**
|
|
45
|
-
* Prefix routers contributed to the keyframe pipeline (e.g. `three.` in
|
|
46
|
-
* pixi-effects/three). Base sequences route nothing extra.
|
|
47
|
-
*/
|
|
48
|
-
protected pathRouters(): PathRouters;
|
|
49
|
-
/**
|
|
50
|
-
* The `initial` and `keyframes` that go onto the display object. A layer whose `time` runs a clock (video, composition) takes `time`
|
|
51
|
-
* out of them: it is not a property of the display object.
|
|
52
|
-
*/
|
|
53
|
-
protected displayProps(): {
|
|
54
|
-
initial: SequenceSpec['initial'];
|
|
55
|
-
keyframes: SequenceSpec['keyframes'];
|
|
56
|
-
};
|
|
57
|
-
destroy(): void;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export { type PathRouters as P, Sequence as S };
|
package/dist/Base-lb5Uhaqu.d.cts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Container } from 'pixi.js';
|
|
2
|
-
import { S as SequenceSpec, C as CompositionShape } from './types-DiNHtdrS.cjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Resolves a routed keyframe path to a concrete tween target.
|
|
6
|
-
* `path` is everything after the registered prefix + dot (for
|
|
7
|
-
* `three.cube.rotation.y` under prefix `three`, path = `cube.rotation.y`).
|
|
8
|
-
* Return null to skip the key (the router is expected to have warned).
|
|
9
|
-
*/
|
|
10
|
-
type PathRouter = (path: string) => {
|
|
11
|
-
target: object;
|
|
12
|
-
prop: string;
|
|
13
|
-
} | null;
|
|
14
|
-
type PathRouters = Record<string, PathRouter>;
|
|
15
|
-
|
|
16
|
-
/** Variables available to expression evaluation. */
|
|
17
|
-
interface Scope {
|
|
18
|
-
w: number;
|
|
19
|
-
h: number;
|
|
20
|
-
W: number;
|
|
21
|
-
H: number;
|
|
22
|
-
GW: number;
|
|
23
|
-
GH: number;
|
|
24
|
-
contain: number;
|
|
25
|
-
cover: number;
|
|
26
|
-
t: number;
|
|
27
|
-
d: number;
|
|
28
|
-
T: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare abstract class Sequence {
|
|
32
|
-
spec: SequenceSpec;
|
|
33
|
-
parent: CompositionShape | null;
|
|
34
|
-
root: CompositionShape;
|
|
35
|
-
target: Container | null;
|
|
36
|
-
intrinsicWidth: number;
|
|
37
|
-
intrinsicHeight: number;
|
|
38
|
-
at: number;
|
|
39
|
-
duration: number | undefined;
|
|
40
|
-
constructor(spec: SequenceSpec, parent: CompositionShape | null, root: CompositionShape);
|
|
41
|
-
abstract build(): Promise<void>;
|
|
42
|
-
buildFilters(): void;
|
|
43
|
-
scope(): Scope;
|
|
44
|
-
/**
|
|
45
|
-
* Prefix routers contributed to the keyframe pipeline (e.g. `three.` in
|
|
46
|
-
* pixi-effects/three). Base sequences route nothing extra.
|
|
47
|
-
*/
|
|
48
|
-
protected pathRouters(): PathRouters;
|
|
49
|
-
/**
|
|
50
|
-
* The `initial` and `keyframes` that go onto the display object. A layer whose `time` runs a clock (video, composition) takes `time`
|
|
51
|
-
* out of them: it is not a property of the display object.
|
|
52
|
-
*/
|
|
53
|
-
protected displayProps(): {
|
|
54
|
-
initial: SequenceSpec['initial'];
|
|
55
|
-
keyframes: SequenceSpec['keyframes'];
|
|
56
|
-
};
|
|
57
|
-
destroy(): void;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export { type PathRouters as P, Sequence as S };
|