@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.
Files changed (73) hide show
  1. package/dist/components/control_area/index.d.ts +0 -0
  2. package/dist/components/cursor/cursor.d.ts +20 -0
  3. package/dist/components/cut-overlay/CutOverlay.d.ts +202 -0
  4. package/dist/components/edit_area/cross_row_drag.d.ts +50 -0
  5. package/dist/components/edit_area/drag_lines.d.ts +11 -0
  6. package/dist/components/edit_area/drag_preview.d.ts +14 -0
  7. package/dist/components/edit_area/drag_utils.d.ts +39 -0
  8. package/dist/components/edit_area/edit_action.d.ts +19 -0
  9. package/dist/components/edit_area/edit_area.d.ts +56 -0
  10. package/dist/components/edit_area/edit_row.d.ts +27 -0
  11. package/dist/components/edit_area/hooks/use_drag_line.d.ts +33 -0
  12. package/dist/components/edit_area/insertion_line.d.ts +12 -0
  13. package/dist/components/loop-zone/LoopZoneOverlay.d.ts +243 -0
  14. package/dist/components/row_rnd/hooks/useAutoScroll.d.ts +7 -0
  15. package/dist/components/row_rnd/interactable.d.ts +14 -0
  16. package/dist/components/row_rnd/row_rnd.d.ts +3 -0
  17. package/dist/components/row_rnd/row_rnd_interface.d.ts +47 -0
  18. package/dist/components/time_area/time_area.d.ts +17 -0
  19. package/dist/components/timeline.d.ts +3 -0
  20. package/dist/components/transport/TransportBar.d.ts +132 -0
  21. package/dist/components/transport/useTimelinePlayer.d.ts +164 -0
  22. package/dist/index.cjs.js +13 -0
  23. package/dist/index.d.ts +12 -0
  24. package/dist/index.es.js +10102 -0
  25. package/dist/index.umd.js +13 -0
  26. package/dist/interface/common_prop.d.ts +12 -0
  27. package/dist/interface/const.d.ts +28 -0
  28. package/dist/interface/timeline.d.ts +342 -0
  29. package/dist/react-timeline-editor.css +1 -0
  30. package/dist/utils/check_props.d.ts +2 -0
  31. package/dist/utils/deal_class_prefix.d.ts +1 -0
  32. package/dist/utils/deal_data.d.ts +58 -0
  33. package/dist/utils/logger.d.ts +132 -0
  34. package/package.json +70 -0
  35. package/src/components/control_area/index.tsx +1 -0
  36. package/src/components/cursor/cursor.css +26 -0
  37. package/src/components/cursor/cursor.tsx +105 -0
  38. package/src/components/cut-overlay/CutOverlay.css +68 -0
  39. package/src/components/cut-overlay/CutOverlay.tsx +491 -0
  40. package/src/components/edit_area/cross_row_drag.tsx +174 -0
  41. package/src/components/edit_area/drag_lines.css +13 -0
  42. package/src/components/edit_area/drag_lines.tsx +31 -0
  43. package/src/components/edit_area/drag_preview.tsx +50 -0
  44. package/src/components/edit_area/drag_utils.ts +77 -0
  45. package/src/components/edit_area/edit_action.css +56 -0
  46. package/src/components/edit_area/edit_action.tsx +362 -0
  47. package/src/components/edit_area/edit_area.css +24 -0
  48. package/src/components/edit_area/edit_area.tsx +606 -0
  49. package/src/components/edit_area/edit_row.css +78 -0
  50. package/src/components/edit_area/edit_row.tsx +128 -0
  51. package/src/components/edit_area/hooks/use_drag_line.ts +93 -0
  52. package/src/components/edit_area/insertion_line.tsx +39 -0
  53. package/src/components/loop-zone/LoopZoneOverlay.css +65 -0
  54. package/src/components/loop-zone/LoopZoneOverlay.tsx +461 -0
  55. package/src/components/row_rnd/hooks/useAutoScroll.ts +81 -0
  56. package/src/components/row_rnd/interactable.tsx +55 -0
  57. package/src/components/row_rnd/row_rnd.tsx +365 -0
  58. package/src/components/row_rnd/row_rnd_interface.ts +59 -0
  59. package/src/components/time_area/time_area.css +35 -0
  60. package/src/components/time_area/time_area.tsx +93 -0
  61. package/src/components/timeline.css +12 -0
  62. package/src/components/timeline.tsx +227 -0
  63. package/src/components/transport/TransportBar.css +171 -0
  64. package/src/components/transport/TransportBar.tsx +322 -0
  65. package/src/components/transport/useTimelinePlayer.ts +319 -0
  66. package/src/index.tsx +17 -0
  67. package/src/interface/common_prop.ts +13 -0
  68. package/src/interface/const.ts +32 -0
  69. package/src/interface/timeline.ts +329 -0
  70. package/src/utils/check_props.ts +77 -0
  71. package/src/utils/deal_class_prefix.ts +6 -0
  72. package/src/utils/deal_data.ts +159 -0
  73. package/src/utils/logger.ts +239 -0
