From 95abb52d81aec1e5fdcb91696dd48236e9a240d8 Mon Sep 17 00:00:00 2001 From: Kakabay <2kakabayashyrberdyew@gmail.com> Date: Tue, 24 Dec 2024 18:33:55 +0500 Subject: [PATCH] counter roll back ready --- .../lottery/RollingCounter/RollingCounter.tsx | 80 ++++++++++++++----- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/components/lottery/RollingCounter/RollingCounter.tsx b/components/lottery/RollingCounter/RollingCounter.tsx index 9d5ee9c..7bbf77d 100644 --- a/components/lottery/RollingCounter/RollingCounter.tsx +++ b/components/lottery/RollingCounter/RollingCounter.tsx @@ -1,6 +1,6 @@ 'use client'; import { motion } from 'framer-motion'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState, useRef } from 'react'; interface RollingCounterProps { numberString: string; @@ -55,6 +55,7 @@ const RollingDigit = ({ isStopped, showHyphen, totalDigits, + isRollingBack, }: { targetValue: number; index: number; @@ -62,6 +63,7 @@ const RollingDigit = ({ isStopped: boolean; showHyphen: boolean; totalDigits: number; + isRollingBack: boolean; }) => { const numbers = useMemo(() => getNumbers(targetValue), [targetValue]); @@ -71,11 +73,13 @@ const RollingDigit = ({ {num} @@ -98,18 +102,19 @@ const RollingDigit = ({ const RollingCounter: React.FC = ({ numberString }) => { const [isStopped, setIsStopped] = useState([]); + const [isRollingBack, setIsRollingBack] = useState(false); + const [isTransitioning, setIsTransitioning] = useState(false); + const [currentNumbers, setCurrentNumbers] = useState([]); + const prevNumberStringRef = useRef(numberString); const { numbers, isInitialLoading } = useMemo(() => { if (!numberString) { return { numbers: [], isInitialLoading: true }; } - const parsed = numberString - .replace(/-/g, '') - .split('') - .map((char) => parseInt(char, 10)); - - setIsStopped(new Array(parsed.length).fill(false)); + const parsed = numberString.split('-').flatMap((pair) => { + return pair.split('').map((char) => parseInt(char, 10)); + }); return { numbers: parsed, @@ -117,13 +122,45 @@ const RollingCounter: React.FC = ({ numberString }) => { }; }, [numberString]); - const handleAnimationComplete = useCallback((index: number) => { - setIsStopped((prev) => { - const newState = [...prev]; - newState[index] = true; - return newState; - }); - }, []); + // Initialize currentNumbers + useEffect(() => { + if (!currentNumbers.length && numbers.length) { + setCurrentNumbers(numbers); + } + }, [numbers, currentNumbers.length]); + + // Handle number changes + useEffect(() => { + if (prevNumberStringRef.current !== numberString && !isRollingBack) { + setIsTransitioning(true); + setIsRollingBack(true); + setIsStopped(new Array(numbers.length).fill(false)); + + setTimeout(() => { + setIsRollingBack(false); + setCurrentNumbers(numbers); + prevNumberStringRef.current = numberString; + }, 2000); + } + }, [numberString, numbers, isRollingBack]); + + const handleAnimationComplete = useCallback( + (index: number) => { + if (!isRollingBack) { + setIsStopped((prev) => { + const newState = [...prev]; + newState[index] = true; + + if (newState.every((stopped) => stopped)) { + setIsTransitioning(false); + } + + return newState; + }); + } + }, + [isRollingBack], + ); if (isInitialLoading) { return ( @@ -135,15 +172,16 @@ const RollingCounter: React.FC = ({ numberString }) => { return (
- {numbers.map((num, index) => ( + {currentNumbers.map((num, index) => ( handleAnimationComplete(index)} - isStopped={isStopped[index]} + isStopped={isStopped[index] && !isTransitioning} showHyphen={(index + 1) % 2 === 0 && index !== numbers.length - 1} totalDigits={numbers.length} + isRollingBack={isRollingBack} /> ))}