refactor(TimelinePanel): 抽取 usePlayheadDrag hook

This commit is contained in:
2026-07-30 07:12:51 +08:00
parent 6930d4543f
commit 2f5eb94cb9
@@ -0,0 +1,76 @@
import { useState, useCallback, useEffect, useRef } from "react"
interface UsePlayheadDragOptions {
/** 当前播放时间(秒) */
currentTime: number
/** 缩放:每秒像素数 */
pps: number
/** 总时长(秒) */
totalDuration: number
/** 播放头跳转回调 */
onSeek?: (time: number) => void
}
/**
* 播放头拖拽 Hook
* 封装播放头的 mousedown/mousemove/mouseup 拖拽逻辑
*/
export const usePlayheadDrag = ({
pps,
totalDuration,
onSeek,
}: UsePlayheadDragOptions) => {
const [playheadDragging, setPlayheadDragging] = useState(false)
const trackRef = useRef<HTMLDivElement>(null)
/* ── 播放头拖拽全局 mousemove/mouseup ── */
useEffect(() => {
if (!playheadDragging) return
const handleMouseMove = (e: MouseEvent) => {
const trackEl = trackRef.current
if (!trackEl) return
const rect = trackEl.getBoundingClientRect()
const x = e.clientX - rect.left + trackEl.scrollLeft
const time = Math.max(0, Math.min(x / pps, totalDuration))
onSeek?.(Math.round(time * 10) / 10)
}
const handleMouseUp = () => {
setPlayheadDragging(false)
}
document.addEventListener("mousemove", handleMouseMove)
document.addEventListener("mouseup", handleMouseUp)
return () => {
document.removeEventListener("mousemove", handleMouseMove)
document.removeEventListener("mouseup", handleMouseUp)
}
}, [playheadDragging, pps, totalDuration, onSeek])
/* ── 播放头拖拽开始 ── */
const handlePlayheadMouseDown = useCallback((e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
setPlayheadDragging(true)
}, [])
/* ── 标尺点击跳转播放头 ── */
const handleRulerClick = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
const rect = e.currentTarget.getBoundingClientRect()
const x = e.clientX - rect.left
const time = Math.max(0, Math.min(x / pps, totalDuration))
onSeek?.(Math.round(time * 10) / 10)
},
[pps, totalDuration, onSeek],
)
return {
trackRef,
playheadDragging,
handlePlayheadMouseDown,
handleRulerClick,
}
}