diff --git a/electron/main.js b/electron/main.js index 657ff95..00e1401 100644 --- a/electron/main.js +++ b/electron/main.js @@ -68,6 +68,19 @@ function createWindow() { }, }); + // 启用触摸事件支持(Windows 触摸屏) + mainWindow.webContents.on("did-finish-load", () => { + // 注入触摸事件支持脚本 + mainWindow.webContents.executeJavaScript(` + // 确保触摸事件可用 + if (navigator.maxTouchPoints === 0) { + console.log('[Electron] 未检测到触摸设备,将使用鼠标事件模拟'); + } else { + console.log('[Electron] 检测到触摸设备,触摸点数:', navigator.maxTouchPoints); + } + `).catch(err => log.error("Failed to inject touch support:", err)); + }); + const isDev = !app.isPackaged; if (isDev) { diff --git a/src/pages/UI8/UI8.tsx b/src/pages/UI8/UI8.tsx index 62aed2f..9cb2756 100644 --- a/src/pages/UI8/UI8.tsx +++ b/src/pages/UI8/UI8.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from "react"; +import React, { useState, useRef, useEffect, useCallback } from "react"; import { Document, Page, pdfjs } from "react-pdf"; import "react-pdf/dist/esm/Page/AnnotationLayer.css"; import "./UI8.css"; @@ -143,7 +143,7 @@ const UI8: React.FC = () => { setLoading(false); }; - const goToPrevPage = () => { + const goToPrevPage = useCallback(() => { if (isAnimating || pageNumber <= 1) return; setIsAnimating(true); setAnimationDirection("down"); @@ -152,9 +152,9 @@ const UI8: React.FC = () => { setIsAnimating(false); setAnimationDirection(null); }, 300); - }; + }, [isAnimating, pageNumber]); - const goToNextPage = () => { + const goToNextPage = useCallback(() => { if (isAnimating || pageNumber >= numPages) return; setIsAnimating(true); setAnimationDirection("up"); @@ -163,19 +163,24 @@ const UI8: React.FC = () => { setIsAnimating(false); setAnimationDirection(null); }, 300); - }; + }, [isAnimating, pageNumber, numPages]); - // 监听触摸事件实现上下滑动翻页 + // 监听触摸和鼠标事件实现上下滑动翻页 useEffect(() => { const container = scrollContainerRef.current; if (!container) return; + let isDragging = false; + let startY = 0; + + // 触摸事件处理 const handleTouchStart = (e: TouchEvent) => { const touch = e.touches[0]; touchStartRef.current = { x: touch.clientX, y: touch.clientY, }; + window.electronAPI?.log("info", `触摸开始: (${touch.clientX}, ${touch.clientY})`); }; const handleTouchEnd = (e: TouchEvent) => { @@ -185,14 +190,18 @@ const UI8: React.FC = () => { const deltaX = touch.clientX - touchStartRef.current.x; const deltaY = touch.clientY - touchStartRef.current.y; + window.electronAPI?.log("info", `触摸结束: delta(${deltaX}, ${deltaY})`); + // 判断是否为有效滑动(至少50px,且垂直滑动大于水平滑动) const minSwipeDistance = 50; if (Math.abs(deltaY) > minSwipeDistance && Math.abs(deltaY) > Math.abs(deltaX)) { if (deltaY < 0) { // 向上滑动 = 下一页 + window.electronAPI?.log("info", "向上滑动 -> 下一页"); goToNextPage(); } else if (deltaY > 0) { // 向下滑动 = 上一页 + window.electronAPI?.log("info", "向下滑动 -> 上一页"); goToPrevPage(); } } @@ -204,16 +213,70 @@ const UI8: React.FC = () => { touchStartRef.current = null; }; + // 鼠标事件处理(作为触摸的后备方案) + const handleMouseDown = (e: MouseEvent) => { + isDragging = true; + startY = e.clientY; + window.electronAPI?.log("info", `鼠标按下: (${e.clientX}, ${e.clientY})`); + }; + + const handleMouseMove = (e: MouseEvent) => { + if (!isDragging) return; + // 防止页面滚动 + e.preventDefault(); + }; + + const handleMouseUp = (e: MouseEvent) => { + if (!isDragging) return; + + const deltaY = e.clientY - startY; + window.electronAPI?.log("info", `鼠标释放: deltaY=${deltaY}`); + + // 判断是否为有效滑动(至少50px) + const minSwipeDistance = 50; + if (Math.abs(deltaY) > minSwipeDistance) { + if (deltaY < 0) { + // 向上拖动 = 下一页 + window.electronAPI?.log("info", "向上拖动 -> 下一页"); + goToNextPage(); + } else if (deltaY > 0) { + // 向下拖动 = 上一页 + window.electronAPI?.log("info", "向下拖动 -> 上一页"); + goToPrevPage(); + } + } + + isDragging = false; + }; + + // 注册触摸事件 container.addEventListener("touchstart", handleTouchStart, { passive: true }); container.addEventListener("touchend", handleTouchEnd, { passive: true }); container.addEventListener("touchcancel", handleTouchCancel, { passive: true }); + // 鼠标离开处理 + const handleMouseLeave = () => { + isDragging = false; + }; + + // 注册鼠标事件(作为后备) + container.addEventListener("mousedown", handleMouseDown); + container.addEventListener("mousemove", handleMouseMove); + container.addEventListener("mouseup", handleMouseUp); + container.addEventListener("mouseleave", handleMouseLeave); + return () => { + // 清理触摸事件 container.removeEventListener("touchstart", handleTouchStart); container.removeEventListener("touchend", handleTouchEnd); container.removeEventListener("touchcancel", handleTouchCancel); + // 清理鼠标事件 + container.removeEventListener("mousedown", handleMouseDown); + container.removeEventListener("mousemove", handleMouseMove); + container.removeEventListener("mouseup", handleMouseUp); + container.removeEventListener("mouseleave", handleMouseLeave); }; - }, [numPages, pageNumber]); + }, [goToNextPage, goToPrevPage]); return (