@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,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
+ }