Created
May 31, 2023 15:32
-
-
Save ZowieTao/8372a7a61d8d2c70ab4dc3061732d0d2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
const Swiper = () => { | |
const [currentIndex, setCurrentIndex] = useState(0) | |
// eslint-disable-next-line no-unused-vars | |
const [_, forceUpdate] = useState<boolean>(true) | |
const slides = useMemo(() => { | |
const content0 = ( | |
<div className="flex w-full border rounded-xl aspect-[7/4] overflow-hidden"> | |
<div className="w-[232px]">side0</div> | |
<div className="flex-1">content0</div> | |
</div> | |
) | |
const content1 = ( | |
<div className="flex w-full border rounded-xl aspect-[7/4] overflow-hidden"> | |
<div className="w-[232px]">side1</div> | |
<div className="flex-1">content1</div> | |
</div> | |
) | |
const content2 = ( | |
<div className="flex w-full border rounded-xl aspect-[7/4] overflow-hidden"> | |
<div className="w-[232px]">side2</div> | |
<div className="flex-1">content2</div> | |
</div> | |
) | |
const content3 = ( | |
<div className="flex w-full border rounded-xl aspect-[7/4] overflow-hidden"> | |
<div className="w-[232px]">side3</div> | |
<div className="flex-1">content3</div> | |
</div> | |
) | |
const content4 = ( | |
<div className="flex w-full border rounded-xl aspect-[7/4] overflow-hidden"> | |
<div className="w-[232px]">side4</div> | |
<div className="flex-1">content4</div> | |
</div> | |
) | |
return [content0, content1, content2, content3, content4] | |
}, []) | |
const slidesLen = useMemo(() => { | |
return slides.length | |
}, [slides.length]) | |
const content0Ref = useRef(slides[currentIndex]) | |
const content1Ref = useRef(slides[(currentIndex + 1) % slidesLen]) | |
const content2Ref = useRef(slides[(currentIndex + 2) % slidesLen]) | |
const handlePrev = useCallback(() => { | |
setCurrentIndex((prevIndex) => { | |
return prevIndex - 1 | |
}) | |
setTimeout(() => { | |
const windowSize = 3 | |
const _currentCursor = currentIndex - 1 | |
const _idx = | |
_currentCursor < 0 | |
? windowSize - (Math.abs(_currentCursor) % windowSize) | |
: _currentCursor % windowSize | |
if (_idx === 0) { | |
content0Ref.current = slides[mod(_currentCursor, slidesLen)] | |
} else if (_idx === 1) { | |
content1Ref.current = slides[mod(_currentCursor, slidesLen)] | |
} else { | |
content2Ref.current = slides[mod(_currentCursor, slidesLen)] | |
} | |
forceUpdate((pre) => { | |
return !pre | |
}) | |
}) | |
}, [currentIndex, slides, slidesLen]) | |
const mod = (n: number, m: number) => { | |
return n < 0 ? m - (Math.abs(n) % m) : n % m | |
} | |
const handleNext = useCallback(() => { | |
setCurrentIndex((prevIndex) => { | |
return prevIndex + 1 | |
}) | |
setTimeout(() => { | |
const windowSize = 3 | |
const _idx = | |
currentIndex < 0 | |
? windowSize - (Math.abs(currentIndex) % windowSize) | |
: currentIndex % windowSize | |
const offset = currentIndex + windowSize | |
if (_idx === 0) { | |
content0Ref.current = slides[mod(offset, slidesLen) % slidesLen] | |
} else if (_idx === 1) { | |
content1Ref.current = slides[mod(offset, slidesLen) % slidesLen] | |
} else { | |
content2Ref.current = slides[mod(offset, slidesLen) % slidesLen] | |
} | |
forceUpdate((pre) => { | |
return !pre | |
}) | |
}, 100) | |
}, [currentIndex, slides, slidesLen]) | |
// const style1 = "flex pt-12 pl-16", | |
// style2 = "absolute flex w-full h-full pb-12 pr-16", | |
// style3 = "hidden" | |
// const [front, cycleFront] = useCycle(style1, style2, style3) | |
// const [back, cycleBack] = useCycle(style2, style3, style1) | |
// const [hidden, cycleHidden] = useCycle(style3, style1, style2) | |
return ( | |
<div className="relative w-full"> | |
<div className="w-full max-w-6xl mx-auto border border-red-800 relative"> | |
{/* font item: flex pt-12 pl-16 */} | |
<motion.div className="flex pt-12 pl-16"> | |
{content0Ref.current} | |
</motion.div> | |
{/* back item: absolute flex w-full h-full pb-12 pr-16 */} | |
<motion.div className="absolute flex top-0 w-full h-full pb-12 pr-16"> | |
{content1Ref.current} | |
</motion.div> | |
{/* hidden and prepare: hidden*/} | |
<motion.div className="absolute -top-12 -left-12"> | |
{content2Ref.current} | |
</motion.div> | |
</div> | |
<div className="absolute top-1/2 left-0 w-full flex justify-between"> | |
<button | |
className="px-4 py-2 bg-gray-500 text-white" | |
onClick={handlePrev} | |
> | |
< | |
</button> | |
<button | |
className="px-4 py-2 bg-gray-500 text-white" | |
onClick={handleNext} | |
> | |
> | |
</button> | |
</div> | |
</div> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment