import { useCallback, useEffect, useRef, useState } from 'react'
interface MobileSwiperProps {
children: React.ReactNode
onSwipe: ({ deltaX, deltaY }: { deltaX: number; deltaY?: number }) => void
}
export default function MobileSwiper({ children, onSwipe }: MobileSwiperProps) {
const wrapperRef = useRef<HTMLDivElement>(null)
const [startX, setStartX] = useState(0)
const [startY, setStartY] = useState(0)
// 터치 시작시 유저 터치 중인 위치 저장
const handleTouchStart = useCallback((e) => {
if (!wrapperRef.current.contains(e.target as Node)) return
e.preventDefault()
setStartX(e.touches[0].clientX)
setStartY(e.touches[0].clientY)
}, [])
const handleTouchEnd = useCallback(
(e) => {
if (!wrapperRef.current.contains(e.target as Node)) 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)
window.addEventListener('touchend', handleTouchEnd)
return () => {
window.removeEventListener('touchstart', handleTouchStart)
window.removeEventListener('touchend', handleTouchEnd)
}
}, [handleTouchStart, handleTouchEnd])
return <div ref={wrapperRef}>{children}</div>
}
참고: https://www.freecodecamp.org/news/how-to-build-mobile-swiping-component-in-react/