@linker-design-plus/timeline-track 1.0.9 → 1.0.10

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 CHANGED
@@ -348,6 +348,12 @@ new TimelineManager(config?: Partial<TimelineConfig>)
348
348
  | `off(event, listener)` | 移除事件监听器 | `event`:事件类型,`listener`:事件监听器 | 无 |
349
349
  | `destroy()` | 销毁时间轴管理器 | 无 | 无 |
350
350
 
351
+ ### 交互事件分层规范
352
+
353
+ - 鼠标交互(时间轴拖拽、底部滑块拖拽、片段拖拽)采用统一分层策略,详见:
354
+ - `docs/interaction-model.md`
355
+ - 该文档用于约束后续重构,避免出现“移出画布中断拖拽”或“回到画布瞬移”等回归问题。
356
+
351
357
  #### 事件
352
358
 
353
359
  | 事件名 | 描述 | 数据 |
@@ -359,10 +365,13 @@ new TimelineManager(config?: Partial<TimelineConfig>)
359
365
  | `clip_removed` | 移除片段 | `{ clipId: string }` |
360
366
  | `clip_updated` | 更新片段 | `{ clip: Clip }` |
361
367
  | `clip_selected` | 选择片段 | `{ clip: Clip }` |
368
+ | `selected_clip_change` | 选中片段变化(订阅后会立即回调当前状态) | `{ clip: Clip \| null, hasSelectedClip: boolean }` |
362
369
  | `zoom_change` | 缩放比例变化 | `{ zoom: number }` |
363
370
  | `history_change` | 历史记录变更 | `{ canUndo: boolean, canRedo: boolean }` |
364
371
  | `track_duration_change` | 轨道总时长变化 | `{ duration: number }` |
365
372
  | `buffering_state_change` | 视频缓冲状态变化 | `{ isBuffering: boolean }` |
373
+ | `can_play_change` | 是否可播放状态变化 | `{ canPlay: boolean }` |
374
+ | `source_loading_change` | 视频源加载状态变化 | `{ isLoading: boolean, pending: number }` |
366
375
 
367
376
  ### ClipConfig 接口
368
377
 
@@ -18,9 +18,21 @@ export declare class Timeline {
18
18
  private isScrollbarDragging;
19
19
  private scrollbarDragStartX;
20
20
  private scrollbarDragStartScrollLeft;
21
+ private hasBoundGlobalPointerListenersForDrag;
22
+ private isPointerInsideTimeline;
23
+ private lastPointerXInTimeline;
24
+ private handleGlobalPointerMove;
25
+ private handleGlobalPointerEnd;
26
+ private handleVisibilityChange;
21
27
  private leftPadding;
22
28
  constructor(stage: Konva.Stage, gridLayer: Konva.Layer, config: Partial<TimelineConfig>, onTimeChange: (time: TimeMs) => void, onZoomChange: (zoom: number) => void, onScrollChange: (scrollLeft: number) => void);
23
29
  private initEventListeners;
30
+ private updatePointerPosition;
31
+ private bindGlobalPointerListenersForDrag;
32
+ private unbindGlobalPointerListenersForDrag;
33
+ private isPointerSessionActive;
34
+ private finalizePointerInteraction;
35
+ private handlePointerMove;
24
36
  private handleZoom;
25
37
  private animateZoom;
26
38
  private animateHorizontalScroll;
@@ -63,6 +75,14 @@ export declare class Timeline {
63
75
  * 获取网格图层
64
76
  */
65
77
  getGridLayer(): Konva.Layer;
78
+ /**
79
+ * 鼠标当前是否位于时间轴区域内
80
+ */
81
+ hasPointerInTimeline(): boolean;
82
+ /**
83
+ * 获取时间轴内最近一次鼠标 X 坐标(相对 stage)
84
+ */
85
+ getPointerXInTimeline(): number | null;
66
86
  /**
67
87
  * 调整大小
68
88
  */
@@ -21,13 +21,21 @@ export declare class VideoTrack {
21
21
  private onClipSplit;
22
22
  private onClipSelect;
23
23
  private onTimeJump;
24
+ private onAutoScrollDuringDrag?;
25
+ private dragAutoScrollOffsetPx;
26
+ private hasBoundGlobalPointerListenersForDrag;
27
+ private handleGlobalPointerMove;
28
+ private handleGlobalPointerEnd;
24
29
  constructor(layer: Konva.Layer, config: TrackConfig, zoom: number, trackY: number, trackHeight: number, theme: Theme, onClipUpdate: (clip: ClipType, originalClip?: ClipType, clipUpdates?: Array<{
25
30
  clipId: string;
26
31
  newState: any;
27
32
  previousState: any;
28
- }>) => void, onClipAdd: (clip: ClipType) => void, onClipRemove: (clipId: string) => void, onClipSplit: (clip1: ClipType, clip2: ClipType) => void, onClipSelect: (clip: ClipType) => void, onTimeJump: (time: TimeMs) => void);
33
+ }>) => void, onClipAdd: (clip: ClipType) => void, onClipRemove: (clipId: string) => void, onClipSplit: (clip1: ClipType, clip2: ClipType) => void, onClipSelect: (clip: ClipType) => void, onTimeJump: (time: TimeMs) => void, onAutoScrollDuringDrag?: (targetScrollLeft: number) => void);
29
34
  private initClips;
