|
|
@@ -0,0 +1,144 @@
|
|
|
+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,
|
|
|
+ };
|
|
|
+}
|
|
|
+
|