import { reactive } from 'vue'; export interface TriggerState { visible: boolean; x: number; y: number; } export interface TriggerHandle { state: TriggerState; onEnter: (e: MouseEvent) => void; onMove: (e: MouseEvent) => void; onLeave: () => void; onBtnEnter: () => void; onBtnLeave: () => void; destroy: () => void; } export interface TriggerOptions { /** 鼠标停顿多久后显示按钮 (ms),默认 400 */ pauseDelay?: number; /** 按钮显示后多久自动消失 (ms),默认 3000 */ hideDelay?: number; } /** * 创建一个悬浮按钮触发器实例。 * 每个需要数据解读的 DOM 元素(卡片行、表格行、3D 标记等)对应一个 trigger。 * * 使用方式: * 1. 在 v-for 中为每行数据 createTrigger() * 2. 将 onEnter/onMove/onLeave 绑定到容器元素的 mouseenter/mousemove/mouseleave * 3. 将 DataInterpretationBtn 放在容器内,绑定 state 和 onBtnEnter/onBtnLeave */ export function createTrigger(options?: TriggerOptions): TriggerHandle { const PAUSE_DELAY = options?.pauseDelay ?? 400; const HIDE_DELAY = options?.hideDelay ?? 3000; const state = reactive({ visible: false, x: 0, y: 0, }); let pauseTimer: ReturnType | null = null; let hideTimer: ReturnType | null = null; function trackMouse(e: MouseEvent) { const target = e.currentTarget as HTMLElement; const rect = target.getBoundingClientRect(); state.x = e.clientX - rect.left - 36; state.y = e.clientY - rect.top - 34; } function startPauseTimer() { pauseTimer = setTimeout(() => { state.visible = true; startHideTimer(); }, PAUSE_DELAY); } function resetPauseTimer() { if (pauseTimer) { clearTimeout(pauseTimer); pauseTimer = null; } } function startHideTimer() { clearHideTimer(); hideTimer = setTimeout(() => { state.visible = false; }, HIDE_DELAY); } function clearHideTimer() { if (hideTimer) { clearTimeout(hideTimer); hideTimer = null; } } function onEnter(e: MouseEvent) { clearHideTimer(); trackMouse(e); startPauseTimer(); } function onMove(e: MouseEvent) { if (state.visible) return; trackMouse(e); resetPauseTimer(); startPauseTimer(); } function onLeave() { resetPauseTimer(); clearHideTimer(); state.visible = false; } function onBtnEnter() { clearHideTimer(); } function onBtnLeave() { startHideTimer(); } function destroy() { resetPauseTimer(); clearHideTimer(); } return { state, onEnter, onMove, onLeave, onBtnEnter, onBtnLeave, destroy, }; }