Skip to content

Commit 1012b8c

Browse files
committed
feat: ✨ max scale count
1 parent ddf99a0 commit 1012b8c

File tree

6 files changed

+62
-37
lines changed

6 files changed

+62
-37
lines changed

src/components/cursor/cursor.tsx

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const Cursor: FC<CursorProps> = ({
2626
cursorTime,
2727
setCursor,
2828
startLeft,
29-
scaleCount,
29+
timelineWidth,
3030
scaleWidth,
3131
scale,
3232
scrollLeft,
@@ -39,7 +39,6 @@ export const Cursor: FC<CursorProps> = ({
3939
}) => {
4040
const rowRnd = useRef<RowRndApi>();
4141
const draggingLeft = useRef<undefined | number>();
42-
const [width, setWidth] = useState(Number.MAX_SAFE_INTEGER);
4342

4443
useEffect(() => {
4544
if (typeof draggingLeft.current === 'undefined') {
@@ -48,38 +47,16 @@ export const Cursor: FC<CursorProps> = ({
4847
}
4948
}, [cursorTime, startLeft, scaleWidth, scale, scrollLeft]);
5049

51-
useEffect(() => {
52-
if (areaRef.current) {
53-
const resizeObserver = new ResizeObserver(() => {
54-
if(!areaRef.current) return;
55-
setWidth(areaRef.current.getBoundingClientRect().width);
56-
});
57-
resizeObserver.observe(areaRef.current!);
58-
return () => {
59-
resizeObserver && resizeObserver.disconnect();
60-
};
61-
}
62-
}, []);
63-
6450
return (
6551
<RowDnd
6652
start={startLeft}
6753
ref={rowRnd}
6854
parentRef={areaRef}
6955
bounds={{
7056
left: 0,
71-
right: width,
57+
right: timelineWidth,
7258
}}
73-
deltaScrollLeft={
74-
deltaScrollLeft
75-
? (delta) => {
76-
// 当超过最大距离时,禁止滚动
77-
const data = scrollSync.current.state.scrollLeft + delta;
78-
if (data > scaleCount * (scaleWidth - 1) + startLeft - width) return;
79-
deltaScrollLeft(delta);
80-
}
81-
: undefined
82-
}
59+
deltaScrollLeft={deltaScrollLeft}
8360
enableDragging={!disableDrag}
8461
enableResizing={false}
8562
onDragStart={() => {

src/components/edit_area/edit_action.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const EditAction: FC<EditActionProps> = ({
3434
disableDrag,
3535

3636
scaleCount,
37+
maxScaleCount,
3738
setScaleCount,
3839
onActionMoveStart,
3940
onActionMoving,
@@ -63,11 +64,14 @@ export const EditAction: FC<EditActionProps> = ({
6364
scale,
6465
scaleWidth,
6566
});
66-
const rightLimit = parserTimeToPixel(maxEnd || Number.MAX_VALUE, {
67-
startLeft,
68-
scale,
69-
scaleWidth,
70-
});
67+
const rightLimit = Math.min(
68+
maxScaleCount * scaleWidth + startLeft, // 根据maxScaleCount限制移动范围
69+
parserTimeToPixel(maxEnd || Number.MAX_VALUE, {
70+
startLeft,
71+
scale,
72+
scaleWidth,
73+
}),
74+
);
7175

7276
// 初始化动作坐标数据
7377
const [transform, setTransform] = useState(() => {

src/components/timeline.tsx

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
2424
scaleWidth,
2525
startLeft,
2626
minScaleCount,
27+
maxScaleCount,
2728
onChange,
2829
autoReRender = true,
2930
onScroll: onScrollVertical,
@@ -42,12 +43,14 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
4243
const [cursorTime, setCursorTime] = useState(START_CURSOR_TIME);
4344
// 是否正在运行
4445
const [isPlaying, setIsPlaying] = useState(false);
46+
// 当前时间轴宽度
47+
const [width, setWidth] = useState(Number.MAX_SAFE_INTEGER);
4548

4649
/** 监听数据变化 */
4750
useLayoutEffect(() => {
48-
setScaleCount(Math.max(minScaleCount, getScaleCountByRows(data, { scale })));
51+
handleSetScaleCount(getScaleCountByRows(data, { scale }));
4952
setEditorData(data);
50-
}, [data, minScaleCount, scale]);
53+
}, [data, minScaleCount, maxScaleCount, scale]);
5154

5255
useEffect(() => {
5356
engineRef.current.effects = effects;
@@ -66,6 +69,12 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
6669
scrollSync.current && scrollSync.current.setState({ scrollTop: scrollTop });
6770
}, [scrollTop]);
6871

72+
/** 动态设置scale count */
73+
const handleSetScaleCount = (value: number) => {
74+
const data = Math.min(maxScaleCount, Math.max(minScaleCount, value));
75+
setScaleCount(data);
76+
};
77+
6978
/** 处理主动数据变化 */
7079
const handleEditorDataChange = (editorData: TimelineRow[]) => {
7180
const result = onChange(editorData);
@@ -96,6 +105,9 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
96105

97106
/** 设置scrollLeft */
98107
const handleDeltaScrollLeft = (delta: number) => {
108+
// 当超过最大距离时,禁止自动滚动
109+
const data = scrollSync.current.state.scrollLeft + delta;
110+
if (data > scaleCount * (scaleWidth - 1) + startLeft - width) return;
99111
scrollSync.current && scrollSync.current.setState({ scrollLeft: Math.max(scrollSync.current.state.scrollLeft + delta, 0) });
100112
};
101113

@@ -140,30 +152,46 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
140152
},
141153
}));
142154

155+
// 监听timeline区域宽度变化
156+
useEffect(() => {
157+
if (areaRef.current) {
158+
const resizeObserver = new ResizeObserver(() => {
159+
if (!areaRef.current) return;
160+
setWidth(areaRef.current.getBoundingClientRect().width);
161+
});
162+
resizeObserver.observe(areaRef.current!);
163+
return () => {
164+
resizeObserver && resizeObserver.disconnect();
165+
};
166+
}
167+
}, []);
168+
143169
return (
144170
<div ref={domRef} style={style} className={`${PREFIX} ${disableDrag ? PREFIX + '-disable' : ''}`}>
145171
<ScrollSync ref={scrollSync}>
146172
{({ scrollLeft, scrollTop, onScroll }) => (
147173
<>
148174
<TimeArea
149175
{...checkedProps}
176+
timelineWidth={width}
150177
disableDrag={disableDrag || isPlaying}
151178
setCursor={handleSetCursor}
152179
cursorTime={cursorTime}
153180
editorData={editorData}
154181
scaleCount={scaleCount}
155-
setScaleCount={setScaleCount}
182+
setScaleCount={handleSetScaleCount}
156183
onScroll={onScroll}
157184
scrollLeft={scrollLeft}
158185
/>
159186
<EditArea
160187
{...checkedProps}
188+
timelineWidth={width}
161189
ref={(ref) => ((areaRef.current as any) = ref?.domRef.current)}
162190
disableDrag={disableDrag || isPlaying}
163191
editorData={editorData}
164192
cursorTime={cursorTime}
165193
scaleCount={scaleCount}
166-
setScaleCount={setScaleCount}
194+
setScaleCount={handleSetScaleCount}
167195
scrollTop={scrollTop}
168196
scrollLeft={scrollLeft}
169197
setEditorData={handleEditorDataChange}
@@ -176,10 +204,11 @@ export const Timeline = React.forwardRef<TimelineState, TimelineEditor>((props,
176204
{!hideCursor && (
177205
<Cursor
178206
{...checkedProps}
207+
timelineWidth={width}
179208
disableDrag={isPlaying}
180209
scrollLeft={scrollLeft}
181210
scaleCount={scaleCount}
182-
setScaleCount={setScaleCount}
211+
setScaleCount={handleSetScaleCount}
183212
setCursor={handleSetCursor}
184213
cursorTime={cursorTime}
185214
editorData={editorData}

src/interface/common_prop.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ export interface CommonProp extends EditData {
88
setScaleCount: (scaleCount: number) => void;
99
/** 光标时间 */
1010
cursorTime: number;
11+
/** 当前时间轴宽度 */
12+
timelineWidth: number;
1113
}

src/interface/timeline.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ export interface EditData {
2626
* @default 20
2727
*/
2828
minScaleCount?: number;
29+
/**
30+
* @description 最大刻度个数(>=minScaleCount)
31+
* @default Infinity
32+
*/
33+
maxScaleCount?: number;
2934
/**
3035
* @description 单个刻度细分单元数(>0整数)
3136
* @default 10

src/utils/check_props.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export function checkProps(props: TimelineEditor): TimelineEditor {
1313
scaleWidth = DEFAULT_SCALE_WIDTH,
1414
startLeft = DEFAULT_START_LEFT,
1515
minScaleCount = MIN_SCALE_COUNT,
16+
maxScaleCount = Infinity,
1617
rowHeight = DEFAULT_ROW_HEIGHT,
1718
} = props;
1819

@@ -42,11 +43,17 @@ export function checkProps(props: TimelineEditor): TimelineEditor {
4243
}
4344

4445
if(minScaleCount < 1) {
45-
logger.warn('Warning: rowHeight must be greater than 0!')
46+
logger.warn('Warning: minScaleCount must be greater than 1!')
4647
minScaleCount = MIN_SCALE_COUNT
4748
}
4849
minScaleCount = parseInt(minScaleCount + '');
4950

51+
if(maxScaleCount < minScaleCount) {
52+
logger.warn('Warning: maxScaleCount cannot be less than minScaleCount!')
53+
maxScaleCount = minScaleCount
54+
}
55+
maxScaleCount = maxScaleCount === Infinity ? Infinity : parseInt(maxScaleCount + '');
56+
5057
if(rowHeight <= 0) {
5158
logger.warn('Warning: rowHeight must be greater than 0!')
5259
rowHeight = DEFAULT_ROW_HEIGHT
@@ -64,6 +71,7 @@ export function checkProps(props: TimelineEditor): TimelineEditor {
6471
scaleWidth,
6572
startLeft,
6673
minScaleCount,
74+
maxScaleCount,
6775
rowHeight,
6876
}
6977
}

0 commit comments

Comments
 (0)