import { Application, Sprite, Texture, Container, Graphics, RenderTexture } from 'pixi.js'; import { IClip } from './clips/iclip'; import { PixiSpriteRenderer } from './sprite/pixi-sprite-renderer'; import { ProjectJSON } from './json-serialization'; import { Transformer } from './transfomer/transformer'; import { EffectKey } from './effect/glsl/gl-effect'; import { default as EventEmitter } from './event-emitter'; import { SelectionManager } from './studio/selection-manager'; import { Transport } from './studio/transport'; import { TimelineModel } from './studio/timeline-model'; import { HistoryManager } from './studio/history-manager'; export interface IStudioOpts { width: number; height: number; fps?: number; bgColor?: string; canvas?: HTMLCanvasElement; interactivity?: boolean; spacing?: number; } interface ActiveGlobalEffect { id: string; key: EffectKey; startTime: number; duration: number; trackIndex?: number; } interface GlobalEffectInfo { id: string; key: EffectKey; startTime: number; duration: number; } export interface StudioEvents { 'selection:created': { selected: IClip[]; }; 'selection:updated': { selected: IClip[]; }; 'selection:cleared': { deselected: IClip[]; }; 'track:added': { track: StudioTrack; index?: number; }; 'track:order-changed': { tracks: StudioTrack[]; }; 'track:removed': { trackId: string; }; 'clip:added': { clip: IClip; trackId: string; }; 'clips:added': { clips: IClip[]; trackId?: string; }; 'clip:removed': { clipId: string; }; 'clip:updated': { clip: IClip; }; 'clip:replaced': { oldClip: IClip; newClip: IClip; trackId: string; }; 'studio:restored': { clips: IClip[]; tracks: StudioTrack[]; settings: IStudioOpts; }; currentTime: { currentTime: number; }; play: { isPlaying: boolean; }; pause: { isPlaying: boolean; }; 'history:changed': { canUndo: boolean; canRedo: boolean; }; [key: string]: any; [key: symbol]: any; } export interface StudioTrack { id: string; name: string; type: string; clipIds: string[]; } export declare class Studio extends EventEmitter { selection: SelectionManager; transport: Transport; timeline: TimelineModel; history: HistoryManager; pixiApp: Application | null; get tracks(): StudioTrack[]; get clips(): IClip[]; spriteRenderers: Map, PixiSpriteRenderer>; artboard: Container | null; clipContainer: Container | null; artboardMask: Graphics | null; artboardBg: Graphics | null; get activeTransformer(): Transformer | null; set activeTransformer(val: Transformer | null); get selectedClips(): Set; set selectedClips(val: Set); get interactiveClips(): Set; set interactiveClips(val: Set); get playbackElements(): Map, import('./studio/transport').PlaybackElementInfo>; videoSprites: Map, Sprite>; clipListeners: Map, () => void>; get isPlaying(): boolean; set isPlaying(val: boolean); get currentTime(): number; set currentTime(val: number); get maxDuration(): number; set maxDuration(val: number); opts: Required> & { canvas?: HTMLCanvasElement; }; destroyed: boolean; private renderingSuspended; private historyPaused; private processingHistory; private historyGroupDepth; private clipCache; globalEffects: Map; activeGlobalEffect: ActiveGlobalEffect | null; currentGlobalEffectSprite: Sprite | null; effectFilters: Map; transitionRenderers: Map; transitionSprites: Map; transFromTexture: RenderTexture | null; transToTexture: RenderTexture | null; transBgGraphics: Graphics | null; clipsNormalContainer: Container | null; clipsEffectContainer: Container | null; videoTextureCache: WeakMap>>; lastFromFrame: Texture | ImageBitmap | null; lastToFrame: Texture | ImageBitmap | null; /** * Convert hex color string to number */ private hexToNumber; ready: Promise; /** * Create a new Studio instance */ constructor(opts: IStudioOpts); private handleTimelineChange; private saveHistory; beginHistoryGroup(): void; endHistoryGroup(): void; private setPath; private applyHistoryPatches; undo(): Promise; redo(): Promise; private cleanupClipVisuals; private handleClipRemoved; private handleClipsRemoved; private initPixiApp; /** * Get studio options */ getOptions(): IStudioOpts; /** * Update studio dimensions */ setSize(width: number, height: number): void; updateDimensions(width: number, height: number): void; private handleResize; private updateArtboardLayout; /** * Get the canvas element (creates one if not provided) */ getCanvas(): HTMLCanvasElement; addTransition(transitionKey: string, duration?: number, fromClipId?: string | null, toClipId?: string | null): Promise; findTrackIdByClipId(clipId: string): string | undefined; /** * Add a clip (or clips) to the studio * @param clipOrClips The clip or array of clips to add * @param options Options for addition (trackId, etc.) */ addClip(clipOrClips: IClip | IClip[], options?: { trackId?: string; audioSource?: string | File | Blob; } | string | File | Blob): Promise; /** * Add a new track to the studio */ addTrack(track: { name: string; type: string; id?: string; }, index?: number): StudioTrack; setTracks(tracks: StudioTrack[]): Promise; /** * Move a track to a new index */ moveTrack(trackId: string, newIndex: number): Promise; /** * Set the order of tracks by ID */ setTrackOrder(trackIds: string[]): Promise; removeTrack(trackId: string): Promise; /** * Get a clip by its ID */ getClipById(id: string): IClip | undefined; updateClip(id: string, updates: Partial): Promise; /** * Centers object vertically and horizontally in the studio */ centerClip(clipOrId: IClip | string): Promise; /** * Centers object horizontally in the studio */ centerClipH(clipOrId: IClip | string): Promise; /** * Centers object vertically in the studio */ centerClipV(clipOrId: IClip | string): Promise; /** * Scale clip to fit within the studio dimensions while maintaining aspect ratio */ scaleToFit(clipOrId: IClip | string): Promise; /** * Scale clip to fill the studio dimensions while maintaining aspect ratio */ scaleToCover(clipOrId: IClip | string): Promise; updateClips(updates: { id: string; updates: Partial; }[]): Promise; suspendRendering(): void; resumeRendering(): void; getTracks(): StudioTrack[]; getClip(id: string): IClip | undefined; findClip(id: string): IClip | undefined; /** * Setup sprite interactivity for click selection * Delegated to SelectionManager */ setupSpriteInteractivity(clip: IClip): void; /** * Setup playback element for a clip (if it supports playback) */ /** * Remove a clip from the studio */ removeClip(clipOrId: IClip | string): Promise; removeClips(clips: IClip[]): Promise; removeClipById(clipId: string): Promise; removeClipsById(clipIds: string[]): Promise; /** * Delete all currently selected clips */ deleteSelected(): Promise; duplicateSelected(): Promise; splitSelected(splitTime?: number): Promise; trimSelected(trimFromSeconds: number): Promise; updateSelected(updates: Partial): Promise; /** * Clear all clips from the studio */ clear(): Promise; /** * Start playback */ play(): Promise; /** * Pause playback */ pause(): void; /** * Stop playback and reset to start */ stop(): Promise; /** * Seek to a specific time (in microseconds) */ seek(time: number): Promise; /** * Move to the next frame */ frameNext(): Promise; /** * Move to the previous frame */ framePrev(): Promise; /** * Get current playback time (in microseconds) */ getCurrentTime(): number; /** * Get maximum duration (in microseconds) */ getMaxDuration(): number; /** * Check if currently playing */ getIsPlaying(): boolean; /** * Get currently selected clips */ getSelectedClips(): IClip[]; private getVideoTexture; private isPlaybackCapable; updateFrame(timestamp: number): Promise; /** * Apply global effect to the current scene */ moveClipToEffectContainer(clip: IClip, toEffect?: boolean): void; applyGlobalEffect(key: EffectKey, options: { startTime: number; duration?: number; id?: string; }, clips: IClip[]): string; getTrackIndex(clipId: string): number; /** * Get the frame from the previous clip on the same track for transition */ getTransitionFromFrame(clip: IClip, timestamp: number): Promise; private getPreviousClipOnTrack; /** * Renders a clip frame onto a transition texture with red background */ private renderClipToTransitionTexture; removeGlobalEffect(id: string): void; clearGlobalEffects(): void; private updateActiveGlobalEffect; private applyGlobalEffectIfNeeded; /** * Destroy the studio and clean up resources */ destroy(): void; /** * Select a clip and show transform controls * Delegated to InteractionManager */ selectClip(clip: IClip, addToSelection?: boolean): void; /** * Set the selection to a specific list of clips */ setSelection(clips: IClip[]): void; /** * Select clips by their IDs */ selectClipsByIds(ids: string[]): void; /** * Deselect the current clip and hide transform controls */ deselectClip(): void; /** * Export current studio state to JSON * @param sourceUrlMap Optional map of clips to their source URLs (required for proper serialization) */ exportToJSON(): ProjectJSON; loadFromJSON(json: ProjectJSON): Promise; } export {};