@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.
- package/LICENSE +47 -0
- package/NOTICE.md +19 -0
- package/README.md +6 -2
- package/dist/animation/block-reveal-animation.d.ts +33 -0
- package/dist/animation/easings.d.ts +4 -0
- package/dist/animation/gsap-animation.d.ts +32 -0
- package/dist/animation/index.d.ts +9 -0
- package/dist/animation/keyframe-animation.d.ts +11 -0
- package/dist/animation/mask-animation.d.ts +145 -0
- package/dist/animation/pixi-animation-utils.d.ts +10 -0
- package/dist/animation/registry.d.ts +11 -0
- package/dist/animation/types.d.ts +205 -0
- package/dist/animation/wipe-animation.d.ts +53 -0
- package/dist/clips/audio-clip.d.ts +122 -0
- package/dist/clips/backdrop-clip.d.ts +56 -0
- package/dist/clips/base-clip.d.ts +150 -0
- package/dist/clips/base-text-clip.d.ts +228 -0
- package/dist/clips/caption-clip.d.ts +129 -0
- package/dist/clips/clip-registry.d.ts +56 -0
- package/dist/clips/effect-clip.d.ts +37 -0
- package/dist/clips/iclip.d.ts +231 -0
- package/dist/clips/image-clip.d.ts +116 -0
- package/dist/clips/index.d.ts +20 -0
- package/dist/clips/placeholder-clip.d.ts +22 -0
- package/dist/clips/shape-clip.d.ts +59 -0
- package/dist/clips/text-clip.d.ts +148 -0
- package/dist/clips/transition-clip.d.ts +41 -0
- package/dist/clips/video-clip.d.ts +215 -0
- package/dist/compositor/audio-mixer.d.ts +8 -0
- package/dist/compositor/av-encoder.d.ts +17 -0
- package/dist/compositor/clip-style-renderer.d.ts +23 -0
- package/dist/compositor/compositor-renderer.d.ts +29 -0
- package/dist/compositor/effect-manager.d.ts +28 -0
- package/dist/compositor/scheduler.d.ts +8 -0
- package/dist/compositor/transition-manager.d.ts +45 -0
- package/dist/compositor.d.ts +157 -0
- package/dist/effect/constant/index.d.ts +566 -0
- package/dist/effect/effect.d.ts +9 -0
- package/dist/effect/glsl/custom-glsl.d.ts +1043 -0
- package/dist/effect/glsl/gl-effect.d.ts +38 -0
- package/dist/effect/interface/index.d.ts +25 -0
- package/dist/effect/types.d.ts +26 -0
- package/dist/effect/vertex.d.ts +1 -0
- package/dist/event-emitter.d.ts +55 -0
- package/dist/filters/outline-filter.d.ts +28 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.es.js +16038 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.cjs +3335 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/json-serialization.d.ts +310 -0
- package/dist/mp4-utils/index.d.ts +31 -0
- package/dist/mp4-utils/mp4box-utils.d.ts +44 -0
- package/dist/mp4-utils/sample-transform.d.ts +26 -0
- package/dist/sprite/base-sprite.d.ts +255 -0
- package/dist/sprite/pixi-sprite-renderer.d.ts +68 -0
- package/dist/standalone/index.es.js +94023 -0
- package/dist/standalone/index.es.js.map +1 -0
- package/dist/studio/history-manager.d.ts +46 -0
- package/dist/studio/resource-manager.d.ts +53 -0
- package/dist/studio/selection-manager.d.ts +66 -0
- package/dist/studio/timeline-model.d.ts +117 -0
- package/dist/studio/transport.d.ts +44 -0
- package/dist/studio-bridge.d.ts +50 -0
- package/dist/studio.d.ts +527 -0
- package/dist/transformer/handle.d.ts +17 -0
- package/dist/transformer/snapping.d.ts +45 -0
- package/dist/transformer/transformer.d.ts +38 -0
- package/dist/transformer/wireframe.d.ts +5 -0
- package/dist/transition/fragment.d.ts +1 -0
- package/dist/transition/glsl/custom-glsl.d.ts +231 -0
- package/dist/transition/glsl/gl-transition.d.ts +42 -0
- package/dist/transition/transition.d.ts +6 -0
- package/dist/transition/types.d.ts +29 -0
- package/dist/transition/uniforms.d.ts +35 -0
- package/dist/transition/vertex.d.ts +1 -0
- package/dist/utils/asset-manager.d.ts +15 -0
- package/dist/utils/audio-codec-detector.d.ts +39 -0
- package/dist/utils/audio.d.ts +81 -0
- package/dist/utils/chromakey.d.ts +24 -0
- package/dist/utils/color-adjustment.d.ts +53 -0
- package/dist/utils/color.d.ts +17 -0
- package/dist/utils/common.d.ts +7 -0
- package/dist/utils/dom.d.ts +48 -0
- package/dist/utils/effect.d.ts +1 -0
- package/dist/utils/fonts.d.ts +21 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/log.d.ts +27 -0
- package/dist/utils/media-cache.d.ts +45 -0
- package/dist/utils/stream-utils.d.ts +4 -0
- package/dist/utils/video.d.ts +16 -0
- package/dist/utils/worker-timer.d.ts +1 -0
- package/package.json +63 -3
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { IClip } from './iclip';
|
|
2
|
+
export interface TrackCaptionConfig {
|
|
3
|
+
style?: Record<string, any>;
|
|
4
|
+
colors?: {
|
|
5
|
+
active?: {
|
|
6
|
+
color?: string;
|
|
7
|
+
background?: string;
|
|
8
|
+
border?: {
|
|
9
|
+
color?: string;
|
|
10
|
+
width?: number;
|
|
11
|
+
};
|
|
12
|
+
} | null;
|
|
13
|
+
future?: {
|
|
14
|
+
color?: string;
|
|
15
|
+
border?: {
|
|
16
|
+
color?: string;
|
|
17
|
+
width?: number;
|
|
18
|
+
};
|
|
19
|
+
} | null;
|
|
20
|
+
keyword?: {
|
|
21
|
+
color?: string;
|
|
22
|
+
preserveAfterSpoken?: boolean;
|
|
23
|
+
} | null;
|
|
24
|
+
};
|
|
25
|
+
positioning?: {
|
|
26
|
+
videoWidth?: number;
|
|
27
|
+
videoHeight?: number;
|
|
28
|
+
bottomOffset?: number;
|
|
29
|
+
};
|
|
30
|
+
wordsPerLine?: "single" | "multiple";
|
|
31
|
+
}
|
|
32
|
+
export interface ClipContext {
|
|
33
|
+
captionConfig?: TrackCaptionConfig;
|
|
34
|
+
}
|
|
35
|
+
export type ClipClass = {
|
|
36
|
+
fromObject(json: any, context?: ClipContext): Promise<IClip>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Registry mapping clip type strings to their class constructors.
|
|
40
|
+
* Supports default core clips and dynamic registration of custom clip types.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ClipRegistry {
|
|
43
|
+
private static registry;
|
|
44
|
+
/**
|
|
45
|
+
* Register a clip class under a type name.
|
|
46
|
+
*/
|
|
47
|
+
static register(type: string, klass: ClipClass): void;
|
|
48
|
+
/**
|
|
49
|
+
* Retrieve the registered clip class for a type.
|
|
50
|
+
*/
|
|
51
|
+
static get(type: string): ClipClass | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Get all registered clip types.
|
|
54
|
+
*/
|
|
55
|
+
static getRegisteredTypes(): string[];
|
|
56
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BaseClip } from './base-clip';
|
|
2
|
+
import { IClip } from './iclip';
|
|
3
|
+
import { EffectKey } from '../effect/glsl/gl-effect';
|
|
4
|
+
export declare class Effect extends BaseClip {
|
|
5
|
+
readonly type = "Effect";
|
|
6
|
+
ready: IClip["ready"];
|
|
7
|
+
private _meta;
|
|
8
|
+
get meta(): {
|
|
9
|
+
duration: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Unique identifier for this clip instance
|
|
15
|
+
*/
|
|
16
|
+
id: string;
|
|
17
|
+
/**
|
|
18
|
+
* The effect key
|
|
19
|
+
*/
|
|
20
|
+
effectKey: EffectKey;
|
|
21
|
+
/**
|
|
22
|
+
* Effect parameters / values
|
|
23
|
+
*/
|
|
24
|
+
values: Record<string, any>;
|
|
25
|
+
constructor(effectKey: EffectKey);
|
|
26
|
+
clone(): Promise<this>;
|
|
27
|
+
tick(_time: number): Promise<{
|
|
28
|
+
video: ImageBitmap | undefined;
|
|
29
|
+
state: "success";
|
|
30
|
+
}>;
|
|
31
|
+
split(_time: number): Promise<[this, this]>;
|
|
32
|
+
toJSON(_main?: boolean): any;
|
|
33
|
+
/**
|
|
34
|
+
* Create an Effect instance from a JSON object
|
|
35
|
+
*/
|
|
36
|
+
static fromObject(json: any): Promise<Effect>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { BaseSprite, BaseSpriteEvents } from '../sprite/base-sprite';
|
|
2
|
+
import { ColorAdjustment } from '../utils/color-adjustment';
|
|
3
|
+
export interface IClipMeta {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
duration: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ITransitionInfo {
|
|
9
|
+
name: string;
|
|
10
|
+
duration: number;
|
|
11
|
+
textureUrl?: string;
|
|
12
|
+
prevClipId?: string;
|
|
13
|
+
fromClipId?: string;
|
|
14
|
+
toClipId?: string;
|
|
15
|
+
start?: number;
|
|
16
|
+
end?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface IChromaKeyOpts {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
color: string;
|
|
21
|
+
similarity: number;
|
|
22
|
+
spill: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Interface that all clips must implement
|
|
26
|
+
*
|
|
27
|
+
* Clips are abstractions of different data types, providing data to other modules
|
|
28
|
+
*
|
|
29
|
+
*
|
|
30
|
+
* You only need to implement this interface to create custom clips, giving you maximum flexibility to generate video content such as animations and transition effects
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
export interface IClip<T extends BaseSpriteEvents = BaseSpriteEvents> extends Omit<BaseSprite<T>, "destroy" | "ready"> {
|
|
34
|
+
destroy: () => void;
|
|
35
|
+
readonly ready: Promise<IClipMeta>;
|
|
36
|
+
/**
|
|
37
|
+
* Clip type (e.g., 'video', 'image', 'text', 'audio')
|
|
38
|
+
*/
|
|
39
|
+
readonly type: string;
|
|
40
|
+
/**
|
|
41
|
+
* Name of this clip
|
|
42
|
+
*/
|
|
43
|
+
name: string;
|
|
44
|
+
/**
|
|
45
|
+
* User-defined metadata
|
|
46
|
+
*/
|
|
47
|
+
metadata: Record<string, any>;
|
|
48
|
+
/**
|
|
49
|
+
* Source URL or identifier for this clip
|
|
50
|
+
*/
|
|
51
|
+
src: string;
|
|
52
|
+
/**
|
|
53
|
+
* Extract data from clip at specified time
|
|
54
|
+
* @param time Time in microseconds
|
|
55
|
+
*/
|
|
56
|
+
tick: (time: number) => Promise<{
|
|
57
|
+
video?: VideoFrame | ImageBitmap | null;
|
|
58
|
+
audio?: Float32Array[];
|
|
59
|
+
state: "done" | "success";
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Get video frame and audio at specified time
|
|
63
|
+
* This method is provided by BaseClip and used by Compositor
|
|
64
|
+
*/
|
|
65
|
+
getFrame(time: number): Promise<{
|
|
66
|
+
video: VideoFrame | ImageBitmap | null;
|
|
67
|
+
audio: Float32Array[];
|
|
68
|
+
done: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Data metadata
|
|
72
|
+
*/
|
|
73
|
+
readonly meta: IClipMeta;
|
|
74
|
+
/**
|
|
75
|
+
* When set, the clip's RenderTexture is larger than its logical bounds by this many pixels
|
|
76
|
+
* on each side (top, right, bottom, left). This provides transparent overflow room so that
|
|
77
|
+
* animations (e.g. slide, zoom) can move content outside the clip boundary without clipping.
|
|
78
|
+
* Selection handles, hit areas, and position sync all use the logical bounds, not the texture size.
|
|
79
|
+
*/
|
|
80
|
+
renderTexturePadding?: number;
|
|
81
|
+
/**
|
|
82
|
+
* Clone and return a new clip
|
|
83
|
+
*/
|
|
84
|
+
clone: () => Promise<this>;
|
|
85
|
+
/**
|
|
86
|
+
* Split at specified time, return two new clips before and after that moment, commonly used in editing scenarios to split clips by time
|
|
87
|
+
*
|
|
88
|
+
* This method will not corrupt original clip data
|
|
89
|
+
*
|
|
90
|
+
* @param time Time in microseconds
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
split?: (time: number) => Promise<[this, this]>;
|
|
94
|
+
/**
|
|
95
|
+
* Serialize clip to JSON format
|
|
96
|
+
* Returns a plain object with only serializable data (no circular references)
|
|
97
|
+
* @param main Whether this is the main clip (for Compositor)
|
|
98
|
+
*/
|
|
99
|
+
toJSON(main?: boolean): any;
|
|
100
|
+
/**
|
|
101
|
+
* Set an external renderer (e.g., from Studio)
|
|
102
|
+
* This is called by Studio when adding clips to provide a shared renderer
|
|
103
|
+
* @param renderer The PixiJS renderer to use
|
|
104
|
+
*/
|
|
105
|
+
setRenderer?(renderer: any): void;
|
|
106
|
+
/**
|
|
107
|
+
* Transition info (optional)
|
|
108
|
+
*/
|
|
109
|
+
transition?: ITransitionInfo;
|
|
110
|
+
/**
|
|
111
|
+
* Audio volume level (0-1)
|
|
112
|
+
*/
|
|
113
|
+
volume: number;
|
|
114
|
+
/**
|
|
115
|
+
* Styling properties (e.g., stroke, dropShadow, borderRadius)
|
|
116
|
+
*/
|
|
117
|
+
style: any;
|
|
118
|
+
/**
|
|
119
|
+
* Get the list of visible transformer handles for this clip type
|
|
120
|
+
* Similar to Fabric.js v6 controls visibility pattern
|
|
121
|
+
* @returns Array of handle kinds that should be visible
|
|
122
|
+
*/
|
|
123
|
+
getVisibleHandles?: () => Array<"tl" | "tr" | "bl" | "br" | "ml" | "mr" | "mt" | "mb" | "rot">;
|
|
124
|
+
/**
|
|
125
|
+
* Scale clip to fit within the scene dimensions while maintaining aspect ratio
|
|
126
|
+
*/
|
|
127
|
+
scaleToFit(sceneWidth: number, sceneHeight: number): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Scale clip to fill the scene dimensions while maintaining aspect ratio
|
|
130
|
+
*/
|
|
131
|
+
scaleToFill(sceneWidth: number, sceneHeight: number): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Center the clip within the scene dimensions
|
|
134
|
+
*/
|
|
135
|
+
centerInScene(sceneWidth: number, sceneHeight: number): void;
|
|
136
|
+
/**
|
|
137
|
+
* Add a modular animation to the clip
|
|
138
|
+
* @param name Preset name or 'keyframes'
|
|
139
|
+
* @param opts Animation options (duration, delay, etc.)
|
|
140
|
+
* @param params Preset-specific parameters or KeyframeData
|
|
141
|
+
*/
|
|
142
|
+
addAnimation(name: string, options: any, params?: any): string;
|
|
143
|
+
/**
|
|
144
|
+
* Remove an animation by ID
|
|
145
|
+
*/
|
|
146
|
+
removeAnimation(id: string): void;
|
|
147
|
+
/**
|
|
148
|
+
* Clear all modular animations
|
|
149
|
+
*/
|
|
150
|
+
clearAnimations(): void;
|
|
151
|
+
/**
|
|
152
|
+
* List of active animations
|
|
153
|
+
*/
|
|
154
|
+
readonly animations: any[];
|
|
155
|
+
/**
|
|
156
|
+
* Chroma key settings (green screen removal)
|
|
157
|
+
*/
|
|
158
|
+
chromaKey?: IChromaKeyOpts;
|
|
159
|
+
/**
|
|
160
|
+
* Clip color adjustment settings
|
|
161
|
+
*/
|
|
162
|
+
colorAdjustment?: ColorAdjustment;
|
|
163
|
+
/**
|
|
164
|
+
* Whether the clip is locked (preventing interactions)
|
|
165
|
+
*/
|
|
166
|
+
locked: boolean;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Optional interface for clips that support HTML media element playback
|
|
170
|
+
* Used by Studio for interactive preview
|
|
171
|
+
*/
|
|
172
|
+
export interface IPlaybackCapable {
|
|
173
|
+
/**
|
|
174
|
+
* Create and initialize HTML media element for playback
|
|
175
|
+
* @returns Promise resolving to the media element and optional object URL for cleanup
|
|
176
|
+
*/
|
|
177
|
+
createPlaybackElement(): Promise<{
|
|
178
|
+
element: HTMLVideoElement | HTMLAudioElement;
|
|
179
|
+
objectUrl?: string;
|
|
180
|
+
}>;
|
|
181
|
+
/**
|
|
182
|
+
* Start playback at a specific time
|
|
183
|
+
* @param element The HTML media element
|
|
184
|
+
* @param timeSeconds Time in seconds (relative to clip start)
|
|
185
|
+
*/
|
|
186
|
+
play(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Pause playback
|
|
189
|
+
* @param element The HTML media element
|
|
190
|
+
*/
|
|
191
|
+
pause(element: HTMLVideoElement | HTMLAudioElement): void;
|
|
192
|
+
/**
|
|
193
|
+
* Seek to a specific time
|
|
194
|
+
* @param element The HTML media element
|
|
195
|
+
* @param timeSeconds Time in seconds (relative to clip start)
|
|
196
|
+
*/
|
|
197
|
+
seek(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Sync playback state during preview
|
|
200
|
+
* @param element The HTML media element
|
|
201
|
+
* @param isPlaying Whether playback should be active
|
|
202
|
+
* @param timeSeconds Current time in seconds (relative to clip start)
|
|
203
|
+
*/
|
|
204
|
+
syncPlayback(element: HTMLVideoElement | HTMLAudioElement, isPlaying: boolean, timeSeconds: number): void;
|
|
205
|
+
/**
|
|
206
|
+
* Clean up playback element and resources
|
|
207
|
+
* @param element The HTML media element
|
|
208
|
+
* @param objectUrl Optional object URL to revoke
|
|
209
|
+
*/
|
|
210
|
+
cleanupPlayback(element: HTMLVideoElement | HTMLAudioElement, objectUrl?: string): void;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get the default audio configuration
|
|
214
|
+
* This function returns a promise that resolves to the best supported audio codec
|
|
215
|
+
*/
|
|
216
|
+
export declare function getDefaultAudioConf(): Promise<{
|
|
217
|
+
codec: string;
|
|
218
|
+
sampleRate: number;
|
|
219
|
+
channelCount: number;
|
|
220
|
+
}>;
|
|
221
|
+
/**
|
|
222
|
+
* Synchronous version that returns cached codec or a default fallback
|
|
223
|
+
* Use this only when you need synchronous access (e.g., in constants)
|
|
224
|
+
* Prefer getDefaultAudioConf() for async contexts
|
|
225
|
+
*/
|
|
226
|
+
export declare const DEFAULT_AUDIO_CONF: {
|
|
227
|
+
readonly codec: string;
|
|
228
|
+
readonly codecType: "aac" | "opus";
|
|
229
|
+
readonly sampleRate: number;
|
|
230
|
+
readonly channelCount: number;
|
|
231
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Texture } from 'pixi.js';
|
|
2
|
+
import { BaseClip } from './base-clip';
|
|
3
|
+
import { IClip } from './iclip';
|
|
4
|
+
import { ClipJSON, ImageJSON } from '../json-serialization';
|
|
5
|
+
type AnimateImgType = "avif" | "webp" | "png" | "gif";
|
|
6
|
+
/**
|
|
7
|
+
* Image clip supporting animated images
|
|
8
|
+
*
|
|
9
|
+
* Ordinary text can be converted to image clip using {@link renderTxt2ImgBitmap}
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Load from URL using PixiJS Assets (optimized for Studio)
|
|
13
|
+
* const imgClip = await Image.fromUrl('path/to/image.png');
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Traditional approach (for Compositor/export)
|
|
17
|
+
* new Image((await fetch('<img url>')).body);
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* new Image(
|
|
21
|
+
* await renderTxt2ImgBitmap(
|
|
22
|
+
* 'Watermark',
|
|
23
|
+
* `font-size:40px; color: white; text-shadow: 2px 2px 6px red;`,
|
|
24
|
+
* )
|
|
25
|
+
* )
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
export declare class Image extends BaseClip implements IClip {
|
|
29
|
+
readonly type = "Image";
|
|
30
|
+
ready: IClip["ready"];
|
|
31
|
+
private _meta;
|
|
32
|
+
/**
|
|
33
|
+
* ⚠️ Static images have duration of Infinity
|
|
34
|
+
*
|
|
35
|
+
* When wrapping with Sprite, you need to set its duration to a finite number
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
get meta(): {
|
|
39
|
+
duration: number;
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
};
|
|
43
|
+
private img;
|
|
44
|
+
private pixiTexture;
|
|
45
|
+
private frames;
|
|
46
|
+
/**
|
|
47
|
+
* Unique identifier for this clip instance
|
|
48
|
+
*/
|
|
49
|
+
id: string;
|
|
50
|
+
/**
|
|
51
|
+
* Array of effects to be applied to this clip
|
|
52
|
+
* Each effect specifies key, startTime, duration, and optional targets
|
|
53
|
+
*/
|
|
54
|
+
effects: Array<{
|
|
55
|
+
id: string;
|
|
56
|
+
key: string;
|
|
57
|
+
startTime: number;
|
|
58
|
+
duration: number;
|
|
59
|
+
}>;
|
|
60
|
+
getVisibleHandles(): Array<"tl" | "tr" | "bl" | "br" | "ml" | "mr" | "mt" | "mb" | "rot">;
|
|
61
|
+
/**
|
|
62
|
+
* Load an image clip from a URL using PixiJS Assets
|
|
63
|
+
* This is optimized for Studio as it uses Texture directly
|
|
64
|
+
*
|
|
65
|
+
* @param url Image URL
|
|
66
|
+
* @param src Optional source identifier for serialization
|
|
67
|
+
* @returns Promise that resolves to an Image instance
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* const imgClip = await Image.fromUrl('path/to/image.png');
|
|
71
|
+
*/
|
|
72
|
+
static fromUrl(url: string, src?: string): Promise<Image>;
|
|
73
|
+
/**
|
|
74
|
+
* Get the PixiJS Texture (if available)
|
|
75
|
+
* This is used for optimized rendering in Studio
|
|
76
|
+
*/
|
|
77
|
+
getTexture(): Texture | null;
|
|
78
|
+
/**
|
|
79
|
+
* Static images can be initialized using stream or ImageBitmap
|
|
80
|
+
*
|
|
81
|
+
* Animated images need to use VideoFrame[] or provide image type
|
|
82
|
+
*/
|
|
83
|
+
constructor(dataSource: ReadableStream | ImageBitmap | VideoFrame[] | {
|
|
84
|
+
type: `image/${AnimateImgType}`;
|
|
85
|
+
stream: ReadableStream;
|
|
86
|
+
}, src?: string);
|
|
87
|
+
private initAnimateImg;
|
|
88
|
+
tickInterceptor: <T extends Awaited<ReturnType<Image["tick"]>>>(time: number, tickRet: T) => Promise<T>;
|
|
89
|
+
tick(time: number): Promise<{
|
|
90
|
+
video: ImageBitmap | VideoFrame;
|
|
91
|
+
state: "success";
|
|
92
|
+
}>;
|
|
93
|
+
split(time: number): Promise<[this, this]>;
|
|
94
|
+
clone(): Promise<this>;
|
|
95
|
+
addEffect(effect: {
|
|
96
|
+
id: string;
|
|
97
|
+
key: string;
|
|
98
|
+
startTime: number;
|
|
99
|
+
duration: number;
|
|
100
|
+
}): void;
|
|
101
|
+
editEffect(effectId: string, newEffectData: Partial<{
|
|
102
|
+
key: string;
|
|
103
|
+
startTime: number;
|
|
104
|
+
duration: number;
|
|
105
|
+
}>): void;
|
|
106
|
+
removeEffect(effectId: string): void;
|
|
107
|
+
destroy(): void;
|
|
108
|
+
toJSON(main?: boolean): ImageJSON;
|
|
109
|
+
/**
|
|
110
|
+
* Create an Image instance from a JSON object (fabric.js pattern)
|
|
111
|
+
* @param json The JSON object representing the clip
|
|
112
|
+
* @returns Promise that resolves to an Image instance
|
|
113
|
+
*/
|
|
114
|
+
static fromObject(json: ClipJSON): Promise<Image>;
|
|
115
|
+
}
|
|
116
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './audio-clip';
|
|
2
|
+
export * from './caption-clip';
|
|
3
|
+
export * from './iclip';
|
|
4
|
+
export * from './image-clip';
|
|
5
|
+
export * from './video-clip';
|
|
6
|
+
export { Video } from './video-clip';
|
|
7
|
+
export type { IMP4ClipOpts } from './video-clip';
|
|
8
|
+
export * from './base-text-clip';
|
|
9
|
+
export * from './text-clip';
|
|
10
|
+
export * from './effect-clip';
|
|
11
|
+
export { Effect } from './effect-clip';
|
|
12
|
+
export * from './placeholder-clip';
|
|
13
|
+
export { Placeholder } from './placeholder-clip';
|
|
14
|
+
export * from './transition-clip';
|
|
15
|
+
export { Transition } from './transition-clip';
|
|
16
|
+
export * from './shape-clip';
|
|
17
|
+
export { ShapeClip } from './shape-clip';
|
|
18
|
+
export * from './backdrop-clip';
|
|
19
|
+
export { Backdrop } from './backdrop-clip';
|
|
20
|
+
export * from './clip-registry';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseClip } from './base-clip';
|
|
2
|
+
import { IClipMeta } from './iclip';
|
|
3
|
+
export declare class Placeholder extends BaseClip {
|
|
4
|
+
type: string;
|
|
5
|
+
meta: IClipMeta;
|
|
6
|
+
constructor(src: string, meta?: Partial<IClipMeta>, type?: string);
|
|
7
|
+
private canvas;
|
|
8
|
+
private ctx;
|
|
9
|
+
private animationRafId;
|
|
10
|
+
private renderPending;
|
|
11
|
+
tick(_time: number): Promise<{
|
|
12
|
+
video: ImageBitmap | VideoFrame | null;
|
|
13
|
+
audio: Float32Array[];
|
|
14
|
+
state: "done" | "success";
|
|
15
|
+
}>;
|
|
16
|
+
clone(): Promise<this>;
|
|
17
|
+
split(time: number): Promise<[this, this]>;
|
|
18
|
+
/**
|
|
19
|
+
* Create a Placeholder instance from a JSON object
|
|
20
|
+
*/
|
|
21
|
+
static fromObject(json: any): Promise<Placeholder>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Graphics, Application } from 'pixi.js';
|
|
2
|
+
import { BaseClip } from './base-clip';
|
|
3
|
+
import { ShapeType } from '@agrhub/core';
|
|
4
|
+
import { IClipMeta } from './iclip';
|
|
5
|
+
export interface ShapeClipOptions {
|
|
6
|
+
shapeType: ShapeType;
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
fill?: string;
|
|
10
|
+
fillOpacity?: number;
|
|
11
|
+
stroke?: {
|
|
12
|
+
color: string;
|
|
13
|
+
width: number;
|
|
14
|
+
};
|
|
15
|
+
borderRadius?: number;
|
|
16
|
+
renderer?: Application["renderer"];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* ShapeClip renders rectangle shapes using Pixi.js Graphics
|
|
20
|
+
*/
|
|
21
|
+
export declare class ShapeClip extends BaseClip {
|
|
22
|
+
readonly type = "Shape";
|
|
23
|
+
shapeType: ShapeType;
|
|
24
|
+
graphics: Graphics;
|
|
25
|
+
private _meta;
|
|
26
|
+
private renderTexture;
|
|
27
|
+
private externalRenderer;
|
|
28
|
+
constructor(options: ShapeClipOptions);
|
|
29
|
+
private getRenderer;
|
|
30
|
+
/**
|
|
31
|
+
* Set an external renderer (e.g., from Studio)
|
|
32
|
+
*/
|
|
33
|
+
setRenderer(renderer: Application["renderer"]): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get or create the render texture for this shape
|
|
36
|
+
*/
|
|
37
|
+
private getRenderTexture;
|
|
38
|
+
get meta(): IClipMeta;
|
|
39
|
+
private drawShape;
|
|
40
|
+
private drawRectangle;
|
|
41
|
+
private hexToNumber;
|
|
42
|
+
tick(_time: number): Promise<{
|
|
43
|
+
video: ImageBitmap;
|
|
44
|
+
state: "success";
|
|
45
|
+
}>;
|
|
46
|
+
clone(): Promise<this>;
|
|
47
|
+
split(_time: number): Promise<[this, this]>;
|
|
48
|
+
toJSON(main?: boolean): any;
|
|
49
|
+
set style(style: any);
|
|
50
|
+
get style(): any;
|
|
51
|
+
set width(width: number);
|
|
52
|
+
get width(): number;
|
|
53
|
+
set height(height: number);
|
|
54
|
+
get height(): number;
|
|
55
|
+
/**
|
|
56
|
+
* Create ShapeClip from JSON object
|
|
57
|
+
*/
|
|
58
|
+
static fromObject(json: any): Promise<ShapeClip>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Application, Container } from 'pixi.js';
|
|
2
|
+
import { IClip } from './iclip';
|
|
3
|
+
import { TextJSON } from '../json-serialization';
|
|
4
|
+
import { BaseSpriteEvents } from '../sprite/base-sprite';
|
|
5
|
+
import { BaseTextClip, IBaseTextOpts } from './base-text-clip';
|
|
6
|
+
export interface ITextOpts extends IBaseTextOpts {
|
|
7
|
+
/**
|
|
8
|
+
* Text decoration ('none', 'underline', 'line-through', 'overline')
|
|
9
|
+
* @default 'none'
|
|
10
|
+
*/
|
|
11
|
+
textDecoration?: "none" | "underline" | "line-through" | "overline";
|
|
12
|
+
/**
|
|
13
|
+
* Words per line mode ('single' or 'multiple')
|
|
14
|
+
* @default 'multiple'
|
|
15
|
+
*/
|
|
16
|
+
wordsPerLine?: "single" | "multiple";
|
|
17
|
+
}
|
|
18
|
+
export interface ITextEvents extends BaseSpriteEvents {
|
|
19
|
+
propsChange: Partial<{
|
|
20
|
+
left: number;
|
|
21
|
+
top: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
angle: number;
|
|
25
|
+
zIndex: number;
|
|
26
|
+
opacity: number;
|
|
27
|
+
volume: number;
|
|
28
|
+
text: string;
|
|
29
|
+
style: any;
|
|
30
|
+
} & ITextOpts>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Text clip using PixiJS Text for rendering
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const textClip = new Text('Hello World', {
|
|
37
|
+
* fontSize: 48,
|
|
38
|
+
* fill: '#ffffff',
|
|
39
|
+
* stroke: '#000000',
|
|
40
|
+
* strokeWidth: 2,
|
|
41
|
+
* dropShadow: {
|
|
42
|
+
* color: '#000000',
|
|
43
|
+
* alpha: 0.5,
|
|
44
|
+
* blur: 4,
|
|
45
|
+
* distance: 2,
|
|
46
|
+
* },
|
|
47
|
+
* });
|
|
48
|
+
* textClip.duration = 5e6; // 5 seconds
|
|
49
|
+
*/
|
|
50
|
+
export declare class Text extends BaseTextClip<ITextEvents> {
|
|
51
|
+
readonly type = "Text";
|
|
52
|
+
ready: IClip["ready"];
|
|
53
|
+
get width(): number;
|
|
54
|
+
set width(v: number);
|
|
55
|
+
get height(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Flag to track if height was explicitly set by user (vs auto-calculated from content)
|
|
58
|
+
*/
|
|
59
|
+
private _explicitHeight;
|
|
60
|
+
/**
|
|
61
|
+
* Get whether height was explicitly set by user
|
|
62
|
+
*/
|
|
63
|
+
get isExplicitHeight(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Reset height to auto-fit mode (height will adjust to content)
|
|
66
|
+
*/
|
|
67
|
+
resetHeightToAuto(): void;
|
|
68
|
+
set height(v: number);
|
|
69
|
+
/**
|
|
70
|
+
* Text content (hybrid JSON structure)
|
|
71
|
+
*/
|
|
72
|
+
get text(): string;
|
|
73
|
+
set text(v: string);
|
|
74
|
+
/**
|
|
75
|
+
* Text styling (hybrid JSON structure)
|
|
76
|
+
* Provides direct access to styling properties
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* Text styling (hybrid JSON structure)
|
|
80
|
+
* Provides direct access to styling properties
|
|
81
|
+
*/
|
|
82
|
+
get style(): any;
|
|
83
|
+
set style(opts: Partial<ITextOpts>);
|
|
84
|
+
/**
|
|
85
|
+
* Text alignment proxy for compatibility with UI
|
|
86
|
+
*/
|
|
87
|
+
get textAlign(): "left" | "center" | "right";
|
|
88
|
+
set textAlign(v: "left" | "center" | "right");
|
|
89
|
+
/**
|
|
90
|
+
* Vertical alignment or decoration proxy
|
|
91
|
+
*/
|
|
92
|
+
get verticalAlign(): string;
|
|
93
|
+
set verticalAlign(v: string);
|
|
94
|
+
/**
|
|
95
|
+
* Text case proxy
|
|
96
|
+
*/
|
|
97
|
+
get textCase(): string;
|
|
98
|
+
set textCase(v: "none" | "uppercase" | "lowercase" | "title");
|
|
99
|
+
/**
|
|
100
|
+
* Decoration proxies for UI compatibility (booleans)
|
|
101
|
+
*/
|
|
102
|
+
get underline(): boolean;
|
|
103
|
+
set underline(v: boolean);
|
|
104
|
+
get overline(): boolean;
|
|
105
|
+
set overline(v: boolean);
|
|
106
|
+
get linethrough(): boolean;
|
|
107
|
+
set linethrough(v: boolean);
|
|
108
|
+
protected _targetWidth: number;
|
|
109
|
+
private _wordCache;
|
|
110
|
+
private _measuredTextHeight;
|
|
111
|
+
private _lineHeightMultiplier;
|
|
112
|
+
private _fontSize;
|
|
113
|
+
private _textOnlyContainer;
|
|
114
|
+
originalOpts: ITextOpts;
|
|
115
|
+
constructor(text: string, opts?: ITextOpts, renderer?: Application["renderer"]);
|
|
116
|
+
_onAfterRefresh(words: string[], textOnlyContainer: Container, spaceWidth: number, measuredTextHeight: number, lineHeightMultiplier: number, fontSize: number): void;
|
|
117
|
+
clone(): Promise<this>;
|
|
118
|
+
/**
|
|
119
|
+
* Update text styling options and refresh the texture
|
|
120
|
+
*/
|
|
121
|
+
updateStyle(opts: Partial<ITextOpts>): Promise<void>;
|
|
122
|
+
private _populateWordCache;
|
|
123
|
+
/**
|
|
124
|
+
* Fast layout update for real-time transform operations.
|
|
125
|
+
* Re-calculates word wrapping and repositions existing text objects without
|
|
126
|
+
* re-creating them. Much faster than full refreshText() for resize operations.
|
|
127
|
+
*
|
|
128
|
+
* @param targetWidth - The new target width for wrapping
|
|
129
|
+
* @returns Object with new width and height
|
|
130
|
+
*/
|
|
131
|
+
updateLayoutForWidth(targetWidth: number): {
|
|
132
|
+
width: number;
|
|
133
|
+
height: number;
|
|
134
|
+
};
|
|
135
|
+
toJSON(main?: boolean): TextJSON;
|
|
136
|
+
/**
|
|
137
|
+
* Create a Text instance from a JSON object (fabric.js pattern)
|
|
138
|
+
* @param json The JSON object representing the clip
|
|
139
|
+
* @returns Promise that resolves to a Text instance
|
|
140
|
+
*/
|
|
141
|
+
static fromObject(json: TextJSON): Promise<Text>;
|
|
142
|
+
/**
|
|
143
|
+
* Override handle visibility for text clips
|
|
144
|
+
* Text clips should only show: mr (mid-right), mb (mid-bottom), br (bottom-right), and rot (rotation)
|
|
145
|
+
* This allows resizing width and height independently while preventing corner handles that might distort text
|
|
146
|
+
*/
|
|
147
|
+
getVisibleHandles(): Array<"tl" | "tr" | "bl" | "br" | "ml" | "mr" | "mt" | "mb" | "rot">;
|
|
148
|
+
}
|