@@ -0,0 +1,365 @@
1
+ import { Interactable } from '@interactjs/core/Interactable';
2
+ import { DragEvent, ResizeEvent } from '@interactjs/types/index';
3
+ import React, { ReactElement, useEffect, useImperativeHandle, useRef } from 'react';
4
+ import { DEFAULT_ADSORPTION_DISTANCE, DEFAULT_MOVE_GRID, DEFAULT_START_LEFT } from '../../interface/const';
5
+ import { useAutoScroll } from './hooks/useAutoScroll';
6
+ import { InteractComp } from './interactable';
7
+ import { Direction, RowRndApi, RowRndProps } from './row_rnd_interface';
8
+
9
+ export const RowDnd = React.forwardRef<RowRndApi, RowRndProps>(
10
+ (
11
+ {
12
+ children,
13
+ edges,
14
+ left,
15
+ width,
16
+
17
+ start = DEFAULT_START_LEFT,
18
+ grid = DEFAULT_MOVE_GRID,
19
+ bounds = {
20
+ left: Number.MIN_SAFE_INTEGER,
21
+ right: Number.MAX_SAFE_INTEGER,
22
+ },
23
+ enableResizing = true,
24
+ enableDragging = true,
25
+ adsorptionDistance = DEFAULT_ADSORPTION_DISTANCE,
26
+ adsorptionPositions = [],
27
+ onResizeStart,
28
+ onResize,
29
+ onResizeEnd,
30
+ onDragStart,
31
+ onDragEnd,
32
+ onDrag,
33
+ parentRef,
34
+ deltaScrollLeft,
35
+ },
36
+ ref,
37
+ ) => {
38
+ const interactable = useRef<Interactable | null>(null);
39
+ const deltaX = useRef(0);
40
+ const isAdsorption = useRef(false);
41
+ const { initAutoScroll, dealDragAutoScroll, dealResizeAutoScroll, stopAutoScroll } = useAutoScroll(parentRef);
42
+
43
+ useEffect(() => {
44
+ return () => {
45
+ interactable.current && interactable.current.unset();
46
+ };
47
+ }, []);
48
+
49
+ //#region [rgba(100,120,156,0.08)] Assignment related APIs
50
+ useImperativeHandle(ref, () => ({
51
+ updateLeft: (left) => handleUpdateLeft(left || 0, false),
52
+ updateWidth: (width) => handleUpdateWidth(width, false),
53
+ getLeft: handleGetLeft,
54
+ getWidth: handleGetWidth,
55
+ }));
56
+ useEffect(() => {
57
+ const target = interactable.current?.target as HTMLElement;
58
+ handleUpdateWidth(typeof width === 'undefined' ? target.offsetWidth : width, false);
59
+ }, [width]);
60
+ useEffect(() => {
61
+ handleUpdateLeft(left || 0, false);
62
+ }, [left]);
63
+
64
+ const handleUpdateLeft = (left: number, reset = true) => {
65
+ if (!interactable.current || !interactable.current.target) return;
66
+ reset && (deltaX.current = 0);
67
+ const target = interactable.current.target as HTMLElement;
68
+ target.style.left = `${left}px`;
69
+ Object.assign(target.dataset, { left });
70
+ };
71
+ const handleUpdateWidth = (width: number, reset = true) => {
72
+ if (!interactable.current || !interactable.current.target) return;
73
+ reset && (deltaX.current = 0);
74
+ const target = interactable.current.target as HTMLElement;
75
+ target.style.width = `${width}px`;
76
+ Object.assign(target.dataset, { width });
77
+ };
78
+ const handleGetLeft = () => {
79
+ const target = interactable.current?.target as HTMLElement;
80
+ return parseFloat(target?.dataset?.left || '0');
81
+ };
82
+ const handleGetWidth = () => {
83
+ const target = interactable.current?.target as HTMLElement;
84
+ return parseFloat(target?.dataset?.width || '0');
85
+ };
86
+ //#endregion
87
+
88
+ //#region [rgba(188,188,120,0.05)] Callback APIs
89
+ const handleMoveStart = (e: DragEvent) => {
90
+ deltaX.current = 0;
91
+ isAdsorption.current = false;
92
+ initAutoScroll();
93
+ onDragStart && onDragStart();
94
+ };
95
+
96
+ const move = (param: { preLeft: number; preWidth: number; scrollDelta?: number }) => {
97
+ const { preLeft, preWidth, scrollDelta } = param;
98
+ const distance = isAdsorption.current ? adsorptionDistance : grid;
99
+ if (Math.abs(deltaX.current) >= distance) {
100
+ const count = parseInt(deltaX.current / distance + '');
101
+ let curLeft = preLeft + count * distance;
102
+
103
+ // Control adsorption
104
+ let adsorption = curLeft;
105
+ let minDis = Number.MAX_SAFE_INTEGER;
106
+ adsorptionPositions.forEach((item) => {
107
+ const dis = Math.abs(item - curLeft);
108
+ if (dis < adsorptionDistance && dis < minDis) adsorption = item;
109
+ const dis2 = Math.abs(item - (curLeft + preWidth));
110
+ if (dis2 < adsorptionDistance && dis2 < minDis) adsorption = item - preWidth;
111
+ });
112
+
113
+ if (adsorption !== curLeft) {
114
+ // Use adsorption data
115
+ isAdsorption.current = true;
116
+ curLeft = adsorption;
117
+ } else {
118
+ // Control grid
119
+ if ((curLeft - start) % grid !== 0) {
120
+ curLeft = start + grid * Math.round((curLeft - start) / grid);
121
+ }
122
+ isAdsorption.current = false;
123
+ }
124
+ deltaX.current = deltaX.current % distance;
125
+
126
+ // Control bounds
127
+ if (curLeft < bounds.left) curLeft = bounds.left;
128
+ else if (curLeft + preWidth > bounds.right) curLeft = bounds.right - preWidth;
129
+
130
+ if (onDrag) {
131
+ const ret = onDrag(
132
+ {
133
+ lastLeft: preLeft,
134
+ left: curLeft,
135
+ lastWidth: preWidth,
136
+ width: preWidth,
137
+ },
138
+ scrollDelta,
139
+ );
140
+ if (ret === false) return;
141
+ }
142
+
143
+ handleUpdateLeft(curLeft, false);
144
+ }
145
+ };
146
+
147
+ const handleMove = (e: DragEvent) => {
148
+ const target = e.target;
149
+
150
+ if (deltaScrollLeft && parentRef?.current) {
151
+ const result = dealDragAutoScroll(e, (delta) => {
152
+ deltaScrollLeft(delta);
153
+
154
+ let { left, width } = target.dataset;
155
+ const preLeft = parseFloat(left || '0');
156
+ const preWidth = parseFloat(width || '0');
157
+ deltaX.current += delta;
158
+ move({ preLeft, preWidth, scrollDelta: delta });
159
+ });
160
+ if (!result) return;
161
+ }
162
+
163
+ let { left, width } = target.dataset;
164
+ const preLeft = parseFloat(left || '0');
165
+ const preWidth = parseFloat(width || '0');
166
+
167
+ deltaX.current += e.dx;
168
+ move({ preLeft, preWidth });
169
+ };
170
+
171
+ const handleMoveStop = (e: DragEvent) => {
172
+ deltaX.current = 0;
173
+ isAdsorption.current = false;
174
+ stopAutoScroll();
175
+
176
+ const target = e.target;
177
+ let { left, width } = target.dataset;
178
+ onDragEnd && onDragEnd({ left: parseFloat(left || '0'), width: parseFloat(width || '0') });
179
+ };
180
+
181
+ const handleResizeStart = (e: ResizeEvent) => {
182
+ deltaX.current = 0;
183
+ isAdsorption.current = false;
184
+ initAutoScroll();
185
+
186
+ let dir: Direction = e.edges?.right ? 'right' : 'left';
187
+ onResizeStart && onResizeStart(dir);
188
+ };
189
+
190
+ const resize = (param: { preLeft: number; preWidth: number; dir: 'left' | 'right' }) => {
191
+ const { dir, preWidth, preLeft } = param;
192
+ const distance = isAdsorption.current ? adsorptionDistance : grid;
193
+
194
+ if (dir === 'left') {
195
+ // Dragging left side
196
+ if (Math.abs(deltaX.current) >= distance) {
197
+ const count = parseInt(deltaX.current / distance + '');
198
+ let curLeft = preLeft + count * distance;
199
+
200
+ // Control adsorption
201
+ let adsorption = curLeft;
202
+ let minDis = Number.MAX_SAFE_INTEGER;
203
+ adsorptionPositions.forEach((item) => {
204
+ const dis = Math.abs(item - curLeft);
205
+ if (dis < adsorptionDistance && dis < minDis) adsorption = item;
206
+ });
207
+
208
+ if (adsorption !== curLeft) {
209
+ // Use adsorption data
210
+ isAdsorption.current = true;
211
+ curLeft = adsorption;
212
+ } else {
213
+ // Control grid
214
+ if ((curLeft - start) % grid !== 0) {
215
+ curLeft = start + grid * Math.round((curLeft - start) / grid);
216
+ }
217
+ isAdsorption.current = false;
218
+ }
219
+ deltaX.current = deltaX.current % distance;
220
+
221
+ // Control bounds
222
+ const tempRight = preLeft + preWidth;
223
+ if (curLeft < bounds.left) curLeft = bounds.left;
224
+ const curWidth = tempRight - curLeft;
225
+
226
+ if (onResize) {
227
+ const ret = onResize('left', {
228
+ lastLeft: preLeft,
229
+ lastWidth: preWidth,
230
+ left: curLeft,
231
+ width: curWidth,
232
+ });
233
+ if (ret === false) return;
234
+ }
235
+
236
+ handleUpdateLeft(curLeft, false);
237
+ handleUpdateWidth(curWidth, false);
238
+ }
239
+ } else if (dir === 'right') {
240
+ // Dragging right side
241
+ if (Math.abs(deltaX.current) >= distance) {
242
+ const count = parseInt(deltaX.current / grid + '');
243
+ let curWidth = preWidth + count * grid;
244
+
245
+ // Control adsorption
246
+ let adsorption = preLeft + curWidth;
247
+ let minDis = Number.MAX_SAFE_INTEGER;
248
+ adsorptionPositions.forEach((item) => {
249
+ const dis = Math.abs(item - (preLeft + curWidth));
250
+ if (dis < adsorptionDistance && dis < minDis) adsorption = item;
251
+ });
252
+
253
+ if (adsorption !== preLeft + curWidth) {
254
+ // Use adsorption data
255
+ isAdsorption.current = true;
256
+ curWidth = adsorption - preLeft;
257
+ } else {
258
+ // Control grid
259
+ let tempRight = preLeft + curWidth;
260
+ if ((tempRight - start) % grid !== 0) {
261
+ tempRight = start + grid * Math.round((tempRight - start) / grid);
262
+ curWidth = tempRight - preLeft;
263
+ }
264
+ isAdsorption.current = false;
265
+ }
266
+ deltaX.current = deltaX.current % distance;
267
+
268
+ // Control bounds
269
+ if (preLeft + curWidth > bounds.right) curWidth = bounds.right - preLeft;
270
+
271
+ if (onResize) {
272
+ const ret = onResize('right', {
273
+ lastLeft: preLeft,
274
+ lastWidth: preWidth,
275
+ left: preLeft,
276
+ width: curWidth,
277
+ });
278
+ if (ret === false) return;
279
+ }
280
+
281
+ handleUpdateWidth(curWidth, false);
282
+ }
283
+ }
284
+ };
285
+
286
+ const handleResize = (e: ResizeEvent) => {
287
+ const target = e.target;
288
+ const dir = e.edges?.left ? 'left' : 'right';
289
+
290
+ if (deltaScrollLeft && parentRef?.current) {
291
+ const result = dealResizeAutoScroll(e, dir, (delta) => {
292
+ deltaScrollLeft(delta);
293
+
294
+ let { left, width } = target.dataset;
295
+ const preLeft = parseFloat(left || '0');
296
+ const preWidth = parseFloat(width || '0');
297
+ deltaX.current += delta;
298
+ resize({ preLeft, preWidth, dir });
299
+ });
300
+ if (!result) return;
301
+ }
302
+
303
+ let { left, width } = target.dataset;
304
+ const preLeft = parseFloat(left || '0');
305
+ const preWidth = parseFloat(width || '0');
306
+
307
+ deltaX.current += dir === 'left' ? e.deltaRect?.left || 0 : e.deltaRect?.right || 0;
308
+ resize({ preLeft, preWidth, dir });
309
+ };
310
+ const handleResizeStop = (e: ResizeEvent) => {
311
+ deltaX.current = 0;
312
+ isAdsorption.current = false;
313
+ stopAutoScroll();
314
+
315
+ const target = e.target;
316
+ let { left, width } = target.dataset;
317
+ let dir: Direction = e.edges?.right ? 'right' : 'left';
318
+ onResizeEnd &&
319
+ onResizeEnd(dir, {
320
+ left: parseFloat(left || '0'),
321
+ width: parseFloat(width || '0'),
322
+ });
323
+ };
324
+ //#endregion
325
+
326
+ return (
327
+ <InteractComp
328
+ interactRef={interactable}
329
+ draggable={enableDragging}
330
+ resizable={enableResizing}
331
+ draggableOptions={{
332
+ lockAxis: 'x',
333
+ onmove: handleMove,
334
+ onstart: handleMoveStart,
335
+ onend: handleMoveStop,
336
+ cursorChecker: () => {
337
+ return '';
338
+ },
339
+ }}
340
+ resizableOptions={{
341
+ axis: 'x',
342
+ invert: 'none',
343
+ edges: {
344
+ left: true,
345
+ right: true,
346
+ top: false,
347
+ bottom: false,
348
+ ...(edges || {}),
349
+ },
350
+ onmove: handleResize,
351
+ onstart: handleResizeStart,
352
+ onend: handleResizeStop,
353
+ }}
354
+ >
355
+ {React.cloneElement(children as ReactElement, {
356
+ style: {
357
+ ...((children as ReactElement).props.style || {}),
358
+ left,
359
+ width,
360
+ },
361
+ })}
362
+ </InteractComp>
363
+ );
364
+ },
365
+ );
@@ -0,0 +1,59 @@
1
+ import { DragEvent, ResizeEvent } from "@interactjs/types/index";
2
+
3
+ type EventData = {
4
+ lastLeft: number;
5
+ left: number;
6
+ lastWidth: number;
7
+ width: number;
8
+ };
9
+
10
+ export type RndDragStartCallback = () => void;
11
+ export type RndDragCallback = (
12
+ data: EventData,
13
+ scrollDelta?: number,
14
+ ) => boolean | void;
15
+ export type RndDragEndCallback = (data: Pick<EventData, 'left' | 'width'>) => void;
16
+
17
+ export type Direction = "left" | "right";
18
+ export type RndResizeStartCallback = (dir: Direction) => void;
19
+ export type RndResizeCallback = (
20
+ dir: Direction,
21
+ data: EventData
22
+ ) => boolean | void;
23
+ export type RndResizeEndCallback = (
24
+ dir: Direction,
25
+ data: Pick<EventData, 'left' | 'width'>
26
+ ) => void;
27
+
28
+ export interface RowRndApi {
29
+ updateWidth: (size: number) => void;
30
+ updateLeft: (left: number) => void;
31
+ getLeft: () => number;
32
+ getWidth: () => number;
33
+ }
34
+
35
+ export interface RowRndProps {
36
+ width?: number;
37
+ left?: number;
38
+ grid?: number;
39
+ start?: number;
40
+ bounds?: { left: number; right: number };
41
+ edges?: {left: boolean | string, right: boolean | string};
42
+
43
+ onResizeStart?: RndResizeStartCallback;
44
+ onResize?: RndResizeCallback;
45
+ onResizeEnd?: RndResizeEndCallback;
46
+ onDragStart?: RndDragStartCallback;
47
+ onDrag?: RndDragCallback;
48
+ onDragEnd?: RndDragEndCallback;
49
+ // Automatic scrolling is enabled when both parentRef and deltaScrollLeft are provided
50
+ parentRef: React.RefObject<HTMLDivElement>;
51
+ deltaScrollLeft?: (delta: number) => void;
52
+
53
+ children?: React.ReactNode;
54
+
55
+ enableResizing?: boolean;
56
+ enableDragging?: boolean;
57
+ adsorptionPositions?: number[];
58
+ adsorptionDistance?: number;
59
+ }
@@ -0,0 +1,35 @@
1
+ .timeline-editor-time-area {
2
+ position: relative;
3
+ height: 32px;
4
+ flex: 0 0 auto;
5
+ }
6
+ .timeline-editor-time-area .ReactVirtualized__Grid {
7
+ outline: none;
8
+ }
9
+ .timeline-editor-time-area .ReactVirtualized__Grid::-webkit-scrollbar {
10
+ display: none;
11
+ }
12
+ .timeline-editor-time-area-interact {
13
+ position: absolute;
14
+ cursor: pointer;
15
+ left: 0;
16
+ top: 0;
17
+ }
18
+ .timeline-editor-time-unit {
19
+ border-right: 1px solid rgba(255, 255, 255, 0.2);
20
+ position: relative;
21
+ box-sizing: content-box;
22
+ height: 4px !important;
23
+ bottom: 0 !important;
24
+ top: auto !important;
25
+ }
26
+ .timeline-editor-time-unit-big {
27
+ height: 8px !important;
28
+ }
29
+ .timeline-editor-time-unit-scale {
30
+ color: rgba(255, 255, 255, 0.6);
31
+ position: absolute;
32
+ right: 0;
33
+ top: 0;
34
+ transform: translate(50%, -100%);
35
+ }
@@ -0,0 +1,93 @@
1
+ import { FC, useEffect, useRef } from 'react';
2
+ import { AutoSizer, Grid, GridCellRenderer, OnScrollParams } from 'react-virtualized';
3
+ import { CommonProp } from '../../interface/common_prop';
4
+ import { prefix } from '../../utils/deal_class_prefix';
5
+ import { parserPixelToTime } from '../../utils/deal_data';
6
+ import './time_area.css';
7
+
8
+ /** Animation timeline component parameters */
9
+ export type TimeAreaProps = CommonProp & {
10
+ /** Scroll distance from left */
11
+ scrollLeft: number;
12
+ /** Scroll callback, used for synchronous scrolling */
13
+ onScroll: (params: OnScrollParams) => void;
14
+ /** Set cursor position */
15
+ setCursor: (param: { left?: number; time?: number }) => void;
16
+ };
17
+
18
+ /** Animation timeline component */
19
+ export const TimeArea: FC<TimeAreaProps> = ({ setCursor, maxScaleCount, hideCursor, scale, scaleWidth, scaleCount, scaleSplitCount, startLeft, scrollLeft, onClickTimeArea, getScaleRender }) => {
20
+ const gridRef = useRef<Grid>(null);
21
+ /** Whether to show subdivision marks */
22
+ const showUnit = scaleSplitCount > 0;
23
+
24
+ /** Get rendering content for each cell */
25
+ const cellRenderer: GridCellRenderer = ({ columnIndex, key, style }) => {
26
+ const isShowScale = showUnit ? columnIndex % scaleSplitCount === 0 : true;
27
+ const classNames = ['time-unit'];
28
+ if (isShowScale) classNames.push('time-unit-big');
29
+ const item = (showUnit ? columnIndex / scaleSplitCount : columnIndex) * scale;
30
+ return (
31
+ <div key={key} style={style} className={prefix(...classNames)}>
32
+ {isShowScale && <div className={prefix('time-unit-scale')}>{getScaleRender ? getScaleRender(item) : item}</div>}
33
+ </div>
34
+ );
35
+ };
36
+
37
+ useEffect(() => {
38
+ gridRef.current?.recomputeGridSize();
39
+ }, [scaleWidth, startLeft]);
40
+
41
+ /** Get column width */
42
+ const getColumnWidth = (data: { index: number }) => {
43
+ switch (data.index) {
44
+ case 0:
45
+ return startLeft;
46
+ default:
47
+ return showUnit ? scaleWidth / scaleSplitCount : scaleWidth;
48
+ }
49
+ };
50
+ const estColumnWidth=getColumnWidth({index:1});
51
+ return (
52
+ <div className={prefix('time-area')}>
53
+ <AutoSizer>
54
+ {({ width, height }) => {
55
+ return (
56
+ <>
57
+ <Grid
58
+ ref={gridRef}
59
+ columnCount={showUnit ? scaleCount * scaleSplitCount + 1 : scaleCount}
60
+ columnWidth={getColumnWidth}
61
+ estimatedColumnSize={estColumnWidth}
62
+ rowCount={1}
63
+ rowHeight={height}
64
+ width={width}
65
+ height={height}
66
+ overscanRowCount={0}
67
+ overscanColumnCount={10}
68
+ cellRenderer={cellRenderer}
69
+ scrollLeft={scrollLeft}
70
+ ></Grid>
71
+ <div
72
+ style={{ width, height }}
73
+ onClick={(e) => {
74
+ if (hideCursor) return;
75
+ const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
76
+ const position = e.clientX - rect.x;
77
+ const left = Math.max(position + scrollLeft, startLeft);
78
+ if (left > maxScaleCount * scaleWidth + startLeft - scrollLeft) return;
79
+
80
+ const time = parserPixelToTime(left, { startLeft, scale, scaleWidth });
81
+ const result = onClickTimeArea && onClickTimeArea(time, e);
82
+ if (result === false) return; // Prevent setting time when false is returned
83
+ setCursor({ time });
84
+ }}
85
+ className={prefix('time-area-interact')}
86
+ ></div>
87
+ </>
88
+ );
89
+ }}
90
+ </AutoSizer>
91
+ </div>
92
+ );
93
+ };
@@ -0,0 +1,12 @@
1
+ .timeline-editor {
2
+ height: 600px;
3
+ width: 600px;
4
+ min-height: 32px;
5
+ position: relative;
6
+ font-size: 12px;
7
+ font-family: "PingFang SC";
8
+ background-color: #191b1d;
9
+ display: flex;
10
+ flex-direction: column;
11
+ overflow: hidden;
12
+ }