last work on lottery/
This commit is contained in:
parent
28d98cd790
commit
687a7f0f81
|
|
@ -329,6 +329,11 @@ big {
|
|||
.rolling-number {
|
||||
@apply text-[24px] px-1;
|
||||
}
|
||||
|
||||
.slot-seperator {
|
||||
content: url('/dash-md.svg');
|
||||
@apply !mx-1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 320px) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { cn } from '@/lib/utils';
|
||||
import { motion } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
|
||||
interface AnimatedTextProps {
|
||||
text: string;
|
||||
|
|
@ -23,31 +23,38 @@ const AnimatedText = ({
|
|||
const characters = text.split('');
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden">
|
||||
<motion.div className="overflow-hidden">
|
||||
<motion.p
|
||||
className={cn(`flex `, className)}
|
||||
initial={{ translateY: initialY, opacity: 0 }}
|
||||
animate={{ translateY: 0, opacity: 1 }}
|
||||
exit={{ translateY: exitY, opacity: 0 }}>
|
||||
{characters.map((character, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ translateY: initialY, opacity: 0 }}
|
||||
animate={{ translateY: 0, opacity: 1 }}
|
||||
exit={{ translateY: exitY, opacity: 0 }}
|
||||
transition={{
|
||||
duration,
|
||||
delay: characterDelay + (i / 2) * duration,
|
||||
ease: 'easeOut',
|
||||
}}
|
||||
className={cn(`block `, characterClassName, {
|
||||
'animate-dotsFlash': text === '...',
|
||||
})}>
|
||||
{character}
|
||||
</motion.div>
|
||||
))}
|
||||
className={cn(`flex`, className)}
|
||||
variants={{
|
||||
enter: {
|
||||
transition: { staggerChildren: 1, delayChildren: 0.5 },
|
||||
},
|
||||
exit: {
|
||||
transition: { staggerChildren: 0.05, staggerDirection: -1 },
|
||||
},
|
||||
}}>
|
||||
<AnimatePresence>
|
||||
{characters.map((character, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ translateY: '-100%', opacity: 0 }}
|
||||
animate={{ translateY: 0, opacity: 1 }}
|
||||
exit={{ translateY: '100%', opacity: 0 }}
|
||||
transition={{
|
||||
duration,
|
||||
delay: characterDelay + (i / 5) * duration,
|
||||
ease: 'easeOut',
|
||||
}}
|
||||
className={cn(`block`, characterClassName, {
|
||||
'animate-dotsFlash': text === '...',
|
||||
})}>
|
||||
{character === ' ' ? '\u00A0' : character}
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</motion.p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import ReactConfetti from 'react-confetti';
|
||||
import { useWindowSize } from 'react-use';
|
||||
import { useMediaQuery } from 'usehooks-ts';
|
||||
|
||||
const Confetti = ({
|
||||
numberOfPieces = 200,
|
||||
|
|
@ -21,13 +22,15 @@ const Confetti = ({
|
|||
'#FF3131',
|
||||
];
|
||||
|
||||
const mobile = useMediaQuery('(max-width: 426px)');
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 z-50">
|
||||
<ReactConfetti
|
||||
width={width}
|
||||
height={height}
|
||||
recycle={showConfetti}
|
||||
numberOfPieces={numberOfPieces}
|
||||
numberOfPieces={mobile ? numberOfPieces / 3 : numberOfPieces}
|
||||
tweenDuration={500}
|
||||
// run={true}
|
||||
colors={colors}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ import { useWindowSize } from 'react-use';
|
|||
import AnimatedText from '@/components/common/AnimatedText';
|
||||
import { useWebsocketLottery } from '@/hooks/useWebSocketLottery';
|
||||
import Confetti from '../common/Confetti';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
|
||||
const WEBSOCKET_URL = 'wss://sms.turkmentv.gov.tm/ws/lottery?dst=0506';
|
||||
const SLOT_COUNTER_DURATION = 100000;
|
||||
const SLOT_COUNTER_DURATION = 30000;
|
||||
|
||||
const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) => {
|
||||
const [winners, setWinners] = useState<LotteryWinnerDataSimplified[]>([]);
|
||||
|
|
@ -39,7 +40,7 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
|
|||
setWinners(simplifiedWinners);
|
||||
setCurrentNumber(lotteryData.data.winners.at(-1)?.ticket || '00-00-00-00-00');
|
||||
setWinnerSelectingStatus('selected');
|
||||
setTopText('Ýeňiji');
|
||||
setTopText(`${lotteryData.data.winners.at(-1)?.winner_no}-nji(y) ýeňiji`);
|
||||
setBottomText(lotteryData.data.winners.at(-1)?.client || '');
|
||||
setIsConfettiActive(true);
|
||||
}
|
||||
|
|
@ -60,9 +61,7 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
|
|||
ticket: newWinner.ticket,
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
setIsConfettiActive(false);
|
||||
}, 1000);
|
||||
setIsConfettiActive(false);
|
||||
setTopText(`${winnerData.winner_no}-nji(y) ýeňiji saýlanýar`);
|
||||
setBottomText('...');
|
||||
setWinnerSelectingStatus('is-selecting');
|
||||
|
|
@ -70,12 +69,12 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
|
|||
setCurrentNumber(winnerData.ticket);
|
||||
|
||||
setTimeout(() => {
|
||||
setTopText('Ýeniji');
|
||||
setTopText(`${winnerData.winner_no}-nji(y) ýeňiji`);
|
||||
setBottomText(winnerData.client);
|
||||
setWinnerSelectingStatus('selected');
|
||||
setIsConfettiActive(true);
|
||||
setWinners((prev) => [...prev, winnerData]);
|
||||
}, SLOT_COUNTER_DURATION + 500);
|
||||
}, SLOT_COUNTER_DURATION);
|
||||
});
|
||||
|
||||
return () => {
|
||||
|
|
@ -83,6 +82,25 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
|
|||
};
|
||||
}, [subscribeToMessages]);
|
||||
|
||||
// useEffect(() => {
|
||||
// setTimeout(() => {
|
||||
// setIsConfettiActive(false);
|
||||
// setTopText(`${1}-nji(y) ýeňiji saýlanýar`);
|
||||
// setBottomText('...');
|
||||
// setWinnerSelectingStatus('is-selecting');
|
||||
// // setPendingWinner(winnerData);
|
||||
// setCurrentNumber('55-44-33-22-11');
|
||||
|
||||
// setTimeout(() => {
|
||||
// setTopText('Ýeniji');
|
||||
// setBottomText('99361245555');
|
||||
// setWinnerSelectingStatus('selected');
|
||||
// setIsConfettiActive(true);
|
||||
// // setWinners((prev) => [...prev, winnerData]);
|
||||
// }, SLOT_COUNTER_DURATION);
|
||||
// }, 10000);
|
||||
// }, []);
|
||||
|
||||
return (
|
||||
<section>
|
||||
{wsStatus === 'error' && (
|
||||
|
|
@ -95,47 +113,62 @@ const LotteryWinnersSection = ({ lotteryStatus }: { lotteryStatus: string }) =>
|
|||
style={{
|
||||
background: 'linear-gradient(180deg, #F0ECF4 0%, #E1E0FF 43.5%)',
|
||||
}}>
|
||||
<div className="flex items-center justify-center w-full min-h-[240px]">
|
||||
{winnerSelectingStatus === 'not-selected' ? (
|
||||
// <TextMaskReveal
|
||||
// text={topText}
|
||||
// className="text-center flex items-center justify-center text-[100px] leading-[108px] text-[#E65E19]"
|
||||
// duration={0.5}
|
||||
// />
|
||||
<AnimatedText
|
||||
text={topText}
|
||||
className="text-center flex items-center justify-center text-[100px] leading-[108px] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
{/* <TextMaskReveal
|
||||
<AnimatePresence>
|
||||
<div className="flex items-center justify-center w-full sm:min-h-[240px] pt-6">
|
||||
{winnerSelectingStatus === 'not-selected' ? (
|
||||
// <TextMaskReveal
|
||||
// text={topText}
|
||||
// className="text-center flex items-center justify-center text-[100px] leading-[108px] text-[#E65E19]"
|
||||
// duration={0.5}
|
||||
// />
|
||||
<AnimatedText
|
||||
key={topText}
|
||||
text={topText}
|
||||
className="text-center flex items-center justify-center sm:text-[100px] text-[48px] leading-[120%] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
/>
|
||||
) : (
|
||||
<motion.div
|
||||
variants={{
|
||||
enter: {
|
||||
transition: { staggerChildren: 1, delayChildren: 0.5 },
|
||||
},
|
||||
exit: {
|
||||
transition: { staggerChildren: 0.05, staggerDirection: -1 },
|
||||
},
|
||||
}}
|
||||
className="flex flex-col items-center justify-center">
|
||||
{/* <TextMaskReveal
|
||||
text={topText}
|
||||
className="text-center text-[56px] leading-[64px] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
/> */}
|
||||
<AnimatedText
|
||||
text={topText}
|
||||
className="text-center text-[56px] leading-[64px] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
/>
|
||||
{bottomText && (
|
||||
// <TextMaskReveal
|
||||
// text={bottomText}
|
||||
// className="text-center text-[80px] leading-[88px] text-[#E65E19]"
|
||||
// duration={0.4}
|
||||
// startDelay={3}
|
||||
// />
|
||||
<AnimatedText
|
||||
text={bottomText}
|
||||
className="text-center text-[80px] leading-[88px] text-[#E65E19]"
|
||||
key={topText}
|
||||
text={topText}
|
||||
className="text-center sm:text-[56px] text-[24px] w-full leading-[120%] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
characterDelay={1.3}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{bottomText && (
|
||||
// <TextMaskReveal
|
||||
// text={bottomText}
|
||||
// className="text-center text-[80px] leading-[88px] text-[#E65E19]"
|
||||
// duration={0.4}
|
||||
// startDelay={3}
|
||||
// />
|
||||
<AnimatedText
|
||||
key={bottomText}
|
||||
text={bottomText}
|
||||
className="text-center sm:text-[80px] text-[32px] leading-[120%] text-[#E65E19]"
|
||||
duration={0.4}
|
||||
// characterDelay={2}
|
||||
/>
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</AnimatePresence>
|
||||
|
||||
<div className="z-10">
|
||||
{currentNumber && <LotterySlotCounter numberString={currentNumber} />}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const LotterySlotCounter = ({ numberString }: LotterySlotCounterProps) => {
|
|||
alt="roller-triangle"
|
||||
width={24}
|
||||
height={24}
|
||||
className="absolute left-0 top-1/2 -translate-y-1/2 -translate-x-1/2 z-20"
|
||||
className="absolute left-0 top-1/2 -translate-y-1/2 -translate-x-2/3 z-20"
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
|
|
@ -45,7 +45,7 @@ const LotterySlotCounter = ({ numberString }: LotterySlotCounterProps) => {
|
|||
alt="roller-triangle"
|
||||
width={24}
|
||||
height={24}
|
||||
className="absolute right-0 top-1/2 -translate-y-1/2 translate-x-1/2 z-20 rotate-180"
|
||||
className="absolute right-0 top-1/2 -translate-y-1/2 translate-x-2/3 z-20 rotate-180"
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
|
|
@ -58,7 +58,7 @@ const LotterySlotCounter = ({ numberString }: LotterySlotCounterProps) => {
|
|||
)}
|
||||
|
||||
<div
|
||||
className="flex items-center h-fit md:max-w-[1132px] sm:max-w-[640px] max-w-[324px] w-full justify-center text-white md:py-4 md:px-6 rounded-full overflow-y-hidden overflow-x-visible relative border-4 border-lightPrimary"
|
||||
className="flex items-center h-fit md:max-w-[1132px] sm:max-w-[640px] max-w-[400px] w-full justify-center text-white md:py-4 md:px-6 rounded-full overflow-y-hidden overflow-x-visible relative border-4 border-lightPrimary"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(180deg, #454673 0%, #575992 10.5%, #575992 90%, #454673 100%)',
|
||||
|
|
|
|||
Loading…
Reference in New Issue