From b8ab43aa2505b005cb6cb5bc333c0163d3dd686c Mon Sep 17 00:00:00 2001 From: Wujiao233 Date: Thu, 19 Jan 2023 20:57:03 +0800 Subject: [PATCH] feat: support swipe to switch img on touchscreen (#970) * feat: support swipe to switch img on touchscreen * fix: fix two or more fingers touch * fix lint --- web/src/components/PreviewImageDialog.tsx | 71 +++++++++++++++++++---- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/web/src/components/PreviewImageDialog.tsx b/web/src/components/PreviewImageDialog.tsx index e60f8796..e045dd06 100644 --- a/web/src/components/PreviewImageDialog.tsx +++ b/web/src/components/PreviewImageDialog.tsx @@ -30,6 +30,8 @@ const defaultState: State = { const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }: Props) => { const [currentIndex, setCurrentIndex] = useState(initialIndex); const [state, setState] = useState(defaultState); + let startX = -1; + let endX = -1; const handleCloseBtnClick = () => { destroy(); @@ -42,21 +44,63 @@ const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }: a.click(); }; + const handleTouchStart = (event: React.TouchEvent) => { + if (event.touches.length > 1) { + // two or more fingers, ignore + return; + } + startX = event.touches[0].clientX; + }; + + const handleTouchMove = (event: React.TouchEvent) => { + if (event.touches.length > 1) { + // two or more fingers, ignore + return; + } + endX = event.touches[0].clientX; + }; + + const handleTouchEnd = (event: React.TouchEvent) => { + if (event.touches.length > 1) { + // two or more fingers, ignore + return; + } + if (startX > -1 && endX > -1) { + const distance = startX - endX; + if (distance > 50) { + showNextImg(); + } else if (distance < -50) { + showPrevImg(); + } + } + + endX = -1; + startX = -1; + }; + + const showPrevImg = () => { + if (currentIndex > 0) { + setState(defaultState); + setCurrentIndex(currentIndex - 1); + } else { + destroy(); + } + }; + + const showNextImg = () => { + if (currentIndex < imgUrls.length - 1) { + setState(defaultState); + setCurrentIndex(currentIndex + 1); + } else { + destroy(); + } + }; + const handleImgContainerClick = (event: React.MouseEvent) => { if (event.clientX < window.innerWidth / 2) { - if (currentIndex > 0) { - setState(defaultState); - setCurrentIndex(currentIndex - 1); - } else { - destroy(); - } + showPrevImg(); } else { - if (currentIndex < imgUrls.length - 1) { - setState(defaultState); - setCurrentIndex(currentIndex + 1); - } else { - destroy(); - } + showNextImg(); } }; @@ -111,6 +155,9 @@ const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }:
e.stopPropagation()} + onTouchStart={handleTouchStart} + onTouchMove={handleTouchMove} + onTouchEnd={handleTouchEnd} src={imgUrls[currentIndex]} onWheel={handleImgContainerScroll} style={getImageComputedStyle()}