diff --git a/apps/web/src/pages/editing-planner/components/TimelinePanel.tsx b/apps/web/src/pages/editing-planner/components/TimelinePanel.tsx index a62a783fe..a29731b27 100644 --- a/apps/web/src/pages/editing-planner/components/TimelinePanel.tsx +++ b/apps/web/src/pages/editing-planner/components/TimelinePanel.tsx @@ -141,7 +141,7 @@ const TimelinePanel: React.FC = ({ /* ── "+" 卡片:类型+时长选择状态 ── */ const [addType, setAddType] = useState(defaultAddType) - const [addDuration, setAddDuration] = useState(5) + const [addDuration, setAddDuration] = useState(DEFAULT_ADD_DURATION) /* ── 模式切换时自动同步默认添加类型 ── */ useEffect(() => { @@ -150,21 +150,17 @@ const TimelinePanel: React.FC = ({ } }, [currentMode, addType, availableTypes, defaultAddType]) - /* ── 面板尺寸 ── */ - const PICKER_W = 240 - const GAP = 6 - /* ── 计算 picker 初始位置 ── */ const updatePickerPosition = useCallback(() => { if (!addCardRef.current) return const rect = addCardRef.current.getBoundingClientRect() const vw = window.innerWidth const roughHeight = 180 - let top = rect.top - GAP - roughHeight + let top = rect.top - TRACK_GAP - roughHeight if (top < 8) top = 8 let right = vw - rect.right - if (rect.right - PICKER_W < 8) { - right = vw - PICKER_W - 8 + if (rect.right - ADD_PICKER_WIDTH < 8) { + right = vw - ADD_PICKER_WIDTH - 8 } setPickerPos({ top, right }) }, []) @@ -187,9 +183,9 @@ const TimelinePanel: React.FC = ({ const pickerH = pickerEl.offsetHeight const vh = window.innerHeight const vw = window.innerWidth - let top = addRect.top - GAP - pickerH + let top = addRect.top - TRACK_GAP - pickerH if (top < 8) { - top = addRect.bottom + GAP + top = addRect.bottom + TRACK_GAP if (top + pickerH > vh - 8) { top = vh - 8 - pickerH if (top < 8) top = 8 @@ -198,7 +194,7 @@ const TimelinePanel: React.FC = ({ let right = vw - addRect.right const pickerRect = pickerEl.getBoundingClientRect() if (pickerRect.left < 8) { - right = vw - PICKER_W - 8 + right = vw - ADD_PICKER_WIDTH - 8 } setPickerPos({ top, right }) }, [showAddPicker]) @@ -230,7 +226,7 @@ const TimelinePanel: React.FC = ({ }, [contextMenu]) /* ── 缩放 & 时长 ── */ - const pps = pixelsPerSecond ?? 40 + const pps = pixelsPerSecond ?? DEFAULT_PIXELS_PER_SECOND const totalDuration = totalDurationProp ?? clips.reduce((s, c) => s + c.duration, 0) /* ── 播放头拖拽全局 mousemove/mouseup ── */ @@ -350,11 +346,9 @@ const TimelinePanel: React.FC = ({ useEffect(() => { if (!trimDrag) return - const PX_PER_SECOND = pixelsPerSecond ?? 40 // 与缩放级别同步 - const handleMouseMove = (e: MouseEvent) => { const dx = e.clientX - trimDrag.startX - const dtSec = dx / PX_PER_SECOND + const dtSec = dx / pps const clip = clips.find((c) => c.id === trimDrag.clipId) if (!clip) return @@ -365,10 +359,10 @@ const TimelinePanel: React.FC = ({ if (trimDrag.direction === "left") { // 左手柄:调整入点 - newStart = Math.max(0, Math.min(origTrim.start_time + dtSec, newEnd - 1)) + newStart = Math.max(0, Math.min(origTrim.start_time + dtSec, newEnd - MIN_TRIM_DURATION)) } else { // 右手柄:调整出点 - newEnd = Math.max(origTrim.start_time + 1, Math.min(origTrim.end_time + dtSec, origDur)) + newEnd = Math.max(origTrim.start_time + MIN_TRIM_DURATION, Math.min(origTrim.end_time + dtSec, origDur)) } const newDuration = Math.round((newEnd - newStart) * 10) / 10 @@ -435,7 +429,7 @@ const TimelinePanel: React.FC = ({ }, [contextMenu, onClipRemove]) /* ── 时间标尺 ── */ - const trackWidth = Math.max(totalDuration * pps, 300) + const trackWidth = Math.max(totalDuration * pps, MIN_TRACK_WIDTH) const step = getRulerStep(totalDuration) const rulerMarks = generateRulerMarks(totalDuration, step) @@ -452,7 +446,7 @@ const TimelinePanel: React.FC = ({