@linker-design-plus/timeline-track 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -2
- package/dist/components/Timeline.d.ts +15 -0
- package/dist/components/VideoTrack.d.ts +5 -0
- package/dist/core/constants.d.ts +1 -0
- package/dist/core/timelineManager.d.ts +35 -2
- package/dist/core/types.d.ts +18 -3
- package/dist/index.cjs.js +3 -3
- package/dist/index.d.ts +0 -2
- package/dist/index.es.js +1823 -1730
- package/dist/utils/KonvaUtils.d.ts +31 -24
- package/package.json +6 -1
- package/dist/core/clipManager.d.ts +0 -54
- package/dist/utils/canvasUtils.d.ts +0 -40
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
- ✅ 历史记录变更通知事件,用于外部应用调整撤销/重做按钮状态
|
|
20
20
|
- ✅ 播放倍速控制,支持 0.1x 到 10x 的播放速度
|
|
21
21
|
- ✅ 轨道总时长计算,包含片段间隙
|
|
22
|
+
- ✅ 封面系统,支持自定义缩略图提供器
|
|
23
|
+
- ✅ 异步封面加载,支持 Promise 形式的封面获取
|
|
22
24
|
|
|
23
25
|
## 安装
|
|
24
26
|
|
|
@@ -51,7 +53,8 @@ const clipId = await timelineManager.addClip({
|
|
|
51
53
|
src: 'sample-video.mp4',
|
|
52
54
|
name: 'Clip 1',
|
|
53
55
|
startTimeAtSource: 0, // 源视频中的开始时间(毫秒)
|
|
54
|
-
duration: 5000 // 片段持续时间(毫秒)
|
|
56
|
+
duration: 5000, // 片段持续时间(毫秒)
|
|
57
|
+
thumbnail: 'https://example.com/thumbnail1.jpg' // 可选:直接提供封面图片
|
|
55
58
|
});
|
|
56
59
|
|
|
57
60
|
// 开始播放
|
|
@@ -80,6 +83,44 @@ timelineManager.on('history_change', (event, data) => {
|
|
|
80
83
|
// timelineManager.destroy();
|
|
81
84
|
```
|
|
82
85
|
|
|
86
|
+
### 封面系统用法
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { TimelineManager, ThumbnailProvider } from '@linker-design-plus/timeline-track';
|
|
90
|
+
|
|
91
|
+
// 创建缩略图提供器
|
|
92
|
+
const thumbnailProvider: ThumbnailProvider = {
|
|
93
|
+
getThumbnail(clip) {
|
|
94
|
+
// 同步获取封面
|
|
95
|
+
return `https://example.com/thumbnails/${clip.id}.jpg`;
|
|
96
|
+
|
|
97
|
+
// 或异步获取封面
|
|
98
|
+
// return new Promise((resolve) => {
|
|
99
|
+
// // 模拟异步获取封面
|
|
100
|
+
// setTimeout(() => {
|
|
101
|
+
// resolve(`https://example.com/thumbnails/${clip.id}.jpg`);
|
|
102
|
+
// }, 100);
|
|
103
|
+
// });
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// 创建 TimelineManager 实例时设置缩略图提供器
|
|
108
|
+
const timelineManager = new TimelineManager({
|
|
109
|
+
container: timelineContainer,
|
|
110
|
+
thumbnailProvider: thumbnailProvider
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// 或动态设置缩略图提供器
|
|
114
|
+
timelineManager.setThumbnailProvider(thumbnailProvider);
|
|
115
|
+
|
|
116
|
+
// 添加片段时,会自动通过提供器获取封面
|
|
117
|
+
const clipId = await timelineManager.addClip({
|
|
118
|
+
src: 'sample-video.mp4',
|
|
119
|
+
name: 'Clip 1',
|
|
120
|
+
duration: 5000
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
83
124
|
### Vue 3 集成
|
|
84
125
|
|
|
85
126
|
```vue
|
|
@@ -272,6 +313,7 @@ new TimelineManager(config?: Partial<TimelineConfig>)
|
|
|
272
313
|
- `currentTime`:初始当前时间(毫秒),默认 0
|
|
273
314
|
- `playState`:初始播放状态,默认 'paused'
|
|
274
315
|
- `speed`:初始播放倍速,默认 1.0
|
|
316
|
+
- `thumbnailProvider`:缩略图提供器,用于获取片段封面
|
|
275
317
|
|
|
276
318
|
#### 核心方法
|
|
277
319
|
|
|
@@ -285,7 +327,8 @@ new TimelineManager(config?: Partial<TimelineConfig>)
|
|
|
285
327
|
| `setZoom(zoom)` | 设置缩放比例 | `zoom`:缩放比例(像素/秒) | 无 |
|
|
286
328
|
| `getZoom()` | 获取缩放比例 | 无 | `number` |
|
|
287
329
|
| `setSpeed(speed)` | 设置播放倍速 | `speed`:播放倍速 | 无 |
|
|
288
|
-
| `getSpeed()` |
|
|
330
|
+
| `getSpeed()` | 获取当前播放倍速 | 无 | `number` |
|
|
331
|
+
| `setThumbnailProvider(provider)` | 设置缩略图提供器 | `provider`:缩略图提供器 | 无 |
|
|
289
332
|
| `addClip(clipConfig)` | 添加片段 | `clipConfig`:片段配置 | `Promise<string>`(片段 ID) |
|
|
290
333
|
| `removeClip(clipId)` | 移除片段 | `clipId`:片段 ID | 无 |
|
|
291
334
|
| `removeSelectedClip()` | 移除当前选中的片段 | 无 | `boolean`(是否成功) |
|
|
@@ -15,10 +15,12 @@ export declare class Timeline {
|
|
|
15
15
|
private onScrollChange;
|
|
16
16
|
private animationFrameId;
|
|
17
17
|
private isZooming;
|
|
18
|
+
private leftPadding;
|
|
18
19
|
constructor(stage: Konva.Stage, gridLayer: Konva.Layer, config: Partial<TimelineConfig>, onTimeChange: (time: TimeMs) => void, onZoomChange: (zoom: number) => void, onScrollChange: (scrollLeft: number) => void);
|
|
19
20
|
private initEventListeners;
|
|
20
21
|
private handleZoom;
|
|
21
22
|
private animateZoom;
|
|
23
|
+
private animateHorizontalScroll;
|
|
22
24
|
private easeOutCubic;
|
|
23
25
|
private handleClick;
|
|
24
26
|
private pixelToTime;
|
|
@@ -33,6 +35,19 @@ export declare class Timeline {
|
|
|
33
35
|
getConfig(): TimelineConfig;
|
|
34
36
|
getScrollLeft(): number;
|
|
35
37
|
setScrollLeft(scrollLeft: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* 滚动到指定时间
|
|
40
|
+
* @param time 目标时间(毫秒)
|
|
41
|
+
*/
|
|
42
|
+
scrollToTime(time: TimeMs): void;
|
|
43
|
+
/**
|
|
44
|
+
* 滚动到指定片段
|
|
45
|
+
* @param clip 目标片段
|
|
46
|
+
*/
|
|
47
|
+
scrollToClip(clip: {
|
|
48
|
+
startTime: TimeMs;
|
|
49
|
+
duration: TimeMs;
|
|
50
|
+
}): void;
|
|
36
51
|
/**
|
|
37
52
|
* 获取舞台实例
|
|
38
53
|
*/
|
|
@@ -101,6 +101,11 @@ export declare class VideoTrack {
|
|
|
101
101
|
render(): void;
|
|
102
102
|
getClips(): ClipType[];
|
|
103
103
|
getSelectedClip(): ClipType | null;
|
|
104
|
+
/**
|
|
105
|
+
* 选择指定的片段
|
|
106
|
+
* @param clipId 目标片段的 ID
|
|
107
|
+
*/
|
|
108
|
+
selectClip(clipId: string): void;
|
|
104
109
|
splitSelectedClip(time: TimeMs): void;
|
|
105
110
|
/**
|
|
106
111
|
* 删除轨道内片段之间的空隙
|
package/dist/core/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TimelineConfig, Clip, ClipConfig, TimeMs, PlayState, Action, TimelineEvent, EventListener, VideoPreviewConfig, TimelineExportData } from './types';
|
|
1
|
+
import { TimelineConfig, Clip, ClipConfig, TimeMs, PlayState, Action, TimelineEvent, EventListener, VideoPreviewConfig, TimelineExportData, ThumbnailProvider } from './types';
|
|
2
2
|
|
|
3
3
|
export declare class TimelineManager {
|
|
4
4
|
private timeline;
|
|
@@ -15,9 +15,11 @@ export declare class TimelineManager {
|
|
|
15
15
|
private trackLayer;
|
|
16
16
|
private playheadLayer;
|
|
17
17
|
private selectionLayer;
|
|
18
|
+
private resizeObserver;
|
|
18
19
|
private videoPreview;
|
|
19
20
|
private isExecutingHistoryAction;
|
|
20
21
|
private lastTrackDuration;
|
|
22
|
+
private thumbnailProvider;
|
|
21
23
|
constructor(config?: Partial<TimelineConfig>);
|
|
22
24
|
init(container: HTMLElement): void;
|
|
23
25
|
play(): void;
|
|
@@ -38,9 +40,14 @@ export declare class TimelineManager {
|
|
|
38
40
|
* @returns 当前播放倍速
|
|
39
41
|
*/
|
|
40
42
|
getSpeed(): number;
|
|
43
|
+
/**
|
|
44
|
+
* 设置缩略图提供器
|
|
45
|
+
* @param provider 缩略图提供器
|
|
46
|
+
*/
|
|
47
|
+
setThumbnailProvider(provider: ThumbnailProvider): void;
|
|
41
48
|
addClip(clipConfig: ClipConfig): Promise<string>;
|
|
42
49
|
removeClip(clipId: string): void;
|
|
43
|
-
updateClip(clipId: string, updates: Partial<
|
|
50
|
+
updateClip(clipId: string, updates: Partial<Clip>): void;
|
|
44
51
|
splitClip(clipId: string, time: TimeMs): void;
|
|
45
52
|
splitCurrentClip(): void;
|
|
46
53
|
getClips(): Clip[];
|
|
@@ -72,6 +79,32 @@ export declare class TimelineManager {
|
|
|
72
79
|
getPlayState(): PlayState;
|
|
73
80
|
setDuration(duration: TimeMs): void;
|
|
74
81
|
getDuration(): TimeMs;
|
|
82
|
+
/**
|
|
83
|
+
* 调整时间轴大小以适配容器
|
|
84
|
+
* @param width 新的宽度
|
|
85
|
+
* @param height 新的高度
|
|
86
|
+
*/
|
|
87
|
+
resize(width: number, height: number): void;
|
|
88
|
+
/**
|
|
89
|
+
* 滚动到指定时间
|
|
90
|
+
* @param time 目标时间(毫秒)
|
|
91
|
+
* @param setCurrentTime 是否同时将当前时间设置为该时间点,默认为 false
|
|
92
|
+
*/
|
|
93
|
+
scrollToTime(time: TimeMs, setCurrentTime?: boolean): void;
|
|
94
|
+
/**
|
|
95
|
+
* 选择指定的片段
|
|
96
|
+
* @param clipId 目标片段的 ID
|
|
97
|
+
*/
|
|
98
|
+
selectClip(clipId: string): void;
|
|
99
|
+
/**
|
|
100
|
+
* 滚动到指定片段
|
|
101
|
+
* @param clipId 目标片段的 ID
|
|
102
|
+
* @param options 配置选项
|
|
103
|
+
*/
|
|
104
|
+
scrollToClip(clipId: string, options?: {
|
|
105
|
+
selectClip?: boolean;
|
|
106
|
+
setCurrentTime?: boolean;
|
|
107
|
+
}): void;
|
|
75
108
|
/**
|
|
76
109
|
* 获取当前时间点所在的clip
|
|
77
110
|
* @returns 当前时间点所在的clip,如果没有则返回null
|
package/dist/core/types.d.ts
CHANGED
|
@@ -6,8 +6,17 @@ export interface LogConfig {
|
|
|
6
6
|
level?: LogLevel;
|
|
7
7
|
moduleLevels?: Record<string, LogLevel>;
|
|
8
8
|
}
|
|
9
|
+
export interface ThumbnailProvider {
|
|
10
|
+
/**
|
|
11
|
+
* 获取片段的封面图片
|
|
12
|
+
* @param clip 片段对象
|
|
13
|
+
* @returns 封面图片URL、Promise<URL>或封面图片URL数组、Promise<URL数组>
|
|
14
|
+
*/
|
|
15
|
+
getThumbnails(clip: Clip): string[] | Promise<string[]>;
|
|
16
|
+
}
|
|
9
17
|
export interface ClipConfig {
|
|
10
18
|
id?: string;
|
|
19
|
+
externalId?: string;
|
|
11
20
|
src: string;
|
|
12
21
|
name: string;
|
|
13
22
|
startTime?: TimeMs;
|
|
@@ -15,11 +24,12 @@ export interface ClipConfig {
|
|
|
15
24
|
startTimeAtSource?: TimeMs;
|
|
16
25
|
endTimeAtSource?: TimeMs;
|
|
17
26
|
sourceDuration?: TimeMs;
|
|
18
|
-
|
|
27
|
+
thumbnails?: string[];
|
|
19
28
|
style?: Record<string, any>;
|
|
20
29
|
}
|
|
21
30
|
export interface Clip {
|
|
22
31
|
id: string;
|
|
32
|
+
externalId?: string;
|
|
23
33
|
src: string;
|
|
24
34
|
name: string;
|
|
25
35
|
startTime: TimeMs;
|
|
@@ -35,7 +45,7 @@ export interface Clip {
|
|
|
35
45
|
isSelected: boolean;
|
|
36
46
|
zIndex: number;
|
|
37
47
|
opacity: number;
|
|
38
|
-
|
|
48
|
+
thumbnails?: string[];
|
|
39
49
|
style?: Record<string, any>;
|
|
40
50
|
}
|
|
41
51
|
export interface TrackConfig {
|
|
@@ -57,11 +67,13 @@ export interface Theme {
|
|
|
57
67
|
clipName: string;
|
|
58
68
|
clipDuration: string;
|
|
59
69
|
clipHandle: string;
|
|
70
|
+
clipCoverBackground: string;
|
|
60
71
|
clipSelectedBackground: string;
|
|
61
72
|
clipSelectedBorder: string;
|
|
62
73
|
clipSelectedName: string;
|
|
63
74
|
clipSelectedDuration: string;
|
|
64
75
|
clipSelectedHandle: string;
|
|
76
|
+
clipSelectedCoverBackground: string;
|
|
65
77
|
playhead: string;
|
|
66
78
|
grid: string;
|
|
67
79
|
}
|
|
@@ -76,6 +88,7 @@ export interface TimelineConfig {
|
|
|
76
88
|
timeScaleHeight?: number;
|
|
77
89
|
debug?: boolean;
|
|
78
90
|
speed?: number;
|
|
91
|
+
thumbnailProvider?: ThumbnailProvider;
|
|
79
92
|
}
|
|
80
93
|
export interface VideoPreviewConfig {
|
|
81
94
|
videoElement: HTMLVideoElement;
|
|
@@ -129,6 +142,7 @@ export interface TimelineManagerConfig {
|
|
|
129
142
|
initialDuration?: TimeMs;
|
|
130
143
|
initialZoom?: number;
|
|
131
144
|
logConfig?: LogConfig;
|
|
145
|
+
thumbnailProvider?: ThumbnailProvider;
|
|
132
146
|
}
|
|
133
147
|
export interface TimelineExportData {
|
|
134
148
|
version: string;
|
|
@@ -141,6 +155,7 @@ export interface TrackExportData {
|
|
|
141
155
|
}
|
|
142
156
|
export interface ClipExportData {
|
|
143
157
|
id: string;
|
|
158
|
+
externalId?: string;
|
|
144
159
|
src: string;
|
|
145
160
|
name: string;
|
|
146
161
|
startTime: TimeMs;
|
|
@@ -149,5 +164,5 @@ export interface ClipExportData {
|
|
|
149
164
|
startTimeAtSource: TimeMs;
|
|
150
165
|
endTimeAtSource: TimeMs;
|
|
151
166
|
sourceDuration: TimeMs;
|
|
152
|
-
|
|
167
|
+
thumbnails?: string[];
|
|
153
168
|
}
|