30
35
  private initEventListeners;
36
+ private bindGlobalPointerListenersForDrag;
37
+ private unbindGlobalPointerListenersForDrag;
38
+ private handleVisibilityChange;
31
39
  /**
32
40
  * 处理轨道背景点击事件
33
41
  */
@@ -77,6 +85,9 @@ export declare class VideoTrack {
77
85
  * 处理舞台鼠标移动事件
78
86
  */
79
87
  private handleStageMouseMove;
88
+ private isDragSessionActive;
89
+ private handleDragMove;
90
+ private maybeAutoScrollDuringDrag;
80
91
  /**
81
92
  * 处理片段鼠标离开事件
82
93
  */
@@ -22,6 +22,7 @@ export declare class TimelineManager {
22
22
  private canPlay;
23
23
  private isBuffering;
24
24
  private sourceLoadingCount;
25
+ private lastSelectedClipId;
25
26
  private playStateBeforeBuffering;
26
27
  private isPausingForBuffering;
27
28
  private videoBufferingListeners;
@@ -39,6 +40,16 @@ export declare class TimelineManager {
39
40
  * 调整 scrollLeft 使游标在屏幕上的位置保持不变
40
41
  */
41
42
  setZoomCenteredOnPlayhead(zoom: number): void;
43
+ /**
44
+ * 外部缩放入口:
45
+ * - 鼠标在时间轴内:以鼠标位置为中心缩放
46
+ * - 鼠标不在时间轴内:回退为以游标(playhead)为中心缩放
47
+ */
48
+ setZoomByInteraction(zoom: number): void;
49
+ /**
50
+ * 以时间轴上的指定像素点为中心缩放,保持该像素对应时间不变
51
+ */
52
+ setZoomCenteredOnTimelinePointer(zoom: number, pointerX: number): void;
42
53
  getZoom(): number;
43
54
  /**
44
55
  * 设置播放倍速
@@ -118,6 +129,7 @@ export declare class TimelineManager {
118
129
  private handleTimeChange;
119
130
  private handleZoomChange;
120
131
  private handleScrollChange;
132
+ private handleTrackAutoScrollRequest;
121
133
  private handleClipUpdate;
122
134
  private handleClipAdd;
123
135
  private handleClipRemove;
@@ -138,6 +150,7 @@ export declare class TimelineManager {
138
150
  on(event: TimelineEvent, listener: TimelineEventListener): void;
139
151
  off(event: TimelineEvent, listener: TimelineEventListener): void;
140
152
  private emitEvent;
153
+ private emitSelectedClipChangeIfNeeded;
141
154
  private beginSourceLoading;
142
155
  private endSourceLoading;
143
156
  getPlayState(): PlayState;
@@ -205,6 +218,7 @@ export declare class TimelineManager {
205
218
  private detachVideoBufferingListeners;
206
219
  private enterBuffering;
207
220
  private exitBuffering;
221
+ private clearBufferingStateForNoSource;
208
222
  /**
209
223
  * 检查轨道总时长是否变化,如果变化则触发事件并更新时间轴时长
210
224
  */
@@ -123,7 +123,7 @@ export interface HistoryState {
123
123
  past: Action[];
124
124
  future: Action[];
125
125
  }
126
- export type TimelineEvent = 'time_change' | 'play_state_change' | 'clip_added' | 'clip_removed' | 'clip_updated' | 'zoom_change' | 'history_change' | 'track_duration_change' | 'clip_selected' | 'speed_change' | 'can_play_change' | 'buffering_state_change' | 'source_loading_change';
126
+ export type TimelineEvent = 'time_change' | 'play_state_change' | 'clip_added' | 'clip_removed' | 'clip_updated' | 'zoom_change' | 'history_change' | 'track_duration_change' | 'clip_selected' | 'selected_clip_change' | 'speed_change' | 'can_play_change' | 'buffering_state_change' | 'source_loading_change';
127
127
  export interface TimeChangeData {
128
128
  time: TimeMs;
129
129
  }
@@ -136,6 +136,10 @@ export interface ZoomChangeData {
136
136
  export interface ClipEventData {
137
137
  clip: Clip;
138
138
  }
139
+ export interface SelectedClipChangeData {
140
+ clip: Clip | null;
141
+ hasSelectedClip: boolean;
142
+ }
139
143
  export interface ClipRemovedEventData {
140
144
  clipId: string;
141
145
  }