Quellcode durchsuchen

touch event perfect

yichael vor 5 Monaten
Ursprung
Commit
d6978fe91a

+ 5 - 0
src/pages/ScreenShot/ScreenShot.css

@@ -27,6 +27,11 @@
   overflow: hidden;
 }
 
+.screenshot-frame.filled {
+  border: none;
+  background: transparent;
+}
+
 .screenshot-img {
   max-width: 100%;
   max-height: 100%;

+ 31 - 12
src/pages/ScreenShot/ScreenShot.jsx

@@ -1,23 +1,42 @@
 import './ScreenShot.css';
 import { ScreenShotLogic } from './ScreenShot.js';
+import { useTouchEvents } from './TouchEvent.js';
+import { useRef } from 'react';
 
 function ScreenShot() {
-  const { imageSrc, notifyImageLoaded } = ScreenShotLogic();
+  const { imageSrc, notifyImageLoaded, currentDevice } = ScreenShotLogic();
+  const imageRef = useRef(null);
+  const { handleMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave } = useTouchEvents(currentDevice, imageRef);
 
   return (
     <div className="ScreenShot-container">
-      <div className="screenshot-frame">
-        {imageSrc ? (
-          <img
-            src={imageSrc}
-            alt="设备截屏"
-            onLoad={notifyImageLoaded}
-            className="screenshot-img"
-          />
-        ) : (
+      {!currentDevice && (
+        <div className="screenshot-frame">
           <div className="screenshot-placeholder">等待预览...</div>
-        )}
-      </div>
+        </div>
+      )}
+      {currentDevice && (
+        <div 
+          className="screenshot-frame filled"
+          onMouseDown={handleMouseDown}
+          onMouseMove={handleMouseMove}
+          onMouseUp={handleMouseUp}
+          onMouseLeave={handleMouseLeave}
+        >
+          {imageSrc ? (
+            <img
+              ref={imageRef}
+              src={imageSrc}
+              alt="设备截屏"
+              onLoad={notifyImageLoaded}
+              className="screenshot-img"
+              draggable={false}
+            />
+          ) : (
+            <div className="screenshot-placeholder">加载中...</div>
+          )}
+        </div>
+      )}
     </div>
   );
 }

+ 144 - 0
src/pages/ScreenShot/TouchEvent.js

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