@keplar-404/react-timeline-editor 1.0.6
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/dist/components/control_area/index.d.ts +0 -0
- package/dist/components/cursor/cursor.d.ts +20 -0
- package/dist/components/cut-overlay/CutOverlay.d.ts +202 -0
- package/dist/components/edit_area/cross_row_drag.d.ts +50 -0
- package/dist/components/edit_area/drag_lines.d.ts +11 -0
- package/dist/components/edit_area/drag_preview.d.ts +14 -0
- package/dist/components/edit_area/drag_utils.d.ts +39 -0
- package/dist/components/edit_area/edit_action.d.ts +19 -0
- package/dist/components/edit_area/edit_area.d.ts +56 -0
- package/dist/components/edit_area/edit_row.d.ts +27 -0
- package/dist/components/edit_area/hooks/use_drag_line.d.ts +33 -0
- package/dist/components/edit_area/insertion_line.d.ts +12 -0
- package/dist/components/loop-zone/LoopZoneOverlay.d.ts +243 -0
- package/dist/components/row_rnd/hooks/useAutoScroll.d.ts +7 -0
- package/dist/components/row_rnd/interactable.d.ts +14 -0
- package/dist/components/row_rnd/row_rnd.d.ts +3 -0
- package/dist/components/row_rnd/row_rnd_interface.d.ts +47 -0
- package/dist/components/time_area/time_area.d.ts +17 -0
- package/dist/components/timeline.d.ts +3 -0
- package/dist/components/transport/TransportBar.d.ts +132 -0
- package/dist/components/transport/useTimelinePlayer.d.ts +164 -0
- package/dist/index.cjs.js +13 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.es.js +10102 -0
- package/dist/index.umd.js +13 -0
- package/dist/interface/common_prop.d.ts +12 -0
- package/dist/interface/const.d.ts +28 -0
- package/dist/interface/timeline.d.ts +342 -0
- package/dist/react-timeline-editor.css +1 -0
- package/dist/utils/check_props.d.ts +2 -0
- package/dist/utils/deal_class_prefix.d.ts +1 -0
- package/dist/utils/deal_data.d.ts +58 -0
- package/dist/utils/logger.d.ts +132 -0
- package/package.json +70 -0
- package/src/components/control_area/index.tsx +1 -0
- package/src/components/cursor/cursor.css +26 -0
- package/src/components/cursor/cursor.tsx +105 -0
- package/src/components/cut-overlay/CutOverlay.css +68 -0
- package/src/components/cut-overlay/CutOverlay.tsx +491 -0
- package/src/components/edit_area/cross_row_drag.tsx +174 -0
- package/src/components/edit_area/drag_lines.css +13 -0
- package/src/components/edit_area/drag_lines.tsx +31 -0
- package/src/components/edit_area/drag_preview.tsx +50 -0
- package/src/components/edit_area/drag_utils.ts +77 -0
- package/src/components/edit_area/edit_action.css +56 -0
- package/src/components/edit_area/edit_action.tsx +362 -0
- package/src/components/edit_area/edit_area.css +24 -0
- package/src/components/edit_area/edit_area.tsx +606 -0
- package/src/components/edit_area/edit_row.css +78 -0
- package/src/components/edit_area/edit_row.tsx +128 -0
- package/src/components/edit_area/hooks/use_drag_line.ts +93 -0
- package/src/components/edit_area/insertion_line.tsx +39 -0
- package/src/components/loop-zone/LoopZoneOverlay.css +65 -0
- package/src/components/loop-zone/LoopZoneOverlay.tsx +461 -0
- package/src/components/row_rnd/hooks/useAutoScroll.ts +81 -0
- package/src/components/row_rnd/interactable.tsx +55 -0
- package/src/components/row_rnd/row_rnd.tsx +365 -0
- package/src/components/row_rnd/row_rnd_interface.ts +59 -0
- package/src/components/time_area/time_area.css +35 -0
- package/src/components/time_area/time_area.tsx +93 -0
- package/src/components/timeline.css +12 -0
- package/src/components/timeline.tsx +227 -0
- package/src/components/transport/TransportBar.css +171 -0
- package/src/components/transport/TransportBar.tsx +322 -0
- package/src/components/transport/useTimelinePlayer.ts +319 -0
- package/src/index.tsx +17 -0
- package/src/interface/common_prop.ts +13 -0
- package/src/interface/const.ts +32 -0
- package/src/interface/timeline.ts +329 -0
- package/src/utils/check_props.ts +77 -0
- package/src/utils/deal_class_prefix.ts +6 -0
- package/src/utils/deal_data.ts +159 -0
- package/src/utils/logger.ts +239 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RequiredEditData } from './timeline';
|
|
2
|
+
/** Common component parameters */
|
|
3
|
+
export interface CommonProp extends RequiredEditData {
|
|
4
|
+
/** Scale count */
|
|
5
|
+
scaleCount: number;
|
|
6
|
+
/** Set scale count */
|
|
7
|
+
setScaleCount: (scaleCount: number) => void;
|
|
8
|
+
/** Cursor time */
|
|
9
|
+
cursorTime: number;
|
|
10
|
+
/** Current timeline width */
|
|
11
|
+
timelineWidth: number;
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const PREFIX = "timeline-editor";
|
|
2
|
+
/** Cursor time at start */
|
|
3
|
+
export declare const START_CURSOR_TIME = 0;
|
|
4
|
+
/** Default scale */
|
|
5
|
+
export declare const DEFAULT_SCALE = 1;
|
|
6
|
+
/** Default scale split count */
|
|
7
|
+
export declare const DEFAULT_SCALE_SPLIT_COUNT = 10;
|
|
8
|
+
/** Default scale display width */
|
|
9
|
+
export declare const DEFAULT_SCALE_WIDTH = 160;
|
|
10
|
+
/** Default scale start distance from left */
|
|
11
|
+
export declare const DEFAULT_START_LEFT = 20;
|
|
12
|
+
/** Default minimum movement in pixels */
|
|
13
|
+
export declare const DEFAULT_MOVE_GRID = 1;
|
|
14
|
+
/** Default adsorption distance in pixels */
|
|
15
|
+
export declare const DEFAULT_ADSORPTION_DISTANCE = 8;
|
|
16
|
+
/** Default action row height */
|
|
17
|
+
export declare const DEFAULT_ROW_HEIGHT = 32;
|
|
18
|
+
/** Minimum scale count */
|
|
19
|
+
export declare const MIN_SCALE_COUNT = 20;
|
|
20
|
+
/** Maximum scale count */
|
|
21
|
+
export declare const MAX_SCALE_COUNT: number;
|
|
22
|
+
/** Number of scale marks to add each time */
|
|
23
|
+
export declare const ADD_SCALE_COUNT = 5;
|
|
24
|
+
/** Error messages */
|
|
25
|
+
export declare const ERROR: {
|
|
26
|
+
START_TIME_LESS_THEN_ZERO: string;
|
|
27
|
+
END_TIME_LESS_THEN_START_TIME: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { Emitter, EventTypes, ITimelineEngine, TimelineAction, TimelineRow, TimelineEffect } from '@keplar-404/timeline-engine';
|
|
2
|
+
import { default as React, ReactNode } from 'react';
|
|
3
|
+
import { OnScrollParams } from 'react-virtualized';
|
|
4
|
+
export interface EditData {
|
|
5
|
+
/**
|
|
6
|
+
* @description Timeline editing data
|
|
7
|
+
*/
|
|
8
|
+
editorData: TimelineRow[];
|
|
9
|
+
/**
|
|
10
|
+
* @description Timeline action effect map
|
|
11
|
+
*/
|
|
12
|
+
effects: Record<string, TimelineEffect>;
|
|
13
|
+
/**
|
|
14
|
+
* @description Scaling factor for individual scale marks (>0)
|
|
15
|
+
* @default 1
|
|
16
|
+
*/
|
|
17
|
+
scale?: number;
|
|
18
|
+
/**
|
|
19
|
+
* @description Minimum number of scale marks (>=1)
|
|
20
|
+
* @default 20
|
|
21
|
+
*/
|
|
22
|
+
minScaleCount?: number;
|
|
23
|
+
/**
|
|
24
|
+
* @description Maximum number of scale marks (>=minScaleCount)
|
|
25
|
+
* @default Infinity
|
|
26
|
+
*/
|
|
27
|
+
maxScaleCount?: number;
|
|
28
|
+
/**
|
|
29
|
+
* @description Number of subdivision units for a single scale mark (integer >0)
|
|
30
|
+
* @default 10
|
|
31
|
+
*/
|
|
32
|
+
scaleSplitCount?: number;
|
|
33
|
+
/**
|
|
34
|
+
* @description Display width of a single scale mark (>0, unit: px)
|
|
35
|
+
* @default 160
|
|
36
|
+
*/
|
|
37
|
+
scaleWidth?: number;
|
|
38
|
+
/**
|
|
39
|
+
* @description Distance from the start of the scale to the left edge (>=0, unit: px)
|
|
40
|
+
* @default 20
|
|
41
|
+
*/
|
|
42
|
+
startLeft?: number;
|
|
43
|
+
/**
|
|
44
|
+
* @description Default height for each editing row (>0, unit: px)
|
|
45
|
+
* @default 32
|
|
46
|
+
*/
|
|
47
|
+
rowHeight?: number;
|
|
48
|
+
/**
|
|
49
|
+
* @description Whether to enable grid movement snapping
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
gridSnap?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* @description Enable snapping to drag auxiliary lines
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
dragLine?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* @description Whether to hide the cursor
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
hideCursor?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* @description Prevent dragging in all action areas
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
disableDrag?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* @description Prevent dragging of all rows
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
enableRowDrag?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* @description Enable dragging action blocks between different rows
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
enableCrossRowDrag?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* @description Show a ghost/preview element following the cursor during cross-row block drag.
|
|
80
|
+
* Set to `false` to disable the ghost entirely, or use `getGhostPreview` for a custom component.
|
|
81
|
+
* @default true
|
|
82
|
+
*/
|
|
83
|
+
enableGhostPreview?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* @description Custom render function for the drag ghost/preview element shown while
|
|
86
|
+
* dragging a block across rows. When provided, replaces the default blue glowing box.
|
|
87
|
+
*
|
|
88
|
+
* The function receives the action being dragged and its source row, so you can
|
|
89
|
+
* render a fully custom preview that matches your block's actual appearance.
|
|
90
|
+
*
|
|
91
|
+
* @param params - The action being dragged and the row it originated from
|
|
92
|
+
* @returns A React node to render inside the ghost container
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```tsx
|
|
96
|
+
* <Timeline
|
|
97
|
+
* enableCrossRowDrag
|
|
98
|
+
* getGhostPreview={({ action, row }) => (
|
|
99
|
+
* <div style={{ background: '#1a3a5c', border: '2px solid #3b82f6', height: '100%', borderRadius: 4, padding: '0 8px', display: 'flex', alignItems: 'center' }}>
|
|
100
|
+
* <span style={{ color: '#3b82f6', fontSize: 12 }}>{action.id}</span>
|
|
101
|
+
* </div>
|
|
102
|
+
* )}
|
|
103
|
+
* />
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
getGhostPreview?: (params: {
|
|
107
|
+
action: TimelineAction;
|
|
108
|
+
row: TimelineRow;
|
|
109
|
+
}) => ReactNode;
|
|
110
|
+
/**
|
|
111
|
+
* @description Timeline engine; uses the built-in engine if not provided
|
|
112
|
+
*/
|
|
113
|
+
engine?: ITimelineEngine;
|
|
114
|
+
/**
|
|
115
|
+
* @description Custom action area rendering
|
|
116
|
+
*/
|
|
117
|
+
getActionRender?: (action: TimelineAction, row: TimelineRow) => ReactNode;
|
|
118
|
+
/**
|
|
119
|
+
* @description Custom scale rendering
|
|
120
|
+
*/
|
|
121
|
+
getScaleRender?: (scale: number) => ReactNode;
|
|
122
|
+
/**
|
|
123
|
+
* @description Callback when movement starts
|
|
124
|
+
*/
|
|
125
|
+
onActionMoveStart?: (params: {
|
|
126
|
+
action: TimelineAction;
|
|
127
|
+
row: TimelineRow;
|
|
128
|
+
}) => void;
|
|
129
|
+
/**
|
|
130
|
+
* @description Movement callback (return false to prevent movement)
|
|
131
|
+
*/
|
|
132
|
+
onActionMoving?: (params: {
|
|
133
|
+
action: TimelineAction;
|
|
134
|
+
row: TimelineRow;
|
|
135
|
+
start: number;
|
|
136
|
+
end: number;
|
|
137
|
+
}) => void | boolean;
|
|
138
|
+
/**
|
|
139
|
+
* @description Movement end callback (return false to prevent onChange from triggering)
|
|
140
|
+
*/
|
|
141
|
+
onActionMoveEnd?: (params: {
|
|
142
|
+
action: TimelineAction;
|
|
143
|
+
row: TimelineRow;
|
|
144
|
+
start: number;
|
|
145
|
+
end: number;
|
|
146
|
+
}) => void;
|
|
147
|
+
/**
|
|
148
|
+
* @description Callback when resizing starts
|
|
149
|
+
*/
|
|
150
|
+
onActionResizeStart?: (params: {
|
|
151
|
+
action: TimelineAction;
|
|
152
|
+
row: TimelineRow;
|
|
153
|
+
dir: 'right' | 'left';
|
|
154
|
+
}) => void;
|
|
155
|
+
/**
|
|
156
|
+
* @description Resizing callback (return false to prevent change)
|
|
157
|
+
*/
|
|
158
|
+
onActionResizing?: (params: {
|
|
159
|
+
action: TimelineAction;
|
|
160
|
+
row: TimelineRow;
|
|
161
|
+
start: number;
|
|
162
|
+
end: number;
|
|
163
|
+
dir: 'right' | 'left';
|
|
164
|
+
}) => void | boolean;
|
|
165
|
+
/**
|
|
166
|
+
* @description Callback when resizing ends (return false to prevent onChange from triggering)
|
|
167
|
+
*/
|
|
168
|
+
onActionResizeEnd?: (params: {
|
|
169
|
+
action: TimelineAction;
|
|
170
|
+
row: TimelineRow;
|
|
171
|
+
start: number;
|
|
172
|
+
end: number;
|
|
173
|
+
dir: 'right' | 'left';
|
|
174
|
+
}) => void;
|
|
175
|
+
/**
|
|
176
|
+
* @description Callback when a row is clicked
|
|
177
|
+
*/
|
|
178
|
+
onClickRow?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
179
|
+
row: TimelineRow;
|
|
180
|
+
time: number;
|
|
181
|
+
}) => void;
|
|
182
|
+
/**
|
|
183
|
+
* @description Callback when an action is clicked
|
|
184
|
+
*/
|
|
185
|
+
onClickAction?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
186
|
+
action: TimelineAction;
|
|
187
|
+
row: TimelineRow;
|
|
188
|
+
time: number;
|
|
189
|
+
}) => void;
|
|
190
|
+
/**
|
|
191
|
+
* @description Callback when an action is clicked (not executed when drag is triggered)
|
|
192
|
+
*/
|
|
193
|
+
onClickActionOnly?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
194
|
+
action: TimelineAction;
|
|
195
|
+
row: TimelineRow;
|
|
196
|
+
time: number;
|
|
197
|
+
}) => void;
|
|
198
|
+
/**
|
|
199
|
+
* @description Callback when a row is double-clicked
|
|
200
|
+
*/
|
|
201
|
+
onDoubleClickRow?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
202
|
+
row: TimelineRow;
|
|
203
|
+
time: number;
|
|
204
|
+
}) => void;
|
|
205
|
+
/**
|
|
206
|
+
* @description Callback when an action is double-clicked
|
|
207
|
+
*/
|
|
208
|
+
onDoubleClickAction?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
209
|
+
action: TimelineAction;
|
|
210
|
+
row: TimelineRow;
|
|
211
|
+
time: number;
|
|
212
|
+
}) => void;
|
|
213
|
+
/**
|
|
214
|
+
* @description Callback when a row is right-clicked
|
|
215
|
+
*/
|
|
216
|
+
onContextMenuRow?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
217
|
+
row: TimelineRow;
|
|
218
|
+
time: number;
|
|
219
|
+
}) => void;
|
|
220
|
+
/**
|
|
221
|
+
* @description Callback when an action is right-clicked
|
|
222
|
+
*/
|
|
223
|
+
onContextMenuAction?: (e: React.MouseEvent<HTMLElement, MouseEvent>, param: {
|
|
224
|
+
action: TimelineAction;
|
|
225
|
+
row: TimelineRow;
|
|
226
|
+
time: number;
|
|
227
|
+
}) => void;
|
|
228
|
+
/**
|
|
229
|
+
* @description Get a list of action IDs for auxiliary lines, calculated at move/resize start; defaults to all except the current moving action
|
|
230
|
+
*/
|
|
231
|
+
getAssistDragLineActionIds?: (params: {
|
|
232
|
+
action: TimelineAction;
|
|
233
|
+
editorData: TimelineRow[];
|
|
234
|
+
row: TimelineRow;
|
|
235
|
+
}) => string[];
|
|
236
|
+
/**
|
|
237
|
+
* @description Cursor start drag event
|
|
238
|
+
*/
|
|
239
|
+
onCursorDragStart?: (time: number) => void;
|
|
240
|
+
/**
|
|
241
|
+
* @description Cursor end drag event
|
|
242
|
+
*/
|
|
243
|
+
onCursorDragEnd?: (time: number) => void;
|
|
244
|
+
/**
|
|
245
|
+
* @description Cursor drag event
|
|
246
|
+
*/
|
|
247
|
+
onCursorDrag?: (time: number) => void;
|
|
248
|
+
/**
|
|
249
|
+
* @description Click on time area event; return false to prevent setting time
|
|
250
|
+
*/
|
|
251
|
+
onClickTimeArea?: (time: number, e: React.MouseEvent<HTMLDivElement, MouseEvent>) => boolean | undefined;
|
|
252
|
+
/**
|
|
253
|
+
* @description Row drag start callback
|
|
254
|
+
* @param params row is the data of the row being dragged
|
|
255
|
+
*/
|
|
256
|
+
onRowDragStart?: (params: {
|
|
257
|
+
row: TimelineRow;
|
|
258
|
+
}) => void;
|
|
259
|
+
/**
|
|
260
|
+
* @description Row drag end callback
|
|
261
|
+
* @param params row is the data of the row being dragged; editorData is the new data arrangement after the row is dragged
|
|
262
|
+
* @returns
|
|
263
|
+
*/
|
|
264
|
+
onRowDragEnd?: (params: {
|
|
265
|
+
row: TimelineRow;
|
|
266
|
+
editorData: TimelineRow[];
|
|
267
|
+
}) => void;
|
|
268
|
+
}
|
|
269
|
+
export interface TimelineState {
|
|
270
|
+
/** DOM node */
|
|
271
|
+
target: HTMLElement | null;
|
|
272
|
+
/** Execution listener */
|
|
273
|
+
listener: Emitter<EventTypes>;
|
|
274
|
+
/** Whether it is playing */
|
|
275
|
+
isPlaying: boolean;
|
|
276
|
+
/** Whether it is paused */
|
|
277
|
+
isPaused: boolean;
|
|
278
|
+
/** Set current playback time */
|
|
279
|
+
setTime: (time: number) => void;
|
|
280
|
+
/** Get current playback time */
|
|
281
|
+
getTime: () => number;
|
|
282
|
+
/** Set playback rate */
|
|
283
|
+
setPlayRate: (rate: number) => void;
|
|
284
|
+
/** Get playback rate */
|
|
285
|
+
getPlayRate: () => number;
|
|
286
|
+
/** Re-render current time */
|
|
287
|
+
reRender: () => void;
|
|
288
|
+
/** Play */
|
|
289
|
+
play: (param: {
|
|
290
|
+
/** Default run from start to end, priority greater than autoEnd */
|
|
291
|
+
toTime?: number;
|
|
292
|
+
/** Whether it is automatically end after playback */
|
|
293
|
+
autoEnd?: boolean;
|
|
294
|
+
/** List of actionIds to run; runs all by default if not provided */
|
|
295
|
+
runActionIds?: string[];
|
|
296
|
+
}) => boolean;
|
|
297
|
+
/** Pause */
|
|
298
|
+
pause: () => void;
|
|
299
|
+
/** Set scroll left */
|
|
300
|
+
setScrollLeft: (val: number) => void;
|
|
301
|
+
/** Set scroll top */
|
|
302
|
+
setScrollTop: (val: number) => void;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Animation editor parameters
|
|
306
|
+
* @export
|
|
307
|
+
* @interface TimelineProp
|
|
308
|
+
*/
|
|
309
|
+
export interface TimelineEditor extends EditData {
|
|
310
|
+
/**
|
|
311
|
+
* @description Scroll distance of the editing area from the top (please use ref.setScrollTop instead)
|
|
312
|
+
* @deprecated
|
|
313
|
+
*/
|
|
314
|
+
scrollTop?: number;
|
|
315
|
+
/**
|
|
316
|
+
* @description Scroll callback for the editing area (used to control synchronization with scroll of editing rows)
|
|
317
|
+
*/
|
|
318
|
+
onScroll?: (params: OnScrollParams) => void;
|
|
319
|
+
/**
|
|
320
|
+
* @description Whether to enable automatic scrolling during dragging
|
|
321
|
+
* @default false
|
|
322
|
+
*/
|
|
323
|
+
autoScroll?: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* @description Custom timeline style
|
|
326
|
+
*/
|
|
327
|
+
style?: React.CSSProperties;
|
|
328
|
+
/**
|
|
329
|
+
* @description Whether to re-render automatically (update tick when data changes or cursor time changes)
|
|
330
|
+
* @default true
|
|
331
|
+
*/
|
|
332
|
+
autoReRender?: boolean;
|
|
333
|
+
/**
|
|
334
|
+
* @description Data change callback, triggered after the end of an action operation changes data (returning false will prevent automatic engine synchronization, used to reduce performance overhead)
|
|
335
|
+
*/
|
|
336
|
+
onChange?: (editorData: TimelineRow[]) => void | boolean;
|
|
337
|
+
}
|
|
338
|
+
export type RequiredPick<T, K extends keyof T> = T & {
|
|
339
|
+
[P in K]-?: T[P];
|
|
340
|
+
};
|
|
341
|
+
export type RequiredEditData = RequiredPick<EditData, 'editorData' | 'effects' | 'scale' | 'scaleSplitCount' | 'scaleWidth' | 'startLeft' | 'minScaleCount' | 'maxScaleCount' | 'rowHeight'>;
|
|
342
|
+
export type RequiredTimelineEditor = RequiredPick<TimelineEditor, 'scrollTop'> & RequiredEditData;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.timeline-editor-cursor{cursor:ew-resize;position:absolute;top:32px;height:calc(100% - 32px);box-sizing:border-box;border-left:1px solid #5297FF;border-right:1px solid #5297FF;transform:translate(-25%) scaleX(.5)}.timeline-editor-cursor-top{position:absolute;top:0;left:50%;transform:translate(-50%) scaleX(2);margin:auto}.timeline-editor-cursor-area{width:16px;height:100%;cursor:ew-resize;position:absolute;top:0;left:50%;transform:translate(-50%)}.timeline-editor-drag-line-container{position:absolute;height:100%;top:0;left:0}.timeline-editor-drag-line{width:0;position:absolute;top:0;height:99%;border-left:1px dashed rgba(82,151,255,.6)}.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar{height:4px}.timeline-editor-edit-area{flex:1 1 auto;margin-top:10px;overflow:hidden;position:relative}.timeline-editor-edit-area .ReactVirtualized__Grid{outline:none!important;overflow:overlay!important}.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar{width:0;height:0}.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track{background-color:transparent!important}.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb{background:#313132;border-radius:16px}.timeline-editor-action{position:absolute;left:0;top:0;background-color:#2f3134;cursor:default;transition:box-shadow .15s ease}.timeline-editor-action.action-cross-row-dragging{box-shadow:0 0 0 2px #63b3edcc,0 0 16px #63b3ed99,0 0 32px #63b3ed4d;opacity:.75;z-index:10}.timeline-editor-action.action-movable{cursor:move}.timeline-editor-action .timeline-editor-action-left-stretch,.timeline-editor-action .timeline-editor-action-right-stretch{position:absolute;top:0;width:10px;border-radius:4px;height:100%;overflow:hidden}.timeline-editor-action .timeline-editor-action-left-stretch:after,.timeline-editor-action .timeline-editor-action-right-stretch:after{position:absolute;top:0;bottom:0;margin:auto;border-radius:4px;border-top:28px solid transparent;border-bottom:28px solid transparent}.timeline-editor-action .timeline-editor-action-left-stretch{left:0;cursor:w-resize}.timeline-editor-action .timeline-editor-action-left-stretch:after{left:0;content:"";border-left:7px solid rgba(255,255,255,.1);border-right:7px solid transparent}.timeline-editor-action .timeline-editor-action-right-stretch{right:0;cursor:e-resize}.timeline-editor-action .timeline-editor-action-right-stretch:after{right:0;content:"";border-right:7px solid rgba(255,255,255,.1);border-left:7px solid transparent}.timeline-editor-edit-row-dragging{opacity:.5}.timeline-editor-edit-row{background-repeat:no-repeat,repeat;background-image:linear-gradient(#191b1d,#191b1d),linear-gradient(90deg,rgba(255,255,255,.08) 1px,transparent 0);display:flex;flex-direction:row;box-sizing:border-box;position:relative;transition:opacity .2s ease,transform .2s ease}.timeline-editor-edit-row-drag-handle{position:absolute;left:4px;top:50%;transform:translateY(-50%);width:16px;height:16px;cursor:grab;display:flex;align-items:center;justify-content:center;color:#666;font-size:12px;-webkit-user-select:none;user-select:none;z-index:10;opacity:.6;transition:opacity .2s ease}.timeline-editor-edit-row-drag-handle:hover{opacity:1;color:#999}.timeline-editor-edit-row-drag-handle:active{cursor:grabbing}.timeline-editor-edit-row-dragged{opacity:.5;transform:scale(.98);pointer-events:none;z-index:1000;position:relative}.timeline-editor-edit-row-dragging{cursor:grabbing}.timeline-editor-edit-row-placeholder{background:#4a90e21a;border:2px dashed #4a90e2;height:4px;min-height:4px;margin:2px 0;opacity:.8}.timeline-editor-edit-row-placeholder .timeline-editor-edit-row-drag-handle,.timeline-editor-edit-row-placeholder .timeline-editor-edit-action{display:none}.timeline-editor-edit-row:before{content:"";position:absolute;left:0;right:0;height:2px;background:#4a90e2;z-index:100;opacity:0;transition:opacity .2s ease}.timeline-editor-edit-row[data-insert-position=top]:before{top:-1px;opacity:1}.timeline-editor-edit-row[data-insert-position=bottom]:before{bottom:-1px;opacity:1}.timeline-editor-time-area{position:relative;height:32px;flex:0 0 auto}.timeline-editor-time-area .ReactVirtualized__Grid{outline:none}.timeline-editor-time-area .ReactVirtualized__Grid::-webkit-scrollbar{display:none}.timeline-editor-time-area-interact{position:absolute;cursor:pointer;left:0;top:0}.timeline-editor-time-unit{border-right:1px solid rgba(255,255,255,.2);position:relative;box-sizing:content-box;height:4px!important;bottom:0!important;top:auto!important}.timeline-editor-time-unit-big{height:8px!important}.timeline-editor-time-unit-scale{color:#fff9;position:absolute;right:0;top:0;transform:translate(50%,-100%)}.timeline-editor{height:600px;width:600px;min-height:32px;position:relative;font-size:12px;font-family:PingFang SC;background-color:#191b1d;display:flex;flex-direction:column;overflow:hidden}.cut-overlay{position:absolute;inset:0;z-index:20;pointer-events:auto;-webkit-user-select:none;user-select:none}.cut-block-clip{position:absolute;pointer-events:none;border-radius:3px;box-sizing:border-box;overflow:visible}.cut-blade{position:absolute;top:0;width:2px;height:100%;transform:translate(-50%);border-radius:1px;pointer-events:none;z-index:2;animation:cut-blade-in .1s ease-out}@keyframes cut-blade-in{0%{opacity:0;transform:translate(-50%) scaleY(.3)}to{opacity:1;transform:translate(-50%) scaleY(1)}}.cut-pill{position:absolute;bottom:calc(100% + 5px);transform:translate(-50%);font-size:10px;font-weight:700;font-family:SF Mono,Cascadia Code,Fira Code,monospace;letter-spacing:.04em;padding:2px 7px;border-radius:4px;white-space:nowrap;pointer-events:none;animation:cut-pill-in .1s ease-out;z-index:25}@keyframes cut-pill-in{0%{opacity:0;transform:translate(-50%) translateY(4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.loop-zone-overlay{position:absolute;top:0;left:0;right:0;height:100%;pointer-events:none;z-index:4;overflow:visible}.loop-zone-band{position:absolute;top:0;height:100%;pointer-events:none;border-left:1px solid transparent;border-right:1px solid transparent;border-top:2px solid transparent}.loop-zone-handle{position:absolute;top:0;height:100%;transform:translate(-50%);pointer-events:none;-webkit-user-select:none;user-select:none}.loop-zone-handle__line{position:absolute;top:32px;bottom:0;left:50%;transform:translate(-50%);width:1px;pointer-events:none;border-left:1px dashed transparent;background:currentColor;opacity:.5}.loop-zone-handle__grip{position:absolute;top:6px;left:50%;transform:translate(-50%);pointer-events:auto;cursor:ew-resize;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:center;padding:5px 7px;border-radius:5px;transition:filter .12s,transform .1s}.loop-zone-handle__grip:hover{filter:brightness(1.2);transform:translate(-50%) scaleY(1.1)}.loop-zone-handle__grip:active{transform:translate(-50%) scale(.94)}.loop-zone-handle__grip svg{display:block;flex-shrink:0}.timeline-transport-bar{display:flex;align-items:center;justify-content:space-between;padding:0 16px;height:48px;background:#0a0a14d9;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,.06);gap:16px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Inter,Segoe UI,sans-serif}.timeline-transport-controls{display:flex;align-items:center;gap:4px}.timeline-transport-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:6px;border:1px solid rgba(255,255,255,.07);background:#ffffff08;color:#64748b;cursor:pointer;transition:background .12s,color .12s,border-color .12s}.timeline-transport-btn:hover{background:#ffffff14;color:#94a3b8;border-color:#ffffff1f}.timeline-transport-btn--primary{color:#c4c9d4}.timeline-transport-btn--primary:hover{background:#ffffff1a;color:#e2e8f0}.timeline-transport-btn--stop:hover{background:#ef44441f;border-color:#ef44444d;color:#ef4444}.timeline-transport-btn--loop{font-size:14px;line-height:1;width:auto;padding:0 6px;color:#4b5563}.timeline-transport-btn--loop:hover{background:#10b9811a;border-color:#10b9814d;color:#10b981}.timeline-transport-btn--loop-active{background:#10b9812e!important;border-color:#10b98180!important;color:#10b981!important;box-shadow:0 0 10px #10b98140!important}.timeline-transport-divider{width:1px;height:20px;background:#ffffff14;margin:0 4px;flex-shrink:0}.timeline-transport-loop-inputs{display:flex;align-items:center;gap:4px;margin-left:4px}.timeline-transport-loop-input{width:52px;background:#00000059;border:1px solid rgba(16,185,129,.3);border-radius:5px;color:#10b981;font-size:12px;font-family:SF Mono,Cascadia Code,Fira Code,monospace;font-weight:600;padding:2px 6px;text-align:center;outline:none;transition:border-color .12s}.timeline-transport-loop-input:focus{border-color:#10b981b3;box-shadow:0 0 6px #10b98133}.timeline-transport-loop-input::-webkit-inner-spin-button,.timeline-transport-loop-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.timeline-transport-loop-arrow{font-size:11px;color:#334155}.timeline-transport-loop-unit{font-size:10px;color:#334155;font-family:SF Mono,Cascadia Code,monospace}.timeline-transport-time{display:flex;flex-direction:column;align-items:center;gap:1px;min-width:100px}.timeline-transport-time-value{font-size:22px;font-weight:700;font-family:SF Mono,Cascadia Code,Fira Code,monospace;color:#e2e8f0;letter-spacing:.05em;line-height:1}.timeline-transport-time-label{font-size:9px;font-weight:600;letter-spacing:.15em;color:#475569;text-transform:uppercase}.timeline-transport-rate{display:flex;align-items:center;gap:8px}.timeline-transport-rate-label{font-size:9px;font-weight:600;letter-spacing:.15em;color:#475569;text-transform:uppercase}.timeline-transport-rate-buttons{display:flex;gap:3px}.timeline-transport-rate-btn{padding:3px 8px;border-radius:5px;border:1px solid rgba(255,255,255,.07);background:#ffffff08;color:#475569;font-size:11px;font-weight:600;font-family:SF Mono,Cascadia Code,monospace;cursor:pointer;transition:all .12s}.timeline-transport-rate-btn:hover{background:#ffffff12;color:#94a3b8}.timeline-transport-rate-btn--active{background:#3b82f626;border-color:#3b82f666;color:#3b82f6;box-shadow:0 0 6px #3b82f626}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function prefix(...classNames: string[]): string;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { TimelineAction, TimelineRow } from '@keplar-404/timeline-engine';
|
|
2
|
+
/** Time to pixel */
|
|
3
|
+
export declare function parserTimeToPixel(data: number, param: {
|
|
4
|
+
startLeft: number;
|
|
5
|
+
scale: number;
|
|
6
|
+
scaleWidth: number;
|
|
7
|
+
}): number;
|
|
8
|
+
/** Pixel to time */
|
|
9
|
+
export declare function parserPixelToTime(data: number, param: {
|
|
10
|
+
startLeft: number;
|
|
11
|
+
scale: number;
|
|
12
|
+
scaleWidth: number;
|
|
13
|
+
}): number;
|
|
14
|
+
/** Position + Width to Start + End */
|
|
15
|
+
export declare function parserTransformToTime(data: {
|
|
16
|
+
left: number;
|
|
17
|
+
width: number;
|
|
18
|
+
}, param: {
|
|
19
|
+
startLeft: number;
|
|
20
|
+
scale: number;
|
|
21
|
+
scaleWidth: number;
|
|
22
|
+
}): {
|
|
23
|
+
start: number;
|
|
24
|
+
end: number;
|
|
25
|
+
};
|
|
26
|
+
/** Start + End to Position + Width */
|
|
27
|
+
export declare function parserTimeToTransform(data: {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
}, param: {
|
|
31
|
+
startLeft: number;
|
|
32
|
+
scale: number;
|
|
33
|
+
scaleWidth: number;
|
|
34
|
+
}): {
|
|
35
|
+
left: number;
|
|
36
|
+
width: number;
|
|
37
|
+
};
|
|
38
|
+
/** Get number of scale marks based on data */
|
|
39
|
+
export declare function getScaleCountByRows(data: TimelineRow[], param: {
|
|
40
|
+
scale: number;
|
|
41
|
+
}): number;
|
|
42
|
+
/** Get current number of scale marks based on time */
|
|
43
|
+
export declare function getScaleCountByPixel(data: number, param: {
|
|
44
|
+
startLeft: number;
|
|
45
|
+
scaleWidth: number;
|
|
46
|
+
scaleCount: number;
|
|
47
|
+
}): number;
|
|
48
|
+
/** Get collection of positions for all action times */
|
|
49
|
+
export declare function parserActionsToPositions(actions: TimelineAction[], param: {
|
|
50
|
+
startLeft: number;
|
|
51
|
+
scale: number;
|
|
52
|
+
scaleWidth: number;
|
|
53
|
+
}): number[];
|
|
54
|
+
/**
|
|
55
|
+
* Split an action in a row at a given time.
|
|
56
|
+
* Automatically updates start/end times and creates a new adjacent action.
|
|
57
|
+
*/
|
|
58
|
+
export declare function splitActionInRow(data: TimelineRow[], rowId: string, actionId: string, cutTime: number): TimelineRow[];
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export declare enum LogLevel {
|
|
2
|
+
VERBOSE = 0,
|
|
3
|
+
LOG = 1,
|
|
4
|
+
INFO = 2,
|
|
5
|
+
WARN = 3,
|
|
6
|
+
ERROR = 4,
|
|
7
|
+
FATAL = 5,
|
|
8
|
+
SILENT = Infinity
|
|
9
|
+
}
|
|
10
|
+
export declare const LogLevels: {
|
|
11
|
+
VERBOSE: LogLevel;
|
|
12
|
+
LOG: LogLevel;
|
|
13
|
+
INFO: LogLevel;
|
|
14
|
+
WARN: LogLevel;
|
|
15
|
+
ERROR: LogLevel;
|
|
16
|
+
SILENT: LogLevel;
|
|
17
|
+
};
|
|
18
|
+
export default class ConsoleLogger {
|
|
19
|
+
static readonly instances: ConsoleLogger[];
|
|
20
|
+
static level: LogLevel;
|
|
21
|
+
static Levels: {
|
|
22
|
+
VERBOSE: LogLevel;
|
|
23
|
+
LOG: LogLevel;
|
|
24
|
+
INFO: LogLevel;
|
|
25
|
+
WARN: LogLevel;
|
|
26
|
+
ERROR: LogLevel;
|
|
27
|
+
SILENT: LogLevel;
|
|
28
|
+
};
|
|
29
|
+
static noColor: boolean;
|
|
30
|
+
Levels: {
|
|
31
|
+
VERBOSE: LogLevel;
|
|
32
|
+
LOG: LogLevel;
|
|
33
|
+
INFO: LogLevel;
|
|
34
|
+
WARN: LogLevel;
|
|
35
|
+
ERROR: LogLevel;
|
|
36
|
+
SILENT: LogLevel;
|
|
37
|
+
};
|
|
38
|
+
level: LogLevel;
|
|
39
|
+
prefix: string;
|
|
40
|
+
enabled: boolean;
|
|
41
|
+
debugColor: string;
|
|
42
|
+
logColor: string;
|
|
43
|
+
infoColor: string;
|
|
44
|
+
warnColor: string;
|
|
45
|
+
errorColor: string;
|
|
46
|
+
fatalColor: string;
|
|
47
|
+
/**
|
|
48
|
+
* ConsoleLogger
|
|
49
|
+
* @param {string} prefix Logger prefix
|
|
50
|
+
* @return {ConsoleLogger}
|
|
51
|
+
*/
|
|
52
|
+
constructor(prefix: string);
|
|
53
|
+
static setLevel(level: LogLevel): void;
|
|
54
|
+
static enable(level?: LogLevel): void;
|
|
55
|
+
static disable(): void;
|
|
56
|
+
/**
|
|
57
|
+
* set logger prefix
|
|
58
|
+
* @param prefix
|
|
59
|
+
*/
|
|
60
|
+
setPrefix(prefix: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* enable logger with optional log level
|
|
63
|
+
* @param level
|
|
64
|
+
*/
|
|
65
|
+
enable(level?: LogLevel): void;
|
|
66
|
+
/**
|
|
67
|
+
* disable logger
|
|
68
|
+
*/
|
|
69
|
+
disable(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set log level
|
|
72
|
+
* @param {LogLevel} level
|
|
73
|
+
* @return {void}
|
|
74
|
+
*/
|
|
75
|
+
setLevel(level: LogLevel): void;
|
|
76
|
+
/**
|
|
77
|
+
* trace
|
|
78
|
+
* @param title
|
|
79
|
+
* @param args
|
|
80
|
+
*/
|
|
81
|
+
trace(title: string, ...args: any[]): void;
|
|
82
|
+
/**
|
|
83
|
+
* debug
|
|
84
|
+
* @param title
|
|
85
|
+
* @param args
|
|
86
|
+
*/
|
|
87
|
+
debug(title: string, ...args: any[]): void;
|
|
88
|
+
/**
|
|
89
|
+
* log
|
|
90
|
+
* @param title
|
|
91
|
+
* @param args
|
|
92
|
+
*/
|
|
93
|
+
log(title: string, ...args: any[]): void;
|
|
94
|
+
/**
|
|
95
|
+
* info
|
|
96
|
+
* @param title
|
|
97
|
+
* @param args
|
|
98
|
+
*/
|
|
99
|
+
info(title: string, ...args: any[]): void;
|
|
100
|
+
/**
|
|
101
|
+
* warn
|
|
102
|
+
* @param title
|
|
103
|
+
* @param args
|
|
104
|
+
*/
|
|
105
|
+
warn(title: string, ...args: any[]): void;
|
|
106
|
+
/**
|
|
107
|
+
* error
|
|
108
|
+
* @param title
|
|
109
|
+
* @param args
|
|
110
|
+
*/
|
|
111
|
+
error(title: string, ...args: any[]): void;
|
|
112
|
+
/**
|
|
113
|
+
* fatal error
|
|
114
|
+
* @param title
|
|
115
|
+
* @param args
|
|
116
|
+
*/
|
|
117
|
+
fatal(title: string, ...args: any[]): void;
|
|
118
|
+
/**
|
|
119
|
+
* start a group with label
|
|
120
|
+
* @param label
|
|
121
|
+
*/
|
|
122
|
+
group(...label: any[]): void;
|
|
123
|
+
/**
|
|
124
|
+
* end a group
|
|
125
|
+
*/
|
|
126
|
+
groupEnd(): void;
|
|
127
|
+
/**
|
|
128
|
+
* collapse log group
|
|
129
|
+
* @param label
|
|
130
|
+
*/
|
|
131
|
+
groupCollapsed(...label: any[]): void;
|
|
132
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@keplar-404/react-timeline-editor",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"author": "keplar-404",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"timeline",
|
|
8
|
+
"animation",
|
|
9
|
+
"editor",
|
|
10
|
+
"react",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/keplar-404/react-timeline-editor/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/keplar-404/react-timeline-editor#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/keplar-404/react-timeline-editor.git"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "bun run clean && vite build",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"src",
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"main": "src/index.tsx",
|
|
30
|
+
"module": "src/index.tsx",
|
|
31
|
+
"typings": "src/index.tsx",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": ">=18.0.0",
|
|
34
|
+
"react-dom": ">=18.0.0"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@interactjs/types": "^1.10.11",
|
|
38
|
+
"@keplar-404/timeline-engine": "workspace:*",
|
|
39
|
+
"@types/react-virtualized": "^9.21.14",
|
|
40
|
+
"framework-utils": "^1.1.0",
|
|
41
|
+
"interactjs": "^1.10.11",
|
|
42
|
+
"react-virtualized": "^9.22.3"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/lodash": "^4.14.177",
|
|
46
|
+
"@types/react": "^18.2.0",
|
|
47
|
+
"@types/react-dom": "^18.2.0",
|
|
48
|
+
"@umijs/test": "^3.0.5",
|
|
49
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
50
|
+
"@vitejs/plugin-react-swc": "^3.5.0",
|
|
51
|
+
"lint-staged": "^10.0.7",
|
|
52
|
+
"lodash": "^4.17.21",
|
|
53
|
+
"prettier": "^2.2.1",
|
|
54
|
+
"react": "^18.2.0",
|
|
55
|
+
"react-dom": "^18.2.0",
|
|
56
|
+
"vite": "^7.0.0",
|
|
57
|
+
"vite-plugin-dts": "^4.5.4",
|
|
58
|
+
"yorkie": "^2.0.0"
|
|
59
|
+
},
|
|
60
|
+
"conditions": {
|
|
61
|
+
"USE_SRC": [
|
|
62
|
+
null,
|
|
63
|
+
{
|
|
64
|
+
"main": "dist/index.es.js",
|
|
65
|
+
"module": "dist/index.es.js",
|
|
66
|
+
"typings": "dist/index.d.ts"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// TODO: default control components (currently customized by users as needed)
|