import { useState, useRef, useCallback, useEffect } from "react" import type { MediaAsset } from "@/api/template-editor" interface UseAssetPreviewReturn { previewAsset: MediaAsset | null previewPos: { x: number; y: number } handleMouseEnter: (asset: MediaAsset, e: React.MouseEvent) => void handleMouseLeave: () => void } /** * 悬浮预览 Hook —— 延迟 400ms 显示预览浮层 */ const useAssetPreview = (): UseAssetPreviewReturn => { const [previewAsset, setPreviewAsset] = useState(null) const [previewPos, setPreviewPos] = useState({ x: 0, y: 0 }) const previewTimer = useRef | null>(null) const handleMouseEnter = useCallback((asset: MediaAsset, e: React.MouseEvent) => { if (previewTimer.current) clearTimeout(previewTimer.current) previewTimer.current = setTimeout(() => { const rect = (e.currentTarget as HTMLElement).getBoundingClientRect() setPreviewAsset(asset) setPreviewPos({ x: rect.right + 12, y: Math.max(8, rect.top - 20), }) }, 400) }, []) const handleMouseLeave = useCallback(() => { if (previewTimer.current) { clearTimeout(previewTimer.current) previewTimer.current = null } setPreviewAsset(null) }, []) // 清理定时器 useEffect(() => { return () => { if (previewTimer.current) clearTimeout(previewTimer.current) } }, []) return { previewAsset, previewPos, handleMouseEnter, handleMouseLeave, } } export default useAssetPreview