@agrhub/engine-pixi 0.0.0-stage → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/LICENSE +47 -0
  2. package/NOTICE.md +19 -0
  3. package/README.md +6 -2
  4. package/dist/animation/block-reveal-animation.d.ts +33 -0
  5. package/dist/animation/easings.d.ts +4 -0
  6. package/dist/animation/gsap-animation.d.ts +32 -0
  7. package/dist/animation/index.d.ts +9 -0
  8. package/dist/animation/keyframe-animation.d.ts +11 -0
  9. package/dist/animation/mask-animation.d.ts +145 -0
  10. package/dist/animation/pixi-animation-utils.d.ts +10 -0
  11. package/dist/animation/registry.d.ts +11 -0
  12. package/dist/animation/types.d.ts +205 -0
  13. package/dist/animation/wipe-animation.d.ts +53 -0
  14. package/dist/clips/audio-clip.d.ts +122 -0
  15. package/dist/clips/backdrop-clip.d.ts +56 -0
  16. package/dist/clips/base-clip.d.ts +150 -0
  17. package/dist/clips/base-text-clip.d.ts +228 -0
  18. package/dist/clips/caption-clip.d.ts +129 -0
  19. package/dist/clips/clip-registry.d.ts +56 -0
  20. package/dist/clips/effect-clip.d.ts +37 -0
  21. package/dist/clips/iclip.d.ts +231 -0
  22. package/dist/clips/image-clip.d.ts +116 -0
  23. package/dist/clips/index.d.ts +20 -0
  24. package/dist/clips/placeholder-clip.d.ts +22 -0
  25. package/dist/clips/shape-clip.d.ts +59 -0
  26. package/dist/clips/text-clip.d.ts +148 -0
  27. package/dist/clips/transition-clip.d.ts +41 -0
  28. package/dist/clips/video-clip.d.ts +215 -0
  29. package/dist/compositor/audio-mixer.d.ts +8 -0
  30. package/dist/compositor/av-encoder.d.ts +17 -0
  31. package/dist/compositor/clip-style-renderer.d.ts +23 -0
  32. package/dist/compositor/compositor-renderer.d.ts +29 -0
  33. package/dist/compositor/effect-manager.d.ts +28 -0
  34. package/dist/compositor/scheduler.d.ts +8 -0
  35. package/dist/compositor/transition-manager.d.ts +45 -0
  36. package/dist/compositor.d.ts +157 -0
  37. package/dist/effect/constant/index.d.ts +566 -0
  38. package/dist/effect/effect.d.ts +9 -0
  39. package/dist/effect/glsl/custom-glsl.d.ts +1043 -0
  40. package/dist/effect/glsl/gl-effect.d.ts +38 -0
  41. package/dist/effect/interface/index.d.ts +25 -0
  42. package/dist/effect/types.d.ts +26 -0
  43. package/dist/effect/vertex.d.ts +1 -0
  44. package/dist/event-emitter.d.ts +55 -0
  45. package/dist/filters/outline-filter.d.ts +28 -0
  46. package/dist/index.d.ts +27 -0
  47. package/dist/index.es.js +16038 -0
  48. package/dist/index.es.js.map +1 -0
  49. package/dist/index.umd.cjs +3335 -0
  50. package/dist/index.umd.cjs.map +1 -0
  51. package/dist/json-serialization.d.ts +310 -0
  52. package/dist/mp4-utils/index.d.ts +31 -0
  53. package/dist/mp4-utils/mp4box-utils.d.ts +44 -0
  54. package/dist/mp4-utils/sample-transform.d.ts +26 -0
  55. package/dist/sprite/base-sprite.d.ts +255 -0
  56. package/dist/sprite/pixi-sprite-renderer.d.ts +68 -0
  57. package/dist/standalone/index.es.js +94023 -0
  58. package/dist/standalone/index.es.js.map +1 -0
  59. package/dist/studio/history-manager.d.ts +46 -0
  60. package/dist/studio/resource-manager.d.ts +53 -0
  61. package/dist/studio/selection-manager.d.ts +66 -0
  62. package/dist/studio/timeline-model.d.ts +117 -0
  63. package/dist/studio/transport.d.ts +44 -0
  64. package/dist/studio-bridge.d.ts +50 -0
  65. package/dist/studio.d.ts +527 -0
  66. package/dist/transformer/handle.d.ts +17 -0
  67. package/dist/transformer/snapping.d.ts +45 -0
  68. package/dist/transformer/transformer.d.ts +38 -0
  69. package/dist/transformer/wireframe.d.ts +5 -0
  70. package/dist/transition/fragment.d.ts +1 -0
  71. package/dist/transition/glsl/custom-glsl.d.ts +231 -0
  72. package/dist/transition/glsl/gl-transition.d.ts +42 -0
  73. package/dist/transition/transition.d.ts +6 -0
  74. package/dist/transition/types.d.ts +29 -0
  75. package/dist/transition/uniforms.d.ts +35 -0
  76. package/dist/transition/vertex.d.ts +1 -0
  77. package/dist/utils/asset-manager.d.ts +15 -0
  78. package/dist/utils/audio-codec-detector.d.ts +39 -0
  79. package/dist/utils/audio.d.ts +81 -0
  80. package/dist/utils/chromakey.d.ts +24 -0
  81. package/dist/utils/color-adjustment.d.ts +53 -0
  82. package/dist/utils/color.d.ts +17 -0
  83. package/dist/utils/common.d.ts +7 -0
  84. package/dist/utils/dom.d.ts +48 -0
  85. package/dist/utils/effect.d.ts +1 -0
  86. package/dist/utils/fonts.d.ts +21 -0
  87. package/dist/utils/index.d.ts +6 -0
  88. package/dist/utils/log.d.ts +27 -0
  89. package/dist/utils/media-cache.d.ts +45 -0
  90. package/dist/utils/stream-utils.d.ts +4 -0
  91. package/dist/utils/video.d.ts +16 -0
  92. package/dist/utils/worker-timer.d.ts +1 -0
  93. package/package.json +63 -3
