@designcombo/video 0.0.1 → 0.0.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.
@@ -1,5 +1,13 @@
1
1
  import { IClip } from './clips';
2
2
  interface BaseClipJSON {
3
+ id?: string;
4
+ effects?: Array<{
5
+ id: string;
6
+ key: string;
7
+ startTime: number;
8
+ duration: number;
9
+ targets?: number[];
10
+ }>;
3
11
  src: string;
4
12
  display: {
5
13
  from: number;
@@ -15,6 +23,10 @@ interface BaseClipJSON {
15
23
  zIndex: number;
16
24
  opacity: number;
17
25
  flip: 'horizontal' | 'vertical' | null;
26
+ trim?: {
27
+ from: number;
28
+ to: number;
29
+ };
18
30
  animation?: {
19
31
  keyFrames: Record<string, Partial<{
20
32
  x: number;
@@ -122,8 +134,21 @@ export interface CaptionClipJSON extends BaseClipJSON {
122
134
  fontUrl?: string;
123
135
  }
124
136
  export type ClipJSON = VideoClipJSON | AudioClipJSON | ImageClipJSON | TextClipJSON | CaptionClipJSON;
137
+ export interface StudioTrackJSON {
138
+ id: string;
139
+ name: string;
140
+ type: string;
141
+ clipIds: string[];
142
+ }
125
143
  export interface ProjectJSON {
144
+ tracks?: StudioTrackJSON[];
126
145
  clips: ClipJSON[];
146
+ globalEffects?: Array<{
147
+ id: string;
148
+ key: string;
149
+ startTime: number;
150
+ duration: number;
151
+ }>;
127
152
  settings?: {
128
153
  width?: number;
129
154
  height?: number;
@@ -15,6 +15,10 @@ type TKeyFrameOpts = Partial<Record<`${number}%` | 'from' | 'to', Partial<TAnima
15
15
  * @see {@link OffscreenSprite}
16
16
  */
17
17
  export declare abstract class BaseSprite {
18
+ /**
19
+ * Unique identifier for the sprite/clip
20
+ */
21
+ id: string;
18
22
  /**
19
23
  * Control display time range of clips, commonly used in editing scenario timeline (track) module
20
24
  * from: start time offset in microseconds
@@ -36,6 +40,15 @@ export declare abstract class BaseSprite {
36
40
  * 2. Audio uses the simplest interpolation algorithm to change rate, so changing rate will cause pitch variation, for custom algorithm please use {@link VideoClip.tickInterceptor} to implement
37
41
  */
38
42
  playbackRate: number;
43
+ /**
44
+ * Trim range of the source media in microseconds
45
+ * from: start time in microseconds
46
+ * to: end time in microseconds
47
+ */
48
+ trim: {
49
+ from: number;
50
+ to: number;
51
+ };
39
52
  private evtTool;
40
53
  /**
41
54
  * Listen to property change events
@@ -50,6 +63,10 @@ export declare abstract class BaseSprite {
50
63
  height: number;
51
64
  angle: number;
52
65
  zIndex: number;
66
+ blur: number;
67
+ brightness: number;
68
+ round: number;
69
+ volume: number;
53
70
  }>) => void;
54
71
  }[Type]) => (() => void);
55
72
  private _left;
@@ -96,6 +113,30 @@ export declare abstract class BaseSprite {
96
113
  * Control layering relationship between clips, clips with smaller zIndex will be occluded
97
114
  */
98
115
  set zIndex(v: number);
116
+ private _blur;
117
+ /**
118
+ * Blur intensity (0.0 to 1.0, where 1.0 is max useful blur, e.g. 50px)
119
+ */
120
+ get blur(): number;
121
+ set blur(v: number);
122
+ private _brightness;
123
+ /**
124
+ * Brightness intensity (0.0 to 1.0, where 0.0 is Normal, 1.0 is Maximum)
125
+ */
126
+ get brightness(): number;
127
+ set brightness(v: number);
128
+ private _round;
129
+ /**
130
+ * Rounded corners intensity (0.0 to 1.0, where 1.0 is a perfect circle/capsule)
131
+ */
132
+ get round(): number;
133
+ set round(v: number);
134
+ private _volume;
135
+ /**
136
+ * Audio volume (0.0 to 1.0)
137
+ */
138
+ get volume(): number;
139
+ set volume(v: number);
99
140
  /**
100
141
  * Opacity
101
142
  */
@@ -104,6 +145,13 @@ export declare abstract class BaseSprite {
104
145
  * Flip clip horizontally or vertically
105
146
  */
106
147
  flip: 'horizontal' | 'vertical' | null;
148
+ effects: Array<{
149
+ id: string;
150
+ key: string;
151
+ startTime: number;
152
+ duration: number;
153
+ targets?: number[];
154
+ }>;
107
155
  private animatKeyFrame;
108
156
  private animatOpts;
109
157
  /**
@@ -19,7 +19,10 @@ export declare class PixiSpriteRenderer {
19
19
  private canvas;
20
20
  private context;
21
21
  private destroyed;
22
- constructor(pixiApp: Application | null, sprite: IClip, targetContainer?: Container | null);
22
+ private blurFilter;
23
+ private colorMatrixFilter;
24
+ private roundMask;
25
+ constructor(_pixiApp: Application | null, sprite: IClip, targetContainer?: Container | null);
23
26
  /**
24
27
  * Update the sprite with a new video frame or Texture
25
28
  * @param frame ImageBitmap, Texture, or null to render
@@ -28,21 +31,9 @@ export declare class PixiSpriteRenderer {
28
31
  updateFrame(frame: ImageBitmap | Texture | null): Promise<void>;
29
32
  /**
30
33
  * Apply sprite transformations to the Pixi Sprite
31
- * This reads the current sprite properties (which may have been updated by animations)
32
- * and applies them to the Pixi sprite
33
34
  */
34
35
  private applySpriteTransforms;
35
- /**
36
- * Update sprite properties without changing the frame
37
- * Useful when sprite properties change but frame stays the same
38
- */
39
36
  updateTransforms(): void;
40
- /**
41
- * Get the Pixi Sprite instance
42
- */
43
37
  getSprite(): Sprite | null;
44
- /**
45
- * Destroy the renderer and clean up resources
46
- */
47
38
  destroy(): void;
48
39
  }
package/dist/studio.d.ts CHANGED
@@ -1,11 +1,55 @@
1
1
  import { IClip } from './clips/iclip';
2
2
  import { ProjectJSON } from './json-serialization';
3
+ import { EffectKey } from './effect/glsl/gl-effect';
4
+ import { default as EventEmitter } from './event-emitter';
3
5
  export interface IStudioOpts {
4
6
  width: number;
5
7
  height: number;
6
8
  fps?: number;
7
9
  bgColor?: string;
8
10
  canvas?: HTMLCanvasElement;
11
+ interactivity?: boolean;
12
+ }
13
+ export interface StudioEvents {
14
+ 'selection:created': {
15
+ selected: IClip[];
16
+ };
17
+ 'selection:updated': {
18
+ selected: IClip[];
19
+ };
20
+ 'selection:cleared': {
21
+ deselected: IClip[];
22
+ };
23
+ 'track:added': {
24
+ track: StudioTrack;
25
+ };
26
+ 'track:removed': {
27
+ trackId: string;
28
+ };
29
+ 'clip:added': {
30
+ clip: IClip;
31
+ trackId: string;
32
+ };
33
+ 'clip:removed': {
34
+ clipId: string;
35
+ };
36
+ currentTime: {
37
+ currentTime: number;
38
+ };
39
+ play: {
40
+ isPlaying: boolean;
41
+ };
42
+ pause: {
43
+ isPlaying: boolean;
44
+ };
45
+ [key: string]: any;
46
+ [key: symbol]: any;
47
+ }
48
+ export interface StudioTrack {
49
+ id: string;
50
+ name: string;
51
+ type: string;
52
+ clipIds: string[];
9
53
  }
10
54
  /**
11
55
  * Interactive preview studio for clips with playback controls
@@ -22,9 +66,14 @@ export interface IStudioOpts {
22
66
  * await studio.addClip(spr1);
23
67
  * await studio.addClip(spr2);
24
68
  * studio.play();
69
+ *
70
+ * studio.on('selection:created', ({ selected }) => {
71
+ * console.log('Selection created', selected);
72
+ * });
25
73
  */
26
- export declare class Studio {
74
+ export declare class Studio extends EventEmitter<StudioEvents> {
27
75
  private pixiApp;
76
+ private tracks;
28
77
  private clips;
29
78
  private spriteRenderers;
30
79
  private artboard;
@@ -44,6 +93,12 @@ export declare class Studio {
44
93
  private maxDuration;
45
94
  private opts;
46
95
  private destroyed;
96
+ private globalEffects;
97
+ private activeGlobalEffect;
98
+ private currentGlobalEffectSprite;
99
+ private effectFilters;
100
+ private clipsNormalContainer;
101
+ private clipsEffectContainer;
47
102
  /**
48
103
  * Convert hex color string to number
49
104
  */
@@ -65,7 +120,35 @@ export declare class Studio {
65
120
  * @param clip The clip to add
66
121
  * @param audioSource Optional audio source (URL, File, or Blob) for AudioClip playback
67
122
  */
68
- addClip(clip: IClip, audioSource?: string | File | Blob): Promise<void>;
123
+ addClip(clip: IClip, options?: {
124
+ trackId?: string;
125
+ audioSource?: string | File | Blob;
126
+ } | string | File | Blob): Promise<void>;
127
+ /**
128
+ * Add a new track to the studio
129
+ */
130
+ addTrack(track: {
131
+ name: string;
132
+ type: string;
133
+ id?: string;
134
+ }): StudioTrack;
135
+ /**
136
+ * Set tracks (and implicitly clips if they are new)
137
+ */
138
+ setTracks(tracks: StudioTrack[]): Promise<void>;
139
+ /**
140
+ * Remove a track and all its clips
141
+ */
142
+ removeTrack(trackId: string): Promise<void>;
143
+ /**
144
+ * Update a clip's properties
145
+ * Handles consistency between display (from/to) and duration
146
+ */
147
+ updateClip(id: string, updates: Partial<IClip>): Promise<void>;
148
+ /**
149
+ * Get all tracks
150
+ */
151
+ getTracks(): StudioTrack[];
69
152
  /**
70
153
  * Setup sprite interactivity for click selection
71
154
  */
@@ -115,6 +198,20 @@ export declare class Studio {
115
198
  private renderLoop;
116
199
  private updateFrame;
117
200
  private recalculateMaxDuration;
201
+ /**
202
+ * Apply global effect to the current scene
203
+ */
204
+ moveClipToEffectContainer(clip: IClip, toEffect?: boolean): void;
205
+ applyGlobalEffect(key: EffectKey, options: {
206
+ startTime: number;
207
+ duration?: number;
208
+ id?: string;
209
+ }, clips: IClip[]): string;
210
+ getTrackIndex(clipId: string): number;
211
+ removeGlobalEffect(id: string): void;
212
+ clearGlobalEffects(): void;
213
+ private updateActiveGlobalEffect;
214
+ private applyGlobalEffectIfNeeded;
118
215
  /**
119
216
  * Destroy the studio and clean up resources
120
217
  */
@@ -154,4 +251,5 @@ export declare class Studio {
154
251
  * @param json The JSON project data
155
252
  */
156
253
  loadFromJSON(json: ProjectJSON): Promise<void>;
254
+ private loadClipIntoTrack;
157
255
  }