@twick/timeline 0.14.0

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 (38) hide show
  1. package/README.md +175 -0
  2. package/dist/context/timeline-context.d.ts +33 -0
  3. package/dist/context/undo-redo-context.d.ts +21 -0
  4. package/dist/core/addOns/animation.d.ts +24 -0
  5. package/dist/core/addOns/frame-effect.d.ts +14 -0
  6. package/dist/core/addOns/text-effect.d.ts +19 -0
  7. package/dist/core/editor/timeline.editor.d.ts +94 -0
  8. package/dist/core/elements/audio.element.d.ts +20 -0
  9. package/dist/core/elements/base.element.d.ts +35 -0
  10. package/dist/core/elements/caption.element.d.ts +10 -0
  11. package/dist/core/elements/circle.element.d.ts +13 -0
  12. package/dist/core/elements/icon.element.d.ts +9 -0
  13. package/dist/core/elements/image.element.d.ts +32 -0
  14. package/dist/core/elements/rect.element.d.ts +11 -0
  15. package/dist/core/elements/text.element.d.ts +26 -0
  16. package/dist/core/elements/video.element.d.ts +41 -0
  17. package/dist/core/track/track.d.ts +77 -0
  18. package/dist/core/track/track.friend.d.ts +34 -0
  19. package/dist/core/visitor/element-adder.d.ts +29 -0
  20. package/dist/core/visitor/element-cloner.d.ts +22 -0
  21. package/dist/core/visitor/element-deserializer.d.ts +23 -0
  22. package/dist/core/visitor/element-remover.d.ts +28 -0
  23. package/dist/core/visitor/element-serializer.d.ts +23 -0
  24. package/dist/core/visitor/element-splitter.d.ts +28 -0
  25. package/dist/core/visitor/element-updater.d.ts +28 -0
  26. package/dist/core/visitor/element-validator.d.ts +34 -0
  27. package/dist/core/visitor/element-visitor.d.ts +19 -0
  28. package/dist/index.d.ts +36 -0
  29. package/dist/index.js +2630 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/index.mjs +2628 -0
  32. package/dist/index.mjs.map +1 -0
  33. package/dist/services/data.service.d.ts +25 -0
  34. package/dist/types/index.d.ts +169 -0
  35. package/dist/utils/constants.d.ts +55 -0
  36. package/dist/utils/register-editor.d.ts +8 -0
  37. package/dist/utils/timeline.utils.d.ts +11 -0
  38. package/package.json +40 -0
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # @twick/timeline
2
+
3
+ ## Timeline Editor CRUD Operations
4
+
5
+ The TimelineEditor provides a clean interface for managing tracks and elements using the visitor pattern.
6
+
7
+ ### Track Operations
8
+
9
+ ```typescript
10
+ import { TimelineEditor, TimelineOperationContext } from '@twick/timeline';
11
+
12
+ // Create editor with context
13
+ const context: TimelineOperationContext = {
14
+ contextId: 'my-editor',
15
+ setTotalDuration: (duration) => console.log('Duration:', duration),
16
+ setPresent: (data) => console.log('Present:', data),
17
+ handleUndo: () => console.log('Undo'),
18
+ handleRedo: () => console.log('Redo'),
19
+ handleResetHistory: () => console.log('Reset History'),
20
+ setLatestProjectVersion: (version) => console.log('Version:', version),
21
+ setTimelineAction: (action, payload) => console.log('Action:', action, payload),
22
+ };
23
+
24
+ const editor = new TimelineEditor(context);
25
+
26
+ // Create a new track
27
+ const track = editor.addTrack('My Video Track');
28
+
29
+ // Get track by ID
30
+ const trackById = editor.getTrackById(track.getId());
31
+
32
+ // Get track by name
33
+ const trackByName = editor.getTrackByName('My Video Track');
34
+
35
+ // Remove track
36
+ editor.removeTrackById(track.getId());
37
+ ```
38
+
39
+ ### Element Operations (Using Visitor Pattern)
40
+
41
+ The TimelineEditor uses the visitor pattern to handle different element types consistently:
42
+
43
+ ```typescript
44
+ import {
45
+ TimelineEditor,
46
+ TextElement,
47
+ VideoElement,
48
+ ImageElement,
49
+ AudioElement,
50
+ TrackElement
51
+ } from '@twick/timeline';
52
+
53
+ // Add elements to track
54
+ const textElement = new TextElement('Hello World')
55
+ .setStart(0)
56
+ .setEnd(5)
57
+ .setName('Welcome Text');
58
+
59
+ const videoElement = new VideoElement('video.mp4', { width: 720, height: 480 })
60
+ .setStart(0)
61
+ .setEnd(30)
62
+ .setName('Main Video');
63
+
64
+ // Add elements using visitor pattern
65
+ await editor.addElementToTrack(track.getId(), textElement);
66
+ await editor.addElementToTrack(track.getId(), videoElement);
67
+
68
+ // Update elements
69
+ const updatedTextElement = new TextElement('Updated Text')
70
+ .setId(textElement.getId()) // Keep same ID
71
+ .setStart(0)
72
+ .setEnd(8)
73
+ .setName('Updated Welcome Text');
74
+
75
+ editor.updateElementInTrack(track.getId(), updatedTextElement);
76
+
77
+ // Remove elements
78
+ editor.removeElementFromTrack(track.getId(), textElement);
79
+ ```
80
+
81
+ ### Complete CRUD Example
82
+
83
+ ```typescript
84
+ // Create editor and track
85
+ const editor = new TimelineEditor(context);
86
+ const track = editor.addTrack('Demo Track');
87
+
88
+ // Create elements
89
+ const textElement = new TextElement('Sample Text')
90
+ .setStart(0)
91
+ .setEnd(5)
92
+ .setName('Sample Text Element');
93
+
94
+ const imageElement = new ImageElement('image.jpg', { width: 300, height: 200 })
95
+ .setStart(5)
96
+ .setEnd(10)
97
+ .setName('Sample Image');
98
+
99
+ // Add elements
100
+ await editor.addElementToTrack(track.getId(), textElement);
101
+ await editor.addElementToTrack(track.getId(), imageElement);
102
+
103
+ // Update element
104
+ const updatedText = new TextElement('Updated Sample Text')
105
+ .setId(textElement.getId())
106
+ .setStart(0)
107
+ .setEnd(8)
108
+ .setName('Updated Text Element');
109
+
110
+ editor.updateElementInTrack(track.getId(), updatedText);
111
+
112
+ // Remove element
113
+ editor.removeElementFromTrack(track.getId(), imageElement);
114
+
115
+ // Get timeline data
116
+ const timelineData = editor.getTimelineData();
117
+ console.log('Timeline:', timelineData);
118
+ ```
119
+
120
+ ### Utility Functions
121
+
122
+ ```typescript
123
+ import {
124
+ getCurrentElements,
125
+ getTotalDuration,
126
+ generateShortUuid,
127
+ isElementId,
128
+ isTrackId
129
+ } from '@twick/timeline';
130
+
131
+ // Get elements currently playing at a specific time
132
+ const currentElements = getCurrentElements(currentTime, tracks);
133
+
134
+ // Get total duration of all tracks
135
+ const totalDuration = getTotalDuration(trackData);
136
+
137
+ // Generate unique IDs
138
+ const elementId = generateShortUuid(); // "e-xxxxxxxxxxxx"
139
+ const trackId = generateShortUuid(); // "t-xxxxxxxxxxxx"
140
+
141
+ // Check ID types
142
+ isElementId('e-123456789abc'); // true
143
+ isTrackId('t-123456789abc'); // true
144
+ ```
145
+
146
+ ### Visitor Pattern Benefits
147
+
148
+ - **Type Safety**: Each element type is handled specifically
149
+ - **Extensibility**: Easy to add new element types
150
+ - **Consistency**: Same pattern for all CRUD operations
151
+ - **Maintainability**: Clean separation of concerns
152
+
153
+ ### React Hook Usage
154
+
155
+ ```typescript
156
+ import { useTimelineContext } from '@twick/timeline';
157
+
158
+ function MyComponent() {
159
+ const { editor } = useTimelineContext();
160
+
161
+ // Use editor methods
162
+ const track = editor.addTrack('My Track');
163
+
164
+ // Add elements
165
+ const textElement = new TextElement('Hello World')
166
+ .setStart(0)
167
+ .setEnd(5);
168
+
169
+ await editor.addElementToTrack(track.getId(), textElement);
170
+
171
+ return <div>Timeline Editor Ready</div>;
172
+ }
173
+ ```
174
+
175
+
@@ -0,0 +1,33 @@
1
+ import { Track } from '../core/track/track';
2
+ import { TrackElement } from '../core/elements/base.element';
3
+ import { ProjectJSON, TrackJSON } from '../types';
4
+ import { TimelineEditor } from '../core/editor/timeline.editor';
5
+
6
+ export type TimelineContextType = {
7
+ contextId: string;
8
+ editor: TimelineEditor;
9
+ selectedItem: Track | TrackElement | null;
10
+ changeLog: number;
11
+ timelineAction: {
12
+ type: string;
13
+ payload: any;
14
+ };
15
+ totalDuration: number;
16
+ present: ProjectJSON | null;
17
+ canUndo: boolean;
18
+ canRedo: boolean;
19
+ setSelectedItem: (item: Track | TrackElement | null) => void;
20
+ setTimelineAction: (type: string, payload: any) => void;
21
+ };
22
+ export interface TimelineProviderProps {
23
+ children: React.ReactNode;
24
+ contextId: string;
25
+ initialData?: {
26
+ tracks: TrackJSON[];
27
+ version: number;
28
+ };
29
+ undoRedoPersistenceKey?: string;
30
+ maxHistorySize?: number;
31
+ }
32
+ export declare const TimelineProvider: ({ contextId, children, initialData, undoRedoPersistenceKey, maxHistorySize, }: TimelineProviderProps) => import("react/jsx-runtime").JSX.Element;
33
+ export declare const useTimelineContext: () => TimelineContextType;
@@ -0,0 +1,21 @@
1
+ import { ProjectJSON } from '../types';
2
+
3
+ interface UndoRedoContextType {
4
+ canUndo: boolean;
5
+ canRedo: boolean;
6
+ present: ProjectJSON | null;
7
+ setPresent: (data: ProjectJSON) => void;
8
+ undo: () => ProjectJSON | null;
9
+ redo: () => ProjectJSON | null;
10
+ resetHistory: () => void;
11
+ getLastPersistedState: () => ProjectJSON | null;
12
+ disablePersistence: () => void;
13
+ }
14
+ export interface UndoRedoProviderProps {
15
+ children: React.ReactNode;
16
+ persistenceKey?: string;
17
+ maxHistorySize?: number;
18
+ }
19
+ export declare const UndoRedoProvider: React.FC<UndoRedoProviderProps>;
20
+ export declare const useUndoRedo: () => UndoRedoContextType;
21
+ export {};
@@ -0,0 +1,24 @@
1
+ import { Animation } from '../../types';
2
+
3
+ export declare class ElementAnimation {
4
+ private name;
5
+ private interval?;
6
+ private intensity?;
7
+ private animate?;
8
+ private mode?;
9
+ private direction?;
10
+ constructor(name: string);
11
+ getName(): string;
12
+ getInterval(): number | undefined;
13
+ getIntensity(): number | undefined;
14
+ getAnimate(): "enter" | "exit" | "both" | undefined;
15
+ getMode(): "in" | "out" | undefined;
16
+ getDirection(): "left" | "center" | "right" | "up" | "down" | undefined;
17
+ setInterval(interval?: number): void;
18
+ setIntensity(intensity?: number): void;
19
+ setAnimate(animate?: "enter" | "exit" | "both"): void;
20
+ setMode(mode?: "in" | "out"): void;
21
+ setDirection(direction?: "up" | "down" | "left" | "right" | "center"): void;
22
+ toJSON(): Animation;
23
+ static fromJSON(json: Animation): ElementAnimation;
24
+ }
@@ -0,0 +1,14 @@
1
+ import { FrameEffect, FrameEffectProps } from '../../types';
2
+
3
+ export declare class ElementFrameEffect {
4
+ private s;
5
+ private e;
6
+ private props;
7
+ constructor(start: number, end: number);
8
+ setProps(props: FrameEffectProps): void;
9
+ getProps(): FrameEffectProps;
10
+ getStart(): number;
11
+ getEnd(): number;
12
+ toJSON(): FrameEffect;
13
+ static fromJSON(json: FrameEffect): ElementFrameEffect;
14
+ }
@@ -0,0 +1,19 @@
1
+ import { TextEffect } from '../../types';
2
+
3
+ export declare class ElementTextEffect {
4
+ private name;
5
+ private duration?;
6
+ private delay?;
7
+ private bufferTime?;
8
+ constructor(name: string);
9
+ getName(): string;
10
+ getDuration(): number | undefined;
11
+ getDelay(): number | undefined;
12
+ getBufferTime(): number | undefined;
13
+ setName(name: string): void;
14
+ setDuration(duration?: number): void;
15
+ setDelay(delay?: number): void;
16
+ setBufferTime(bufferTime?: number): void;
17
+ toJSON(): TextEffect;
18
+ static fromJSON(json: TextEffect): ElementTextEffect;
19
+ }
@@ -0,0 +1,94 @@
1
+ import { Track } from '../track/track';
2
+ import { TimelineTrackData } from '../../services/data.service';
3
+ import { SplitResult } from '../visitor/element-splitter';
4
+ import { TrackElement } from '../elements/base.element';
5
+ import { ProjectJSON, TrackJSON } from '../../types';
6
+
7
+ /**
8
+ * Type for timeline operation context
9
+ */
10
+ export interface TimelineOperationContext {
11
+ contextId: string;
12
+ setTotalDuration: (duration: number) => void;
13
+ setPresent: (data: ProjectJSON) => void;
14
+ handleUndo: () => ProjectJSON | null;
15
+ handleRedo: () => ProjectJSON | null;
16
+ handleResetHistory: () => void;
17
+ updateChangeLog: () => void;
18
+ setTimelineAction?: (action: string, payload?: unknown) => void;
19
+ }
20
+ /**
21
+ * TimelineEditor
22
+ *
23
+ * This class provides an interface to execute all timeline operations
24
+ * using a direct, class-based approach with track-based management.
25
+ * It also handles undo/redo operations internally.
26
+ */
27
+ export declare class TimelineEditor {
28
+ private context;
29
+ constructor(context: TimelineOperationContext);
30
+ getContext(): TimelineOperationContext;
31
+ pauseVideo(): void;
32
+ getTimelineData(): TimelineTrackData | null;
33
+ getLatestVersion(): number;
34
+ protected setTimelineData(tracks: Track[], version?: number): TimelineTrackData;
35
+ addTrack(name: string): Track;
36
+ getTrackById(id: string): Track | null;
37
+ getTrackByName(name: string): Track | null;
38
+ removeTrackById(id: string): void;
39
+ removeTrack(track: Track): void;
40
+ /**
41
+ * Refresh the timeline data
42
+ */
43
+ refresh(): void;
44
+ /**
45
+ * Add an element to a specific track using the visitor pattern
46
+ * @param track The track to add the element to
47
+ * @param element The element to add
48
+ * @returns Promise<boolean> true if element was added successfully
49
+ */
50
+ addElementToTrack(track: Track, element: TrackElement): Promise<boolean>;
51
+ /**
52
+ * Remove an element from a specific track using the visitor pattern
53
+ * @param element The element to remove
54
+ * @returns boolean true if element was removed successfully
55
+ */
56
+ removeElement(element: TrackElement): boolean;
57
+ /**
58
+ * Update an element in a specific track using the visitor pattern
59
+ * @param element The updated element
60
+ * @returns boolean true if element was updated successfully
61
+ */
62
+ updateElement(element: TrackElement): boolean;
63
+ /**
64
+ * Split an element at a specific time point using the visitor pattern
65
+ * @param element The element to split
66
+ * @param splitTime The time point to split at
67
+ * @returns SplitResult with first element, second element, and success status
68
+ */
69
+ splitElement(element: TrackElement, splitTime: number): Promise<SplitResult>;
70
+ /**
71
+ * Clone an element using the visitor pattern
72
+ * @param element The element to clone
73
+ * @returns TrackElement | null - the cloned element or null if cloning failed
74
+ */
75
+ cloneElement(element: TrackElement): TrackElement | null;
76
+ reorderTracks(tracks: Track[]): void;
77
+ updateHistory(timelineTrackData: TimelineTrackData): void;
78
+ /**
79
+ * Trigger undo operation and update timeline data
80
+ */
81
+ undo(): void;
82
+ /**
83
+ * Trigger redo operation and update timeline data
84
+ */
85
+ redo(): void;
86
+ /**
87
+ * Reset history and clear timeline data
88
+ */
89
+ resetHistory(): void;
90
+ loadProject({ tracks, version, }: {
91
+ tracks: TrackJSON[];
92
+ version: number;
93
+ }): void;
94
+ }
@@ -0,0 +1,20 @@
1
+ import { TrackElement } from './base.element';
2
+ import { ElementVisitor } from '../visitor/element-visitor';
3
+ import { AudioProps } from '../../types';
4
+
5
+ export declare class AudioElement extends TrackElement {
6
+ protected mediaDuration: number;
7
+ protected props: AudioProps;
8
+ constructor(src: string);
9
+ getMediaDuration(): number;
10
+ getStartAt(): number;
11
+ updateAudioMeta(): Promise<void>;
12
+ setSrc(src: string): Promise<this>;
13
+ setMediaDuration(mediaDuration: number): this;
14
+ setVolume(volume: number): this;
15
+ setLoop(loop: boolean): this;
16
+ setStartAt(time: number): this;
17
+ setPlaybackRate(playbackRate: number): this;
18
+ setProps(props: Omit<any, "src">): this;
19
+ accept<T>(visitor: ElementVisitor<T>): T;
20
+ }
@@ -0,0 +1,35 @@
1
+ import { ElementVisitor } from '../visitor/element-visitor';
2
+ import { ElementAnimation } from '../addOns/animation';
3
+ import { Position } from '../../types';
4
+
5
+ export declare abstract class TrackElement {
6
+ protected id: string;
7
+ protected type: string;
8
+ protected s: number;
9
+ protected e: number;
10
+ protected trackId: string;
11
+ protected name: string;
12
+ protected animation?: ElementAnimation;
13
+ protected props: Record<string, any>;
14
+ constructor(type: string, id?: string);
15
+ abstract accept<T>(visitor: ElementVisitor<T>): T;
16
+ getId(): string;
17
+ getType(): string;
18
+ getStart(): number;
19
+ getEnd(): number;
20
+ getDuration(): number;
21
+ getTrackId(): string;
22
+ getProps(): Record<string, any>;
23
+ getName(): string;
24
+ getAnimation(): ElementAnimation | undefined;
25
+ getPosition(): Position;
26
+ setId(id: string): this;
27
+ setType(type: string): this;
28
+ setStart(s: number): this;
29
+ setEnd(e: number): this;
30
+ setTrackId(trackId: string): this;
31
+ setName(name: string): this;
32
+ setAnimation(animation?: ElementAnimation): this;
33
+ setPosition(position: Position): this;
34
+ setProps(props: Record<string, any>): this;
35
+ }
@@ -0,0 +1,10 @@
1
+ import { TrackElement } from './base.element';
2
+ import { ElementVisitor } from '../visitor/element-visitor';
3
+
4
+ export declare class CaptionElement extends TrackElement {
5
+ protected t: string;
6
+ constructor(t: string, start: number, end: number);
7
+ getText(): string;
8
+ setText(t: string): this;
9
+ accept<T>(visitor: ElementVisitor<T>): T;
10
+ }
@@ -0,0 +1,13 @@
1
+ import { TrackElement } from './base.element';
2
+ import { ElementVisitor } from '../visitor/element-visitor';
3
+ import { CircleProps } from '../../types';
4
+
5
+ export declare class CircleElement extends TrackElement {
6
+ protected props: CircleProps;
7
+ constructor(fill: string, radius: number);
8
+ getFill(): string;
9
+ getRadius(): number;
10
+ setFill(fill: string): this;
11
+ setRadius(radius: number): this;
12
+ accept<T>(visitor: ElementVisitor<T>): T;
13
+ }
@@ -0,0 +1,9 @@
1
+ import { TrackElement } from './base.element';
2
+ import { ElementVisitor } from '../visitor/element-visitor';
3
+ import { IconProps, Size } from '../../types';
4
+
5
+ export declare class IconElement extends TrackElement {
6
+ protected props: IconProps;
7
+ constructor(src: string, size: Size);
8
+ accept<T>(visitor: ElementVisitor<T>): T;
9
+ }
@@ -0,0 +1,32 @@
1
+ import { Frame, ImageProps, ObjectFit, Position, Size } from '../../types';
2
+ import { TrackElement } from './base.element';
3
+ import { ElementVisitor } from '../visitor/element-visitor';
4
+ import { ElementFrameEffect } from '../addOns/frame-effect';
5
+
6
+ export declare class ImageElement extends TrackElement {
7
+ protected backgroundColor: string;
8
+ protected parentSize: Size;
9
+ protected objectFit: ObjectFit;
10
+ frameEffects?: ElementFrameEffect[];
11
+ frame: Frame;
12
+ protected props: ImageProps;
13
+ constructor(src: string, parentSize: Size);
14
+ getParentSize(): Size;
15
+ getFrame(): Frame;
16
+ getFrameEffects(): ElementFrameEffect[] | undefined;
17
+ getBackgroundColor(): string;
18
+ getObjectFit(): ObjectFit;
19
+ getPosition(): Position;
20
+ updateImageMeta(updateFrame?: boolean): Promise<void>;
21
+ setPosition(position: Position): this;
22
+ setSrc(src: string): Promise<this>;
23
+ setObjectFit(objectFit: ObjectFit): this;
24
+ setFrame(frame: Frame): this;
25
+ setParentSize(parentSize: Size): this;
26
+ setMediaFilter(mediaFilter: string): this;
27
+ setBackgroundColor(backgroundColor: string): this;
28
+ setProps(props: Omit<any, "src">): this;
29
+ setFrameEffects(frameEffects?: ElementFrameEffect[]): this;
30
+ addFrameEffect(frameEffect: ElementFrameEffect): this;
31
+ accept<T>(visitor: ElementVisitor<T>): T;
32
+ }
@@ -0,0 +1,11 @@
1
+ import { RectProps, Size } from '../../types';
2
+ import { TrackElement } from './base.element';
3
+ import { ElementVisitor } from '../visitor/element-visitor';
4
+
5
+ export declare class RectElement extends TrackElement {
6
+ protected props: RectProps;
7
+ constructor(fill: string, size: Size);
8
+ setFill(fill: string): this;
9
+ setSize(size: Size): this;
10
+ accept<T>(visitor: ElementVisitor<T>): T;
11
+ }
@@ -0,0 +1,26 @@
1
+ import { TextAlign, TextProps } from '../../types';
2
+ import { TrackElement } from './base.element';
3
+ import { ElementVisitor } from '../visitor/element-visitor';
4
+ import { ElementTextEffect } from '../addOns/text-effect';
5
+
6
+ export declare class TextElement extends TrackElement {
7
+ protected textEffect?: ElementTextEffect;
8
+ protected props: TextProps;
9
+ constructor(text: string);
10
+ getTextEffect(): ElementTextEffect | undefined;
11
+ getText(): string;
12
+ getStrokeColor(): string | undefined;
13
+ getLineWidth(): number | undefined;
14
+ setText(text: string): this;
15
+ setFill(fill: string): this;
16
+ setRotation(rotation: number): this;
17
+ setFontSize(fontSize: number): this;
18
+ setFontFamily(fontFamily: string): this;
19
+ setFontWeight(fontWeight: number): this;
20
+ setFontStyle(fontStyle: "normal" | "italic"): this;
21
+ setTextEffect(textEffect?: ElementTextEffect): this;
22
+ setTextAlign(textAlign: TextAlign): this;
23
+ setStrokeColor(stroke: string): this;
24
+ setLineWidth(lineWidth: number): this;
25
+ accept<T>(visitor: ElementVisitor<T>): T;
26
+ }
@@ -0,0 +1,41 @@
1
+ import { Frame, ObjectFit, Position, Size, VideoProps } from '../../types';
2
+ import { TrackElement } from './base.element';
3
+ import { ElementVisitor } from '../visitor/element-visitor';
4
+ import { ElementFrameEffect } from '../addOns/frame-effect';
5
+
6
+ export declare class VideoElement extends TrackElement {
7
+ protected baseSize: Size;
8
+ protected mediaDuration: number;
9
+ protected parentSize: Size;
10
+ protected backgroundColor: string;
11
+ protected objectFit: ObjectFit;
12
+ protected frameEffects?: ElementFrameEffect[];
13
+ protected frame: Frame;
14
+ protected props: VideoProps;
15
+ constructor(src: string, parentSize: Size);
16
+ getParentSize(): Size;
17
+ getFrame(): Frame;
18
+ getFrameEffects(): ElementFrameEffect[] | undefined;
19
+ getBackgroundColor(): string;
20
+ getObjectFit(): ObjectFit;
21
+ getMediaDuration(): number;
22
+ getStartAt(): number;
23
+ getPosition(): Position;
24
+ updateVideoMeta(updateFrame?: boolean): Promise<void>;
25
+ setPosition(position: Position): this;
26
+ setSrc(src: string): Promise<this>;
27
+ setMediaDuration(mediaDuration: number): this;
28
+ setParentSize(parentSize: Size): this;
29
+ setObjectFit(objectFit: ObjectFit): this;
30
+ setFrame(frame: Frame): this;
31
+ setPlay(play: boolean): this;
32
+ setPlaybackRate(playbackRate: number): this;
33
+ setStartAt(time: number): this;
34
+ setMediaFilter(mediaFilter: string): this;
35
+ setVolume(volume: number): this;
36
+ setBackgroundColor(backgroundColor: string): this;
37
+ setProps(props: Omit<any, "src">): this;
38
+ setFrameEffects(frameEffects?: ElementFrameEffect[]): this;
39
+ addFrameEffect(frameEffect: ElementFrameEffect): this;
40
+ accept<T>(visitor: ElementVisitor<T>): T;
41
+ }
@@ -0,0 +1,77 @@
1
+ import { TrackJSON } from '../../types';
2
+ import { TrackElement } from '../elements/base.element';
3
+ import { TrackFriend } from './track.friend';
4
+
5
+ export declare class Track {
6
+ private id;
7
+ private name;
8
+ private type;
9
+ private elements;
10
+ private validator;
11
+ constructor(name: string, id?: string);
12
+ /**
13
+ * Create a friend instance for explicit access to protected methods
14
+ * This implements the Friend Class Pattern
15
+ * @returns TrackFriend instance
16
+ */
17
+ createFriend(): TrackFriend;
18
+ /**
19
+ * Friend method to add element (called by TrackFriend)
20
+ * @param element The element to add
21
+ * @param skipValidation If true, skips validation
22
+ * @returns true if element was added successfully
23
+ */
24
+ addElementViaFriend(element: TrackElement, skipValidation?: boolean): boolean;
25
+ /**
26
+ * Friend method to remove element (called by TrackFriend)
27
+ * @param element The element to remove
28
+ */
29
+ removeElementViaFriend(element: TrackElement): void;
30
+ /**
31
+ * Friend method to update element (called by TrackFriend)
32
+ * @param element The element to update
33
+ * @returns true if element was updated successfully
34
+ */
35
+ updateElementViaFriend(element: TrackElement): boolean;
36
+ getId(): string;
37
+ getName(): string;
38
+ getType(): string;
39
+ getElements(): ReadonlyArray<TrackElement>;
40
+ /**
41
+ * Validates an element
42
+ * @param element The element to validate
43
+ * @returns true if valid, throws ValidationError if invalid
44
+ */
45
+ validateElement(element: TrackElement): boolean;
46
+ getTrackDuration(): number;
47
+ /**
48
+ * Adds an element to the track with validation
49
+ * @param element The element to add
50
+ * @param skipValidation If true, skips validation (use with caution)
51
+ * @returns true if element was added successfully, throws ValidationError if validation fails
52
+ */
53
+ protected addElement(element: TrackElement, skipValidation?: boolean): boolean;
54
+ protected removeElement(element: TrackElement): void;
55
+ /**
56
+ * Updates an element in the track with validation
57
+ * @param element The element to update
58
+ * @returns true if element was updated successfully, throws ValidationError if validation fails
59
+ */
60
+ protected updateElement(element: TrackElement): boolean;
61
+ getElementById(id: string): Readonly<TrackElement> | undefined;
62
+ /**
63
+ * Validates all elements in the track and returns combined result and per-element status
64
+ * @returns Object with overall isValid and array of per-element validation results
65
+ */
66
+ validateAllElements(): {
67
+ isValid: boolean;
68
+ results: Array<{
69
+ element: TrackElement;
70
+ isValid: boolean;
71
+ errors?: string[];
72
+ warnings?: string[];
73
+ }>;
74
+ };
75
+ serialize(): TrackJSON;
76
+ static fromJSON(json: any): Track;
77
+ }