@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.
- package/README.md +175 -0
- package/dist/context/timeline-context.d.ts +33 -0
- package/dist/context/undo-redo-context.d.ts +21 -0
- package/dist/core/addOns/animation.d.ts +24 -0
- package/dist/core/addOns/frame-effect.d.ts +14 -0
- package/dist/core/addOns/text-effect.d.ts +19 -0
- package/dist/core/editor/timeline.editor.d.ts +94 -0
- package/dist/core/elements/audio.element.d.ts +20 -0
- package/dist/core/elements/base.element.d.ts +35 -0
- package/dist/core/elements/caption.element.d.ts +10 -0
- package/dist/core/elements/circle.element.d.ts +13 -0
- package/dist/core/elements/icon.element.d.ts +9 -0
- package/dist/core/elements/image.element.d.ts +32 -0
- package/dist/core/elements/rect.element.d.ts +11 -0
- package/dist/core/elements/text.element.d.ts +26 -0
- package/dist/core/elements/video.element.d.ts +41 -0
- package/dist/core/track/track.d.ts +77 -0
- package/dist/core/track/track.friend.d.ts +34 -0
- package/dist/core/visitor/element-adder.d.ts +29 -0
- package/dist/core/visitor/element-cloner.d.ts +22 -0
- package/dist/core/visitor/element-deserializer.d.ts +23 -0
- package/dist/core/visitor/element-remover.d.ts +28 -0
- package/dist/core/visitor/element-serializer.d.ts +23 -0
- package/dist/core/visitor/element-splitter.d.ts +28 -0
- package/dist/core/visitor/element-updater.d.ts +28 -0
- package/dist/core/visitor/element-validator.d.ts +34 -0
- package/dist/core/visitor/element-visitor.d.ts +19 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +2630 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2628 -0
- package/dist/index.mjs.map +1 -0
- package/dist/services/data.service.d.ts +25 -0
- package/dist/types/index.d.ts +169 -0
- package/dist/utils/constants.d.ts +55 -0
- package/dist/utils/register-editor.d.ts +8 -0
- package/dist/utils/timeline.utils.d.ts +11 -0
- 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
|
+
}
|