@@ -0,0 +1,527 @@
1
+ import { Application, Sprite, Texture, Container, Graphics, RenderTexture } from 'pixi.js';
2
+ import { IClip } from './clips/iclip';
3
+ import { PixiSpriteRenderer } from './sprite/pixi-sprite-renderer';
4
+ import { ProjectJSON } from './json-serialization';
5
+ import { Transformer } from './transformer/transformer';
6
+ import { EffectKey } from './effect/glsl/gl-effect';
7
+ import { default as EventEmitter } from './event-emitter';
8
+ import { Core } from '@agrhub/core';
9
+ import { SelectionManager } from './studio/selection-manager';
10
+ import { Transport } from './studio/transport';
11
+ import { TimelineModel } from './studio/timeline-model';
12
+ import { HistoryManager } from './studio/history-manager';
13
+ import { ResourceManager } from './studio/resource-manager';
14
+ export interface IStudioOpts {
15
+ width: number;
16
+ height: number;
17
+ fps?: number;
18
+ backgroundColor?: string;
19
+ artboardColor?: string;
20
+ canvas?: HTMLCanvasElement;
21
+ interactivity?: boolean;
22
+ spacing?: number;
23
+ core?: Core;
24
+ allowZoom?: boolean;
25
+ allowPan?: boolean;
26
+ /**
27
+ * Internal rendering resolution multiplier for preview (0-1).
28
+ * e.g., 0.5 renders at half-resolution, improving playback performance.
29
+ * Default is 1.
30
+ */
31
+ previewScale?: number;
32
+ }
33
+ interface ActiveGlobalEffect {
34
+ id: string;
35
+ key: EffectKey;
36
+ startTime: number;
37
+ duration: number;
38
+ trackIndex?: number;
39
+ values?: Record<string, any>;
40
+ }
41
+ interface GlobalEffectInfo {
42
+ id: string;
43
+ key: EffectKey;
44
+ startTime: number;
45
+ duration: number;
46
+ }
47
+ export interface StudioEvents {
48
+ "selection:created": {
49
+ selected: IClip[];
50
+ };
51
+ "selection:updated": {
52
+ selected: IClip[];
53
+ };
54
+ "selection:cleared": {
55
+ deselected: IClip[];
56
+ };
57
+ "track:added": {
58
+ track: StudioTrack;
59
+ index?: number;
60
+ };
61
+ "track:order-changed": {
62
+ tracks: StudioTrack[];
63
+ };
64
+ "track:removed": {
65
+ trackId: string;
66
+ };
67
+ "clip:added": {
68
+ clip: IClip;
69
+ trackId: string;
70
+ };
71
+ "clips:added": {
72
+ clips: IClip[];
73
+ trackId?: string;
74
+ };
75
+ "clip:removed": {
76
+ clipId: string;
77
+ };
78
+ "clip:updated": {
79
+ clip: IClip;
80
+ };
81
+ "clip:lock-changed": {
82
+ clip: IClip;
83
+ locked: boolean;
84
+ };
85
+ "clip:replaced": {
86
+ oldClip: IClip;
87
+ newClip: IClip;
88
+ trackId: string;
89
+ };
90
+ "studio:restored": {
91
+ clips: IClip[];
92
+ tracks: StudioTrack[];
93
+ settings: IStudioOpts;
94
+ };
95
+ currentTime: {
96
+ currentTime: number;
97
+ };
98
+ play: {
99
+ isPlaying: boolean;
100
+ };
101
+ pause: {
102
+ isPlaying: boolean;
103
+ };
104
+ "history:changed": {
105
+ canUndo: boolean;
106
+ canRedo: boolean;
107
+ };
108
+ "transform:start": {
109
+ transformer: Transformer;
110
+ };
111
+ "transform:end": {
112
+ transformer: Transformer;
113
+ };
114
+ "clip:dblclick": {
115
+ clip: IClip;
116
+ };
117
+ "viewport:changed": {
118
+ zoomLevel: number;
119
+ panOffset: {
120
+ x: number;
121
+ y: number;
122
+ };
123
+ };
124
+ [key: string]: any;
125
+ [key: symbol]: any;
126
+ }
127
+ export interface StudioTrack {
128
+ id: string;
129
+ name: string;
130
+ type: string;
131
+ clipIds: string[];
132
+ }
133
+ export declare class Studio extends EventEmitter<StudioEvents> {
134
+ selection: SelectionManager;
135
+ transport: Transport;
136
+ timeline: TimelineModel;
137
+ history: HistoryManager;
138
+ resourceManager: ResourceManager;
139
+ pixiApp: Application | null;
140
+ get tracks(): StudioTrack[];
141
+ get clips(): IClip<import('./sprite/base-sprite').BaseSpriteEvents>[];
142
+ spriteRenderers: Map<IClip<import('./sprite/base-sprite').BaseSpriteEvents>, PixiSpriteRenderer>;
143
+ artboard: Container | null;
144
+ clipContainer: Container | null;
145
+ artboardMask: Graphics | null;
146
+ artboardBg: Graphics | null;
147
+ get activeTransformer(): Transformer | null;
148
+ set activeTransformer(val: Transformer | null);
149
+ get selectedClips(): Set<IClip>;
150
+ set selectedClips(val: Set<IClip>);
151
+ get interactiveClips(): Set<IClip>;
152
+ set interactiveClips(val: Set<IClip>);
153
+ get playbackElements(): Map<IClip<import('./sprite/base-sprite').BaseSpriteEvents>, import('./studio/transport').PlaybackElementInfo>;
154
+ videoSprites: Map<IClip<import('./sprite/base-sprite').BaseSpriteEvents>, Sprite>;
155
+ clipListeners: Map<IClip<import('./sprite/base-sprite').BaseSpriteEvents>, () => void>;
156
+ get isPlaying(): boolean;
157
+ set isPlaying(val: boolean);
158
+ get currentTime(): number;
159
+ set currentTime(val: number);
160
+ get maxDuration(): number;
161
+ set maxDuration(val: number);
162
+ opts: Required<Omit<IStudioOpts, "canvas" | "core">> & {
163
+ canvas?: HTMLCanvasElement;
164
+ core?: Core;
165
+ };
166
+ destroyed: boolean;
167
+ private renderingSuspended;
168
+ /** Incremented per updateFrame call; only the latest call may apply decoded video frames */
169
+ private frameToken;
170
+ private historyPaused;
171
+ private processingHistory;
172
+ /**
173
+ * Indicates if the studio is currently restoring state from history (undo/redo)
174
+ */
175
+ isRestoring: boolean;
176
+ private historyGroupDepth;
177
+ private clipCache;
178
+ private _isUpdatingLayout;
179
+ private bridge;
180
+ /** User-controlled zoom multiplier on top of the fit-to-screen base scale.
181
+ * 1.0 = 100 % (no extra zoom beyond fit). */
182
+ private _zoomLevel;
183
+ /** Pan offset in canvas/screen pixels, applied after base centering. */
184
+ private _panOffset;
185
+ /** The base fit-to-screen scale last computed by updateArtboardLayout. */
186
+ private _baseScale;
187
+ private _allowZoom;
188
+ private _allowPan;
189
+ private _isPanning;
190
+ private _isSpaceDown;
191
+ private _lastPointerPos;
192
+ private _boundOnWheel;
193
+ private _boundOnPointerDown;
194
+ private _boundOnPointerMove;
195
+ private _boundOnPointerUp;
196
+ private _boundOnKeyDown;
197
+ private _boundOnKeyUp;
198
+ globalEffects: Map<string, GlobalEffectInfo>;
199
+ activeGlobalEffects: ActiveGlobalEffect[];
200
+ currentGlobalEffectSprite: Sprite | null;
201
+ effectFilters: Map<string, {
202
+ filter: null;
203
+ render(_opts: import('./effect/types').EffectRendererOptions): RenderTexture | null;
204
+ } | {
205
+ filter: any;
206
+ render({ width, height, canvasTexture, progress, values: runtimeValues, }: import('./effect/types').EffectRendererOptions): RenderTexture;
207
+ }>;
208
+ transitionRenderers: Map<string, {
209
+ render({ width, height, from, to, progress }: import('./transition/types').TransitionRendererOptions): RenderTexture;
210
+ destroy(): void;
211
+ }>;
212
+ transitionSprites: Map<string, Sprite>;
213
+ transFromTexture: RenderTexture | null;
214
+ transToTexture: RenderTexture | null;
215
+ transBgGraphics: Graphics | null;
216
+ clipsNormalContainer: Container | null;
217
+ clipsEffectContainer: Container | null;
218
+ videoTextureCache: WeakMap<HTMLVideoElement, Texture<import('pixi.js').TextureSource<any>>>;
219
+ lastFromFrame: Texture | ImageBitmap | VideoFrame | null;
220
+ lastToFrame: Texture | ImageBitmap | VideoFrame | null;
221
+ /**
222
+ * Convert hex color string to number
223
+ */
224
+ private hexToNumber;
225
+ ready: Promise<void>;
226
+ /**
227
+ * Create a new Studio instance
228
+ */
229
+ constructor(opts: IStudioOpts);
230
+ private attachClipEvents;
231
+ private handleTimelineChange;
232
+ private saveHistory;
233
+ beginHistoryGroup(): void;
234
+ endHistoryGroup(): void;
235
+ private setPath;
236
+ private applyHistoryPatches;
237
+ undo(): Promise<void>;
238
+ redo(): Promise<void>;
239
+ private cleanupClipVisuals;
240
+ private handleClipRemoved;
241
+ private handleClipsRemoved;
242
+ private initPixiApp;
243
+ /**
244
+ * Get studio options
245
+ */
246
+ getOptions(): IStudioOpts;
247
+ /**
248
+ * Update studio dimensions
249
+ */
250
+ setSize(width: number, height: number): void;
251
+ /**
252
+ * Set the preview resolution scale dynamically
253
+ * @param scale A multiplier between 0.1 and 1
254
+ */
255
+ setPreviewScale(scale: number): void;
256
+ private recreateTransitionTextures;
257
+ /**
258
+ * Update the background color of the studio (applies to the outside area)
259
+ */
260
+ setBackgroundColor(color: string): void;
261
+ /**
262
+ * Update the artboard background color of the studio (applies to the video frame itself)
263
+ */
264
+ setArtboardColor(color: string): void;
265
+ updateDimensions(width: number, height: number): void;
266
+ private handleResize;
267
+ updateArtboardLayout(options?: {
268
+ skipResize?: boolean;
269
+ }): void;
270
+ /** Current user zoom level (1 = fit-to-screen, 2 = 200 %, etc.). */
271
+ get zoomLevel(): number;
272
+ /** Base fit-to-screen scale (read-only, recomputed on every layout update). */
273
+ get baseScale(): number;
274
+ /**
275
+ * Set the user zoom level.
276
+ * @param level Desired zoom (1 = fit-to-screen). Clamped to [0.1, 10].
277
+ * @param originX Optional canvas-space X to zoom toward (defaults to center).
278
+ * @param originY Optional canvas-space Y to zoom toward (defaults to center).
279
+ */
280
+ setZoom(level: number, originX?: number, originY?: number): void;
281
+ /**
282
+ * Apply a relative pan (delta in screen pixels).
283
+ */
284
+ pan(dx: number, dy: number): void;
285
+ /**
286
+ * Reset zoom to 1× (fit-to-screen) and clear pan offset.
287
+ */
288
+ resetView(): void;
289
+ setAllowZoom(enabled: boolean): void;
290
+ setAllowPan(enabled: boolean): void;
291
+ private _initViewportEvents;
292
+ private _destroyViewportEvents;
293
+ /**
294
+ * Get the canvas element (creates one if not provided)
295
+ */
296
+ getCanvas(): HTMLCanvasElement;
297
+ addTransition(transitionKey: string, duration?: number, fromClipId?: string | null, toClipId?: string | null, id?: string): Promise<void>;
298
+ findTrackIdByClipId(clipId: string): string | undefined;
299
+ /**
300
+ * Add a clip (or clips) to the studio
301
+ * @param clipOrClips The clip or array of clips to add
302
+ * @param options Options for addition (trackId, etc.)
303
+ */
304
+ addClip(clipOrClips: IClip | IClip[], options?: {
305
+ trackId?: string;
306
+ audioSource?: string | File | Blob;
307
+ } | string | File | Blob): Promise<void>;
308
+ /**
309
+ * Add a new track to the studio
310
+ */
311
+ addTrack(track: {
312
+ name: string;
313
+ type: string;
314
+ id?: string;
315
+ }, index?: number): StudioTrack;
316
+ setTracks(tracks: StudioTrack[]): Promise<void>;
317
+ /**
318
+ * Move a track to a new index
319
+ */
320
+ moveTrack(trackId: string, newIndex: number): Promise<void>;
321
+ /**
322
+ * Set the order of tracks by ID
323
+ */
324
+ setTrackOrder(trackIds: string[]): Promise<void>;
325
+ removeTrack(trackId: string): Promise<void>;
326
+ /**
327
+ * Get a clip by its ID
328
+ */
329
+ getClipById(id: string): IClip | undefined;
330
+ updateClip(id: string, updates: Partial<IClip>): Promise<void>;
331
+ /**
332
+ * Centers object vertically and horizontally in the studio
333
+ */
334
+ centerClip(clipOrId: IClip | string): Promise<void>;
335
+ /**
336
+ * Centers object horizontally in the studio
337
+ */
338
+ centerClipH(clipOrId: IClip | string): Promise<void>;
339
+ /**
340
+ * Centers object vertically in the studio
341
+ */
342
+ centerClipV(clipOrId: IClip | string): Promise<void>;
343
+ /**
344
+ * Scale clip to fit within the studio dimensions while maintaining aspect ratio
345
+ */
346
+ scaleToFit(clipOrId: IClip | string): Promise<void>;
347
+ /**
348
+ * Scale clip to fill the studio dimensions while maintaining aspect ratio
349
+ */
350
+ scaleToCover(clipOrId: IClip | string): Promise<void>;
351
+ updateClips(updates: {
352
+ id: string;
353
+ updates: Partial<IClip>;
354
+ }[]): Promise<void>;
355
+ suspendRendering(): void;
356
+ resumeRendering(): void;
357
+ getTracks(): StudioTrack[];
358
+ getClip(id: string): IClip | undefined;
359
+ findClip(id: string): IClip | undefined;
360
+ /**
361
+ * Setup sprite interactivity for click selection
362
+ * Delegated to SelectionManager
363
+ */
364
+ setupSpriteInteractivity(clip: IClip): void;
365
+ /**
366
+ * Setup playback element for a clip (if it supports playback)
367
+ */
368
+ /**
369
+ * Remove a clip from the studio
370
+ */
371
+ removeClip(clipOrId: IClip | string): Promise<void>;
372
+ removeClips(clips: IClip[]): Promise<void>;
373
+ removeClipById(clipId: string): Promise<void>;
374
+ removeClipsById(clipIds: string[]): Promise<void>;
375
+ /**
376
+ * Delete all currently selected clips
377
+ */
378
+ deleteSelected(): Promise<void>;
379
+ duplicateSelected(): Promise<void>;
380
+ splitSelected(splitTime?: number): Promise<void>;
381
+ trimSelected(trimFromSeconds: number): Promise<void>;
382
+ updateSelected(updates: Partial<IClip>): Promise<void>;
383
+ /**
384
+ * Clear all clips from the studio
385
+ */
386
+ clear(): Promise<void>;
387
+ /**
388
+ * Start playback
389
+ */
390
+ play(): Promise<void>;
391
+ /**
392
+ * Pause playback
393
+ */
394
+ pause(): void;
395
+ /**
396
+ * Stop playback and reset to start
397
+ */
398
+ stop(): Promise<void>;
399
+ /**
400
+ * Seek to a specific time (in microseconds)
401
+ */
402
+ seek(time: number): Promise<void>;
403
+ /**
404
+ * Move to the next frame
405
+ */
406
+ frameNext(): Promise<void>;
407
+ /**
408
+ * Move to the previous frame
409
+ */
410
+ framePrev(): Promise<void>;
411
+ /**
412
+ * Renders the frame at the given time and returns it as a base64-encoded PNG.
413
+ *
414
+ * The artboard is temporarily reset to 1:1 scale during extraction so the
415
+ * output image always matches the project's configured width × height,
416
+ * regardless of the current viewport zoom.
417
+ *
418
+ * @param timeMs Time in milliseconds
419
+ * @param options.transparent If true, the artboard background fill is
420
+ * hidden so the resulting PNG has a transparent background.
421
+ * @returns Base64 data-URL string (e.g. "data:image/png;base64,...")
422
+ *
423
+ * @example
424
+ * await studio.ready;
425
+ * const frame = await studio.renderFrame(1500); // frame at 1.5 s
426
+ * const transparent = await studio.renderFrame(1500, { transparent: true });
427
+ * const img = document.createElement('img');
428
+ * img.src = frame;
429
+ */
430
+ renderFrame(timeMs: number, options?: {
431
+ transparent?: boolean;
432
+ }): Promise<string>;
433
+ /**
434
+ * Alias for {@link renderFrame} with support for the current playhead.
435
+ * Captures a single frame as a base64-encoded PNG.
436
+ *
437
+ * @param timeMs Optional time in milliseconds, or an options object. If
438
+ * omitted, the current playhead position is used.
439
+ * @param options.transparent If true, the artboard background fill is
440
+ * hidden so the resulting PNG has a transparent background.
441
+ * @returns Base64 data-URL string (e.g. "data:image/png;base64,...")
442
+ *
443
+ * @example
444
+ * await studio.ready;
445
+ * const currentFrame = await studio.snapshot(); // current playhead
446
+ * const frameAt2s = await studio.snapshot(2000); // explicit timestamp
447
+ * const transparent = await studio.snapshot({ transparent: true }); // current frame, transparent
448
+ * const transparent2s = await studio.snapshot(2000, { transparent: true });
449
+ */
450
+ snapshot(timeMs?: number | {
451
+ transparent?: boolean;
452
+ }): Promise<string>;
453
+ /**
454
+ * Get current playback time (in microseconds)
455
+ */
456
+ getCurrentTime(): number;
457
+ /**
458
+ * Get maximum duration (in microseconds)
459
+ */
460
+ getMaxDuration(): number;
461
+ /**
462
+ * Check if currently playing
463
+ */
464
+ getIsPlaying(): boolean;
465
+ /**
466
+ * Get currently selected clips
467
+ */
468
+ getSelectedClips(): IClip[];
469
+ private getVideoTexture;
470
+ private isPlaybackCapable;
471
+ updateFrame(timestamp: number): Promise<void>;
472
+ /**
473
+ * Apply global effect to the current scene
474
+ */
475
+ moveClipToEffectContainer(clip: IClip, toEffect?: boolean): void;
476
+ applyGlobalEffect(key: EffectKey, options: {
477
+ startTime: number;
478
+ duration?: number;
479
+ id?: string;
480
+ }, clips: IClip[]): string;
481
+ getTrackIndex(clipId: string): number;
482
+ /**
483
+ * Get the frame from the previous clip on the same track for transition
484
+ */
485
+ getTransitionFromFrame(clip: IClip, timestamp: number): Promise<VideoFrame | ImageBitmap | null | Texture>;
486
+ private getPreviousClipOnTrack;
487
+ /**
488
+ * Renders a clip frame onto a transition texture with red background
489
+ */
490
+ private renderClipToTransitionTexture;
491
+ removeGlobalEffect(id: string): void;
492
+ clearGlobalEffects(): void;
493
+ private updateActiveGlobalEffect;
494
+ private applyGlobalEffects;
495
+ /**
496
+ * Destroy the studio and clean up resources
497
+ */
498
+ destroy(): void;
499
+ /**
500
+ * Select a clip and show transform controls
501
+ * Delegated to InteractionManager
502
+ */
503
+ selectClip(clip: IClip, addToSelection?: boolean): void;
504
+ /**
505
+ * Set the selection to a specific list of clips
506
+ */
507
+ setSelection(clips: IClip[]): void;
508
+ /**
509
+ * Select clips by their IDs
510
+ */
511
+ selectClipsByIds(ids: string[]): void;
512
+ /**
513
+ * Deselect the current clip and hide transform controls
514
+ */
515
+ deselectClip(): void;
516
+ /**
517
+ * Toggle lock state of a clip
518
+ */
519
+ lockClip(clipId: string, locked: boolean): Promise<void>;
520
+ /**
521
+ * Export current studio state to JSON
522
+ * @param sourceUrlMap Optional map of clips to their source URLs (required for proper serialization)
523
+ */
524
+ exportToJSON(): ProjectJSON;
525
+ loadFromJSON(json: ProjectJSON): Promise<void>;
526
+ }
527
+ export {};
@@ -0,0 +1,17 @@
1
+ import { Graphics, Point } from 'pixi.js';
2
+ export type Side = "ml" | "mr" | "mt" | "mb";
3
+ type Corner = "tl" | "tr" | "bl" | "br" | "rot" | "rot_tl" | "rot_tr" | "rot_bl" | "rot_br";
4
+ export type HandleKind = Corner | Side;
5
+ interface Callbacks {
6
+ beginDrag: (handle: HandleKind, start: Point) => void;
7
+ updateDrag: (handle: HandleKind, pos: Point) => void;
8
+ endDrag: () => void;
9
+ }
10
+ export declare class Handle extends Graphics {
11
+ #private;
12
+ private handle;
13
+ cursor: string;
14
+ private callbacks;
15
+ constructor(handle: HandleKind, cursor: string, callbacks: Callbacks);
16
+ }
17
+ export {};
@@ -0,0 +1,45 @@
1
+ import { Point, Rectangle } from 'pixi.js';
2
+ export interface SnapGuide {
3
+ type: "vertical" | "horizontal";
4
+ position: number;
5
+ start: number;
6
+ end: number;
7
+ }
8
+ export interface SnapResult {
9
+ x: number | null;
10
+ y: number | null;
11
+ guides: SnapGuide[];
12
+ }
13
+ export declare class SnappingManager {
14
+ private artboardWidth;
15
+ private artboardHeight;
16
+ private scale;
17
+ static SNAP_THRESHOLD: number;
18
+ constructor(artboardWidth: number, artboardHeight: number, scale?: number);
19
+ updateContext(width: number, height: number, scale: number): void;
20
+ /**
21
+ * Snap a rectangle (bounds of the object) to artboard edges and center, as well as other objects.
22
+ * returns delta (adjustment) needed for x and y
23
+ */
24
+ snapMove(current: Rectangle, otherBounds?: Rectangle[]): {
25
+ dx: number;
26
+ dy: number;
27
+ guides: SnapGuide[];
28
+ };
29
+ /**
30
+ * Snap during scaling - only snaps the moving edges based on the handle.
31
+ * This prevents false triggers when stationary edges align with artboard edges.
32
+ * @param proposed - The proposed rectangle in local coordinates
33
+ * @param proposedWorld - The world position of the proposed rect's origin (top-left)
34
+ * @param handle - Which resize handle is being dragged
35
+ * @param otherBounds - Optional other clip bounds in parent space to snap to
36
+ */
37
+ snapResize(proposed: Rectangle, proposedWorld: Point, handle: "tl" | "tr" | "bl" | "br" | "ml" | "mr" | "mt" | "mb", otherBounds?: Rectangle[]): {
38
+ corrected: Rectangle;
39
+ guides: SnapGuide[];
40
+ };
41
+ snapPoint(point: Point): {
42
+ p: Point;
43
+ guides: SnapGuide[];
44
+ };
45
+ }
@@ -0,0 +1,38 @@
1
+ import { Container, Point, Graphics } from 'pixi.js';
2
+ import { Wireframe } from './wireframe';
3
+ import { HandleKind } from './handle';
4
+ export declare class Transformer extends Container {
5
+ #private;
6
+ group: Container[];
7
+ wireframe: Wireframe;
8
+ selectionOutlines: Graphics;
9
+ isDragging: boolean;
10
+ lastPointer: Point;
11
+ activeHandle: HandleKind | null;
12
+ opts: {
13
+ group: Container[];
14
+ centeredScaling?: boolean;
15
+ clip?: any;
16
+ artboardWidth?: number;
17
+ artboardHeight?: number;
18
+ locked?: boolean;
19
+ };
20
+ constructor(opts: {
21
+ group: Container[];
22
+ centeredScaling?: boolean;
23
+ clip?: any;
24
+ artboardWidth?: number;
25
+ artboardHeight?: number;
26
+ locked?: boolean;
27
+ });
28
+ /**
29
+ * Immediately initialize bounds and show transformer.
30
+ * Useful when we want to show it without waiting for the next tick.
31
+ */
32
+ showImmediate(): void;
33
+ /**
34
+ * Public method to update transformer bounds without recreating it
35
+ * Useful for updating bounds after clip dimensions change
36
+ */
37
+ updateBounds(): void;
38
+ }
@@ -0,0 +1,5 @@
1
+ import { Graphics, Rectangle } from 'pixi.js';
2
+ export declare class Wireframe extends Graphics {
3
+ constructor();
4
+ draw(bounds: Rectangle, scale?: number): void;
5
+ }
@@ -0,0 +1 @@
1
+ export declare const fragment: (glsl: string) => string;