同时支持触摸和鼠标事件翻页
This commit is contained in:
@@ -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;
|
const isDev = !app.isPackaged;
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
|
|||||||
@@ -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 { Document, Page, pdfjs } from "react-pdf";
|
||||||
import "react-pdf/dist/esm/Page/AnnotationLayer.css";
|
import "react-pdf/dist/esm/Page/AnnotationLayer.css";
|
||||||
import "./UI8.css";
|
import "./UI8.css";
|
||||||
@@ -143,7 +143,7 @@ const UI8: React.FC = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const goToPrevPage = () => {
|
const goToPrevPage = useCallback(() => {
|
||||||
if (isAnimating || pageNumber <= 1) return;
|
if (isAnimating || pageNumber <= 1) return;
|
||||||
setIsAnimating(true);
|
setIsAnimating(true);
|
||||||
setAnimationDirection("down");
|
setAnimationDirection("down");
|
||||||
@@ -152,9 +152,9 @@ const UI8: React.FC = () => {
|
|||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
setAnimationDirection(null);
|
setAnimationDirection(null);
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
}, [isAnimating, pageNumber]);
|
||||||
|
|
||||||
const goToNextPage = () => {
|
const goToNextPage = useCallback(() => {
|
||||||
if (isAnimating || pageNumber >= numPages) return;
|
if (isAnimating || pageNumber >= numPages) return;
|
||||||
setIsAnimating(true);
|
setIsAnimating(true);
|
||||||
setAnimationDirection("up");
|
setAnimationDirection("up");
|
||||||
@@ -163,19 +163,24 @@ const UI8: React.FC = () => {
|
|||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
setAnimationDirection(null);
|
setAnimationDirection(null);
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
}, [isAnimating, pageNumber, numPages]);
|
||||||
|
|
||||||
// 监听触摸事件实现上下滑动翻页
|
// 监听触摸和鼠标事件实现上下滑动翻页
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = scrollContainerRef.current;
|
const container = scrollContainerRef.current;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
let isDragging = false;
|
||||||
|
let startY = 0;
|
||||||
|
|
||||||
|
// 触摸事件处理
|
||||||
const handleTouchStart = (e: TouchEvent) => {
|
const handleTouchStart = (e: TouchEvent) => {
|
||||||
const touch = e.touches[0];
|
const touch = e.touches[0];
|
||||||
touchStartRef.current = {
|
touchStartRef.current = {
|
||||||
x: touch.clientX,
|
x: touch.clientX,
|
||||||
y: touch.clientY,
|
y: touch.clientY,
|
||||||
};
|
};
|
||||||
|
window.electronAPI?.log("info", `触摸开始: (${touch.clientX}, ${touch.clientY})`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTouchEnd = (e: TouchEvent) => {
|
const handleTouchEnd = (e: TouchEvent) => {
|
||||||
@@ -185,14 +190,18 @@ const UI8: React.FC = () => {
|
|||||||
const deltaX = touch.clientX - touchStartRef.current.x;
|
const deltaX = touch.clientX - touchStartRef.current.x;
|
||||||
const deltaY = touch.clientY - touchStartRef.current.y;
|
const deltaY = touch.clientY - touchStartRef.current.y;
|
||||||
|
|
||||||
|
window.electronAPI?.log("info", `触摸结束: delta(${deltaX}, ${deltaY})`);
|
||||||
|
|
||||||
// 判断是否为有效滑动(至少50px,且垂直滑动大于水平滑动)
|
// 判断是否为有效滑动(至少50px,且垂直滑动大于水平滑动)
|
||||||
const minSwipeDistance = 50;
|
const minSwipeDistance = 50;
|
||||||
if (Math.abs(deltaY) > minSwipeDistance && Math.abs(deltaY) > Math.abs(deltaX)) {
|
if (Math.abs(deltaY) > minSwipeDistance && Math.abs(deltaY) > Math.abs(deltaX)) {
|
||||||
if (deltaY < 0) {
|
if (deltaY < 0) {
|
||||||
// 向上滑动 = 下一页
|
// 向上滑动 = 下一页
|
||||||
|
window.electronAPI?.log("info", "向上滑动 -> 下一页");
|
||||||
goToNextPage();
|
goToNextPage();
|
||||||
} else if (deltaY > 0) {
|
} else if (deltaY > 0) {
|
||||||
// 向下滑动 = 上一页
|
// 向下滑动 = 上一页
|
||||||
|
window.electronAPI?.log("info", "向下滑动 -> 上一页");
|
||||||
goToPrevPage();
|
goToPrevPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,16 +213,70 @@ const UI8: React.FC = () => {
|
|||||||
touchStartRef.current = null;
|
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("touchstart", handleTouchStart, { passive: true });
|
||||||
container.addEventListener("touchend", handleTouchEnd, { passive: true });
|
container.addEventListener("touchend", handleTouchEnd, { passive: true });
|
||||||
container.addEventListener("touchcancel", handleTouchCancel, { 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 () => {
|
return () => {
|
||||||
|
// 清理触摸事件
|
||||||
container.removeEventListener("touchstart", handleTouchStart);
|
container.removeEventListener("touchstart", handleTouchStart);
|
||||||
container.removeEventListener("touchend", handleTouchEnd);
|
container.removeEventListener("touchend", handleTouchEnd);
|
||||||
container.removeEventListener("touchcancel", handleTouchCancel);
|
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 (
|
return (
|
||||||
<div className="basic-root">
|
<div className="basic-root">
|
||||||
|
|||||||
Reference in New Issue
Block a user