|
@@ -1,8 +1,4 @@
|
|
|
-import { useRef, useCallback } from 'react';
|
|
|
|
|
-
|
|
|
|
|
-// 设备实际分辨率(竖屏)
|
|
|
|
|
-const DEVICE_WIDTH = 1280;
|
|
|
|
|
-const DEVICE_HEIGHT = 2400;
|
|
|
|
|
|
|
+import { useRef, useCallback, useState, useEffect } from 'react';
|
|
|
|
|
|
|
|
// 触摸事件处理逻辑:坐标转换和手势模拟
|
|
// 触摸事件处理逻辑:坐标转换和手势模拟
|
|
|
export function useTouchEvents(currentDevice, imageRef) {
|
|
export function useTouchEvents(currentDevice, imageRef) {
|
|
@@ -10,6 +6,30 @@ export function useTouchEvents(currentDevice, imageRef) {
|
|
|
const startPos = useRef({ x: 0, y: 0 });
|
|
const startPos = useRef({ x: 0, y: 0 });
|
|
|
const lastPos = useRef({ x: 0, y: 0 });
|
|
const lastPos = useRef({ x: 0, y: 0 });
|
|
|
const touchStartTime = useRef(0);
|
|
const touchStartTime = useRef(0);
|
|
|
|
|
+ const [deviceResolution, setDeviceResolution] = useState({ width: 1280, height: 2400 });
|
|
|
|
|
+
|
|
|
|
|
+ // 获取设备实际分辨率
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ const fetchDeviceResolution = async () => {
|
|
|
|
|
+ if (!currentDevice || !window.electronAPI || !window.electronAPI.getDeviceResolution) {
|
|
|
|
|
+ // 如果 API 不可用,使用默认值
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await window.electronAPI.getDeviceResolution(currentDevice);
|
|
|
|
|
+ if (result?.success && result.width && result.height) {
|
|
|
|
|
+ setDeviceResolution({ width: result.width, height: result.height });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.warn('获取设备分辨率失败,使用默认值:', err);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (currentDevice) {
|
|
|
|
|
+ fetchDeviceResolution();
|
|
|
|
|
+ }
|
|
|
|
|
+ }, [currentDevice]);
|
|
|
|
|
|
|
|
// 将鼠标坐标转换为设备坐标
|
|
// 将鼠标坐标转换为设备坐标
|
|
|
const convertToDeviceCoords = useCallback((clientX, clientY) => {
|
|
const convertToDeviceCoords = useCallback((clientX, clientY) => {
|
|
@@ -20,20 +40,56 @@ export function useTouchEvents(currentDevice, imageRef) {
|
|
|
const img = imageRef.current;
|
|
const img = imageRef.current;
|
|
|
const rect = img.getBoundingClientRect();
|
|
const rect = img.getBoundingClientRect();
|
|
|
|
|
|
|
|
- // 计算鼠标相对于图片的位置(0-1 范围)
|
|
|
|
|
- const relativeX = (clientX - rect.left) / rect.width;
|
|
|
|
|
- const relativeY = (clientY - rect.top) / rect.height;
|
|
|
|
|
|
|
+ // 获取图片的实际显示尺寸(考虑 object-fit: contain)
|
|
|
|
|
+ // 图片可能不会完全填满容器,需要计算实际显示区域
|
|
|
|
|
+ let displayWidth, displayHeight, offsetX, offsetY;
|
|
|
|
|
+
|
|
|
|
|
+ if (img.naturalWidth && img.naturalHeight) {
|
|
|
|
|
+ // 获取图片的原始尺寸
|
|
|
|
|
+ const imgAspect = img.naturalWidth / img.naturalHeight;
|
|
|
|
|
+ const containerAspect = rect.width / rect.height;
|
|
|
|
|
+
|
|
|
|
|
+ if (imgAspect > containerAspect) {
|
|
|
|
|
+ // 图片更宽,以宽度为准(左右可能有黑边)
|
|
|
|
|
+ displayWidth = rect.width;
|
|
|
|
|
+ displayHeight = rect.width / imgAspect;
|
|
|
|
|
+ offsetX = 0;
|
|
|
|
|
+ offsetY = (rect.height - displayHeight) / 2;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 图片更高,以高度为准(上下可能有黑边)
|
|
|
|
|
+ displayHeight = rect.height;
|
|
|
|
|
+ displayWidth = rect.height * imgAspect;
|
|
|
|
|
+ offsetX = (rect.width - displayWidth) / 2;
|
|
|
|
|
+ offsetY = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果图片尺寸未知,使用容器尺寸
|
|
|
|
|
+ displayWidth = rect.width;
|
|
|
|
|
+ displayHeight = rect.height;
|
|
|
|
|
+ offsetX = 0;
|
|
|
|
|
+ offsetY = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算鼠标相对于实际显示区域的位置
|
|
|
|
|
+ const relativeX = (clientX - rect.left - offsetX) / displayWidth;
|
|
|
|
|
+ const relativeY = (clientY - rect.top - offsetY) / displayHeight;
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否在有效显示区域内(0-1之间)
|
|
|
|
|
+ if (relativeX < 0 || relativeX > 1 || relativeY < 0 || relativeY > 1) {
|
|
|
|
|
+ // 点击在显示区域外(黑边区域),返回 null
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 转换为设备坐标
|
|
// 转换为设备坐标
|
|
|
- const deviceX = Math.round(relativeX * DEVICE_WIDTH);
|
|
|
|
|
- const deviceY = Math.round(relativeY * DEVICE_HEIGHT);
|
|
|
|
|
|
|
+ const deviceX = Math.round(relativeX * deviceResolution.width);
|
|
|
|
|
+ const deviceY = Math.round(relativeY * deviceResolution.height);
|
|
|
|
|
|
|
|
// 确保坐标在设备范围内
|
|
// 确保坐标在设备范围内
|
|
|
- const clampedX = Math.max(0, Math.min(DEVICE_WIDTH - 1, deviceX));
|
|
|
|
|
- const clampedY = Math.max(0, Math.min(DEVICE_HEIGHT - 1, deviceY));
|
|
|
|
|
|
|
+ const clampedX = Math.max(0, Math.min(deviceResolution.width - 1, deviceX));
|
|
|
|
|
+ const clampedY = Math.max(0, Math.min(deviceResolution.height - 1, deviceY));
|
|
|
|
|
|
|
|
return { x: clampedX, y: clampedY };
|
|
return { x: clampedX, y: clampedY };
|
|
|
- }, [imageRef]);
|
|
|
|
|
|
|
+ }, [imageRef, deviceResolution]);
|
|
|
|
|
|
|
|
// 发送 tap 事件到设备
|
|
// 发送 tap 事件到设备
|
|
|
const sendTap = useCallback(async (x, y) => {
|
|
const sendTap = useCallback(async (x, y) => {
|