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
This commit is contained in:
Wujiao233 2023-01-19 20:57:03 +08:00 committed by GitHub
parent a5f3b051f2
commit b8ab43aa25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -30,6 +30,8 @@ const defaultState: State = {
const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }: Props) => { const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }: Props) => {
const [currentIndex, setCurrentIndex] = useState(initialIndex); const [currentIndex, setCurrentIndex] = useState(initialIndex);
const [state, setState] = useState<State>(defaultState); const [state, setState] = useState<State>(defaultState);
let startX = -1;
let endX = -1;
const handleCloseBtnClick = () => { const handleCloseBtnClick = () => {
destroy(); destroy();
@ -42,21 +44,63 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
a.click(); 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) => { const handleImgContainerClick = (event: React.MouseEvent) => {
if (event.clientX < window.innerWidth / 2) { if (event.clientX < window.innerWidth / 2) {
if (currentIndex > 0) { showPrevImg();
setState(defaultState);
setCurrentIndex(currentIndex - 1);
} else {
destroy();
}
} else { } else {
if (currentIndex < imgUrls.length - 1) { showNextImg();
setState(defaultState);
setCurrentIndex(currentIndex + 1);
} else {
destroy();
}
} }
}; };
@ -111,6 +155,9 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
<div className="img-container" onClick={handleImgContainerClick}> <div className="img-container" onClick={handleImgContainerClick}>
<img <img
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
src={imgUrls[currentIndex]} src={imgUrls[currentIndex]}
onWheel={handleImgContainerScroll} onWheel={handleImgContainerScroll}
style={getImageComputedStyle()} style={getImageComputedStyle()}