pixi-effects 0.1.0 → 0.2.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.
@@ -1,6 +1,3 @@
1
- import { Application } from 'pixi.js';
2
- import { gsap } from 'gsap';
3
-
4
1
  /**
5
2
  * pixi-effects public DSL types.
6
3
  *
@@ -164,6 +161,13 @@ interface SequenceCommon {
164
161
  * Routed through PIXI's native `setMask({ inverse: true })`.
165
162
  */
166
163
  maskInverted?: boolean;
164
+ /**
165
+ * Opt this layer into 2.5D: it can then use `z`, `rotationX`, `rotationY`
166
+ * (in `initial` / keyframes) and is projected through the composition's
167
+ * `camera` layer. Default false. With z = 0, no 3D rotation and the default
168
+ * camera, a threeD layer renders exactly like a 2D one.
169
+ */
170
+ threeD?: boolean;
167
171
  }
168
172
  interface VideoSequenceSpec extends SequenceCommon {
169
173
  type: 'video';
@@ -212,6 +216,15 @@ interface CompositionSequenceSpec extends SequenceCommon {
212
216
  sequences?: SequenceSpec[];
213
217
  transitions?: TransitionSpec[];
214
218
  }
219
+ /**
220
+ * A camera layer. Put its props in `initial` / `keyframes`:
221
+ * `x`, `y`, `z`, `lookAtX`, `lookAtY`, `lookAtZ`, `fov` (vertical degrees, default 40).
222
+ * Unset `z` follows `fov` so the z = 0 plane stays 1:1. Affects only `threeD`
223
+ * siblings in the same composition. +z points toward the viewer.
224
+ */
225
+ interface CameraSequenceSpec extends SequenceCommon {
226
+ type: 'camera';
227
+ }
215
228
  interface ShapeBase extends SequenceCommon {
216
229
  type: 'shape';
217
230
  /**
@@ -277,7 +290,7 @@ interface PathShapeSpec extends ShapeBase {
277
290
  d: string;
278
291
  }
279
292
  type ShapeSequenceSpec = RectShapeSpec | CircleShapeSpec | EllipseShapeSpec | LineShapeSpec | PolygonShapeSpec | PathShapeSpec;
280
- type SequenceSpec = VideoSequenceSpec | ImageSequenceSpec | TextSequenceSpec | AudioSequenceSpec | CompositionSequenceSpec | ShapeSequenceSpec;
293
+ type SequenceSpec = VideoSequenceSpec | ImageSequenceSpec | TextSequenceSpec | AudioSequenceSpec | CompositionSequenceSpec | CameraSequenceSpec | ShapeSequenceSpec;
281
294
  /** Top-level composition (root node) — same as `CompositionSequenceSpec` minus the discriminant. */
282
295
  interface CompositionSpec extends SequenceCommon {
283
296
  width?: number;
@@ -285,80 +298,23 @@ interface CompositionSpec extends SequenceCommon {
285
298
  sequences?: SequenceSpec[];
286
299
  transitions?: TransitionSpec[];
287
300
  }
288
-
289
- interface MovieOptions {
290
- width?: number;
291
- height?: number;
292
- duration?: number;
293
- frameRate?: number;
294
- background?: string;
295
- canvas?: HTMLCanvasElement;
296
- assets?: AssetSpec[];
297
- composition?: CompositionSpec;
298
- }
299
- interface RenderOptions {
300
- format?: 'mp4' | 'mov' | 'webm' | 'mkv';
301
- video?: {
302
- codec?: string;
303
- bitrate?: 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
304
- };
305
- audio?: {
306
- codec?: string;
307
- bitrate?: 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
308
- };
309
- }
310
- interface FrameEvent {
311
- frame: number;
312
- totalFrames: number;
313
- }
314
- interface ProgressEvent {
315
- progress: number;
316
- frame: number;
317
- totalFrames: number;
318
- }
319
- type Listener = (...args: any[]) => void;
320
- declare class Movie {
321
- private _events;
322
- private _initState;
323
- app: Application | null;
324
- timeline: ReturnType<typeof gsap.timeline> | null;
325
- audioBuffer: AudioBuffer | null;
326
- audioSource: AudioBufferSourceNode | null;
327
- gainNode: GainNode | null;
328
- private _volume;
329
- private _muted;
330
- isPlaying: boolean;
331
- currentFrame: number;
332
- totalFrames: number;
301
+ /** Resolved parent / root composition shape used for scope and sizing. */
302
+ interface CompositionShape {
333
303
  width: number;
334
304
  height: number;
335
305
  duration: number;
336
- frameRate: number;
337
- background: string;
338
- private _audioContext;
339
- private _rootSequence;
340
- private _rootContainer;
341
- private _raf;
342
- on(event: 'ready', fn: () => void): this;
343
- on(event: 'frame', fn: (e: FrameEvent) => void): this;
344
- on(event: 'progress', fn: (e: ProgressEvent) => void): this;
345
- on(event: 'pause', fn: () => void): this;
346
- off(event: string, fn: Listener): this;
347
- emit(event: string, ...args: unknown[]): void;
348
- get isReady(): boolean;
349
- private _ensureAudioContext;
350
- init(options?: MovieOptions): Promise<void>;
351
- gotoFrame(frame: number, force?: boolean): Promise<void>;
352
- private _awaitVideoFrames;
353
- play(): void;
354
- pause(): void;
355
- set volume(v: number);
356
- get volume(): number;
357
- set muted(v: boolean);
358
- get muted(): boolean;
359
- toggleMute(): boolean;
360
- render(options?: RenderOptions): Promise<Blob>;
361
- destroy(): Promise<void>;
306
+ }
307
+ /** Audio descriptor pushed to the mixdown queue by AudioSequence/VideoSequence. */
308
+ interface AudioDescriptor {
309
+ buffer: AudioBuffer;
310
+ loop: boolean;
311
+ start: number;
312
+ end: number;
313
+ initialVolume: number;
314
+ volumeKeyframes: {
315
+ time: number;
316
+ value: number;
317
+ }[];
362
318
  }
363
319
 
364
- export { type AssetSpec as A, type ChromaKeyFilterSpec as C, type DipTransition as D, type EllipseShapeSpec as E, type FilterSpec as F, type ImageSequenceSpec as I, type Keyframe as K, type LineShapeSpec as L, Movie as M, type PathShapeSpec as P, type RectShapeSpec as R, type SequenceCommon as S, type TextSequenceSpec as T, type VideoSequenceSpec as V, type WipeTransition as W, type ZoomTransition as Z, type AudioSequenceSpec as a, type CircleShapeSpec as b, type CompositionSequenceSpec as c, type CompositionSpec as d, type CrossfadeTransition as e, type CustomFilterSpec as f, type DissolveTransition as g, type Expr as h, type FrameEvent as i, type IrisTransition as j, type MovieOptions as k, type PolygonShapeSpec as l, type ProgressEvent as m, type PropValue as n, type Props as o, type RenderOptions as p, type SequenceSpec as q, type ShapeSequenceSpec as r, type SlideTransition as s, type TransitionCommon as t, type TransitionSpec as u };
320
+ export type { AssetSpec as A, CompositionShape as C, DipTransition as D, EllipseShapeSpec as E, FilterSpec as F, ImageSequenceSpec as I, Keyframe as K, LineShapeSpec as L, PathShapeSpec as P, RectShapeSpec as R, SequenceSpec as S, TextSequenceSpec as T, VideoSequenceSpec as V, WipeTransition as W, ZoomTransition as Z, SequenceCommon as a, AudioSequenceSpec as b, CameraSequenceSpec as c, ChromaKeyFilterSpec as d, CircleShapeSpec as e, CompositionSequenceSpec as f, CompositionSpec as g, CrossfadeTransition as h, CustomFilterSpec as i, DissolveTransition as j, Expr as k, IrisTransition as l, PolygonShapeSpec as m, PropValue as n, Props as o, ShapeSequenceSpec as p, SlideTransition as q, TransitionCommon as r, TransitionSpec as s, AudioDescriptor as t };
@@ -1,6 +1,3 @@
1
- import { Application } from 'pixi.js';
2
- import { gsap } from 'gsap';
3
-
4
1
  /**
5
2
  * pixi-effects public DSL types.
6
3
  *
@@ -164,6 +161,13 @@ interface SequenceCommon {
164
161
  * Routed through PIXI's native `setMask({ inverse: true })`.
165
162
  */
166
163
  maskInverted?: boolean;
164
+ /**
165
+ * Opt this layer into 2.5D: it can then use `z`, `rotationX`, `rotationY`
166
+ * (in `initial` / keyframes) and is projected through the composition's
167
+ * `camera` layer. Default false. With z = 0, no 3D rotation and the default
168
+ * camera, a threeD layer renders exactly like a 2D one.
169
+ */
170
+ threeD?: boolean;
167
171
  }
168
172
  interface VideoSequenceSpec extends SequenceCommon {
169
173
  type: 'video';
@@ -212,6 +216,15 @@ interface CompositionSequenceSpec extends SequenceCommon {
212
216
  sequences?: SequenceSpec[];
213
217
  transitions?: TransitionSpec[];
214
218
  }
219
+ /**
220
+ * A camera layer. Put its props in `initial` / `keyframes`:
221
+ * `x`, `y`, `z`, `lookAtX`, `lookAtY`, `lookAtZ`, `fov` (vertical degrees, default 40).
222
+ * Unset `z` follows `fov` so the z = 0 plane stays 1:1. Affects only `threeD`
223
+ * siblings in the same composition. +z points toward the viewer.
224
+ */
225
+ interface CameraSequenceSpec extends SequenceCommon {
226
+ type: 'camera';
227
+ }
215
228
  interface ShapeBase extends SequenceCommon {
216
229
  type: 'shape';
217
230
  /**
@@ -277,7 +290,7 @@ interface PathShapeSpec extends ShapeBase {
277
290
  d: string;
278
291
  }
279
292
  type ShapeSequenceSpec = RectShapeSpec | CircleShapeSpec | EllipseShapeSpec | LineShapeSpec | PolygonShapeSpec | PathShapeSpec;
280
- type SequenceSpec = VideoSequenceSpec | ImageSequenceSpec | TextSequenceSpec | AudioSequenceSpec | CompositionSequenceSpec | ShapeSequenceSpec;
293
+ type SequenceSpec = VideoSequenceSpec | ImageSequenceSpec | TextSequenceSpec | AudioSequenceSpec | CompositionSequenceSpec | CameraSequenceSpec | ShapeSequenceSpec;
281
294
  /** Top-level composition (root node) — same as `CompositionSequenceSpec` minus the discriminant. */
282
295
  interface CompositionSpec extends SequenceCommon {
283
296
  width?: number;
@@ -285,80 +298,23 @@ interface CompositionSpec extends SequenceCommon {
285
298
  sequences?: SequenceSpec[];
286
299
  transitions?: TransitionSpec[];
287
300
  }
288
-
289
- interface MovieOptions {
290
- width?: number;
291
- height?: number;
292
- duration?: number;
293
- frameRate?: number;
294
- background?: string;
295
- canvas?: HTMLCanvasElement;
296
- assets?: AssetSpec[];
297
- composition?: CompositionSpec;
298
- }
299
- interface RenderOptions {
300
- format?: 'mp4' | 'mov' | 'webm' | 'mkv';
301
- video?: {
302
- codec?: string;
303
- bitrate?: 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
304
- };
305
- audio?: {
306
- codec?: string;
307
- bitrate?: 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
308
- };
309
- }
310
- interface FrameEvent {
311
- frame: number;
312
- totalFrames: number;
313
- }
314
- interface ProgressEvent {
315
- progress: number;
316
- frame: number;
317
- totalFrames: number;
318
- }
319
- type Listener = (...args: any[]) => void;
320
- declare class Movie {
321
- private _events;
322
- private _initState;
323
- app: Application | null;
324
- timeline: ReturnType<typeof gsap.timeline> | null;
325
- audioBuffer: AudioBuffer | null;
326
- audioSource: AudioBufferSourceNode | null;
327
- gainNode: GainNode | null;
328
- private _volume;
329
- private _muted;
330
- isPlaying: boolean;
331
- currentFrame: number;
332
- totalFrames: number;
301
+ /** Resolved parent / root composition shape used for scope and sizing. */
302
+ interface CompositionShape {
333
303
  width: number;
334
304
  height: number;
335
305
  duration: number;
336
- frameRate: number;
337
- background: string;
338
- private _audioContext;
339
- private _rootSequence;
340
- private _rootContainer;
341
- private _raf;
342
- on(event: 'ready', fn: () => void): this;
343
- on(event: 'frame', fn: (e: FrameEvent) => void): this;
344
- on(event: 'progress', fn: (e: ProgressEvent) => void): this;
345
- on(event: 'pause', fn: () => void): this;
346
- off(event: string, fn: Listener): this;
347
- emit(event: string, ...args: unknown[]): void;
348
- get isReady(): boolean;
349
- private _ensureAudioContext;
350
- init(options?: MovieOptions): Promise<void>;
351
- gotoFrame(frame: number, force?: boolean): Promise<void>;
352
- private _awaitVideoFrames;
353
- play(): void;
354
- pause(): void;
355
- set volume(v: number);
356
- get volume(): number;
357
- set muted(v: boolean);
358
- get muted(): boolean;
359
- toggleMute(): boolean;
360
- render(options?: RenderOptions): Promise<Blob>;
361
- destroy(): Promise<void>;
306
+ }
307
+ /** Audio descriptor pushed to the mixdown queue by AudioSequence/VideoSequence. */
308
+ interface AudioDescriptor {
309
+ buffer: AudioBuffer;
310
+ loop: boolean;
311
+ start: number;
312
+ end: number;
313
+ initialVolume: number;
314
+ volumeKeyframes: {
315
+ time: number;
316
+ value: number;
317
+ }[];
362
318
  }
363
319
 
364
- export { type AssetSpec as A, type ChromaKeyFilterSpec as C, type DipTransition as D, type EllipseShapeSpec as E, type FilterSpec as F, type ImageSequenceSpec as I, type Keyframe as K, type LineShapeSpec as L, Movie as M, type PathShapeSpec as P, type RectShapeSpec as R, type SequenceCommon as S, type TextSequenceSpec as T, type VideoSequenceSpec as V, type WipeTransition as W, type ZoomTransition as Z, type AudioSequenceSpec as a, type CircleShapeSpec as b, type CompositionSequenceSpec as c, type CompositionSpec as d, type CrossfadeTransition as e, type CustomFilterSpec as f, type DissolveTransition as g, type Expr as h, type FrameEvent as i, type IrisTransition as j, type MovieOptions as k, type PolygonShapeSpec as l, type ProgressEvent as m, type PropValue as n, type Props as o, type RenderOptions as p, type SequenceSpec as q, type ShapeSequenceSpec as r, type SlideTransition as s, type TransitionCommon as t, type TransitionSpec as u };
320
+ export type { AssetSpec as A, CompositionShape as C, DipTransition as D, EllipseShapeSpec as E, FilterSpec as F, ImageSequenceSpec as I, Keyframe as K, LineShapeSpec as L, PathShapeSpec as P, RectShapeSpec as R, SequenceSpec as S, TextSequenceSpec as T, VideoSequenceSpec as V, WipeTransition as W, ZoomTransition as Z, SequenceCommon as a, AudioSequenceSpec as b, CameraSequenceSpec as c, ChromaKeyFilterSpec as d, CircleShapeSpec as e, CompositionSequenceSpec as f, CompositionSpec as g, CrossfadeTransition as h, CustomFilterSpec as i, DissolveTransition as j, Expr as k, IrisTransition as l, PolygonShapeSpec as m, PropValue as n, Props as o, ShapeSequenceSpec as p, SlideTransition as q, TransitionCommon as r, TransitionSpec as s, AudioDescriptor as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-effects",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Declarative composition and video rendering for the web. Built on PixiJS v8.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -11,6 +11,10 @@
11
11
  "./controller": {
12
12
  "import": { "types": "./dist/Controller.d.ts", "default": "./dist/Controller.js" },
13
13
  "require": { "types": "./dist/Controller.d.cts", "default": "./dist/Controller.cjs" }
14
+ },
15
+ "./three": {
16
+ "import": { "types": "./dist/three.d.ts", "default": "./dist/three.js" },
17
+ "require": { "types": "./dist/three.d.cts", "default": "./dist/three.cjs" }
14
18
  }
15
19
  },
16
20
  "main": "./dist/index.cjs",
@@ -19,7 +23,8 @@
19
23
  "files": ["dist", "README.md", "LICENSE"],
20
24
  "keywords": [
21
25
  "pixi", "pixijs", "video", "composition", "compositing", "rendering",
22
- "after-effects", "motion-graphics", "timeline", "webgl", "gsap", "keyframe", "typescript"
26
+ "after-effects", "motion-graphics", "timeline", "webgl", "gsap", "keyframe", "typescript",
27
+ "three", "threejs"
23
28
  ],
24
29
  "license": "MIT",
25
30
  "author": "tefista <tefista.dev@gmail.com>",
@@ -36,11 +41,15 @@
36
41
  "prepublishOnly": "npm run typecheck && npm test && npm run build"
37
42
  },
38
43
  "dependencies": {
39
- "mediabunny": "^1.43.0"
44
+ "mediabunny": "^1.61.3"
40
45
  },
41
46
  "peerDependencies": {
42
47
  "gsap": "^3.12.0",
43
- "pixi.js": "^8.0.0"
48
+ "pixi.js": "^8.0.0",
49
+ "three": ">=0.150.0"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "three": { "optional": true }
44
53
  },
45
54
  "devDependencies": {
46
55
  "tsup": "^8.0.0",
@@ -48,7 +57,9 @@
48
57
  "vitest": "^2.1.0",
49
58
  "happy-dom": "^15.0.0",
50
59
  "gsap": "^3.12.0",
51
- "pixi.js": "^8.16.0"
60
+ "pixi.js": "^8.22.0",
61
+ "three": "^0.185.1",
62
+ "@types/three": "^0.185.0"
52
63
  },
53
64
  "engines": { "node": ">=18" }
54
65
  }