import { useRef, useCallback } from 'react'; // 设备实际分辨率(竖屏) const DEVICE_WIDTH = 1280; const DEVICE_HEIGHT = 2400; // 触摸事件处理逻辑:坐标转换和手势模拟 export function useTouchEvents(currentDevice, imageRef) { const isDragging = useRef(false); const startPos = useRef({ x: 0, y: 0 }); const lastPos = useRef({ x: 0, y: 0 }); const touchStartTime = useRef(0); // 将鼠标坐标转换为设备坐标 const convertToDeviceCoords = useCallback((clientX, clientY) => { if (!imageRef.current) { return null; } const img = imageRef.current; const rect = img.getBoundingClientRect(); // 计算鼠标相对于图片的位置(0-1 范围) const relativeX = (clientX - rect.left) / rect.width; const relativeY = (clientY - rect.top) / rect.height; // 转换为设备坐标 const deviceX = Math.round(relativeX * DEVICE_WIDTH); const deviceY = Math.round(relativeY * DEVICE_HEIGHT); // 确保坐标在设备范围内 const clampedX = Math.max(0, Math.min(DEVICE_WIDTH - 1, deviceX)); const clampedY = Math.max(0, Math.min(DEVICE_HEIGHT - 1, deviceY)); return { x: clampedX, y: clampedY }; }, [imageRef]); // 发送 tap 事件到设备 const sendTap = useCallback(async (x, y) => { if (!currentDevice || !window.electronAPI || !window.electronAPI.sendTap) { console.warn('Tap API 不可用或设备未连接'); return; } try { const result = await window.electronAPI.sendTap(currentDevice, x, y); if (!result?.success) { console.error('Tap 失败:', result?.error); } } catch (err) { console.error('Tap 异常:', err); } }, [currentDevice]); // 发送 swipe 事件到设备 const sendSwipe = useCallback(async (x1, y1, x2, y2, duration = 300) => { if (!currentDevice || !window.electronAPI || !window.electronAPI.sendSwipe) { console.warn('Swipe API 不可用或设备未连接'); return; } try { const result = await window.electronAPI.sendSwipe(currentDevice, x1, y1, x2, y2, duration); if (!result?.success) { console.error('Swipe 失败:', result?.error); } } catch (err) { console.error('Swipe 异常:', err); } }, [currentDevice]); // 处理鼠标按下 const handleMouseDown = useCallback((e) => { if (!currentDevice || !imageRef.current) return; e.preventDefault(); isDragging.current = true; touchStartTime.current = Date.now(); const deviceCoords = convertToDeviceCoords(e.clientX, e.clientY); if (deviceCoords) { startPos.current = deviceCoords; lastPos.current = deviceCoords; } }, [currentDevice, imageRef, convertToDeviceCoords]); // 处理鼠标移动 const handleMouseMove = useCallback((e) => { if (!isDragging.current || !currentDevice || !imageRef.current) return; e.preventDefault(); const deviceCoords = convertToDeviceCoords(e.clientX, e.clientY); if (deviceCoords) { lastPos.current = deviceCoords; } }, [currentDevice, imageRef, convertToDeviceCoords]); // 处理鼠标释放 const handleMouseUp = useCallback((e) => { if (!isDragging.current || !currentDevice) return; e.preventDefault(); isDragging.current = false; const touchDuration = Date.now() - touchStartTime.current; const distance = Math.sqrt( Math.pow(lastPos.current.x - startPos.current.x, 2) + Math.pow(lastPos.current.y - startPos.current.y, 2) ); // 判断是 tap 还是 swipe // 如果移动距离小于 10 像素且时间小于 300ms,认为是 tap if (distance < 10 && touchDuration < 300) { // Tap 操作 sendTap(startPos.current.x, startPos.current.y); } else if (distance >= 10) { // Swipe 操作 const swipeDuration = Math.max(100, Math.min(1000, touchDuration)); sendSwipe( startPos.current.x, startPos.current.y, lastPos.current.x, lastPos.current.y, swipeDuration ); } }, [currentDevice, sendTap, sendSwipe]); // 处理鼠标离开(防止拖拽到外部时无法触发 mouseup) const handleMouseLeave = useCallback((e) => { if (isDragging.current) { handleMouseUp(e); } }, [handleMouseUp]); return { handleMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, }; }