Last active
February 4, 2024 12:43
-
-
Save mateuszsokola/80b2a939ad521eb26f488fcdc659e0ca to your computer and use it in GitHub Desktop.
MobileSwiper from 2048-in-react
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useEffect, useState, useRef } from "react"; | |
/** | |
* MobileSwiper component for handling touch swipe gestures on mobile devices. | |
* | |
* @component | |
* @param {Object} props - React component props | |
* @param {ReactNode} props.children - The content to be wrapped by the swiper | |
* @param {function} props.onSwipe - Callback function triggered on swipe with an object containing deltaX and deltaY | |
* @returns {JSX.Element} - React component | |
* | |
* @author Matéush | |
* @github https://github.com/mateuszsokola | |
* @twitter https://twitter.com/msokola | |
*/ | |
export default function MobileSwiper({ children, onSwipe }) { | |
const wrapperRef = useRef(null); | |
const [startX, setStartX] = useState(0); | |
const [startY, setStartY] = useState(0); | |
const handleTouchStart = useCallback((e) => { | |
if (!wrapperRef.current.contains(e.target)) { | |
return; | |
} | |
e.preventDefault(); | |
setStartX(e.touches[0].clientX); | |
setStartY(e.touches[0].clientY); | |
}, []); | |
const handleTouchEnd = useCallback( | |
(e) => { | |
if (!wrapperRef.current.contains(e.target)) { | |
return; | |
} | |
e.preventDefault(); | |
const endX = e.changedTouches[0].clientX; | |
const endY = e.changedTouches[0].clientY; | |
const deltaX = endX - startX; | |
const deltaY = endY - startY; | |
onSwipe({ deltaX, deltaY }); | |
}, | |
[startX, startY, onSwipe], | |
); | |
useEffect(() => { | |
window.addEventListener("touchstart", handleTouchStart, { passive: false }); | |
window.addEventListener("touchend", handleTouchEnd, { passive: false }); | |
return () => { | |
window.removeEventListener("touchstart", handleTouchStart); | |
window.removeEventListener("touchend", handleTouchEnd); | |
}; | |
}, [handleTouchStart, handleTouchEnd]); | |
return <div ref={wrapperRef}>{children}</div>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment