import React, { useEffect, useMemo, useState } from 'react'
import styled, { keyframes } from 'styled-components'
interface StyledAnimationProps {
animation: ReturnType<typeof keyframes> | null
}
const SEQUENCE_FRAME_COUNT = 55
const FireworksAnimation = () => {
const [frameAnimation, setFrameAnimation] = useState<ReturnType<typeof keyframes> | null>(null)
const [isFramesLoaded, setIsFramesLoaded] = useState(false)
const loadFrames = async () => {
try {
const frameImports = await Promise.all(
Array.from({ length: SEQUENCE_FRAME_COUNT }, (_, index) =>
import(`@/assets/images/pk/fireworksAnimation/fireworks${index + 1}.webp`).then(module => module.default)
)
)
const framesCount = SEQUENCE_FRAME_COUNT
const getURL = (index: number) => frameImports[index].src
const generatedFrames = Array.from({ length: framesCount }, (_, frameIndex) => {
const imageURL = getURL(frameIndex)
if (++frameIndex === framesCount) {
return `
100% {
background-image: url(${imageURL});
background-size: cover;
}
`
}
return `
${frameIndex * (100 / framesCount)}% {
background-image: url(${imageURL});
background-size: cover;
}
`
})
const animation = keyframes`
${generatedFrames.join('')}
`
setFrameAnimation(animation)
setIsFramesLoaded(true)
} catch (error) {
console.error('Error loading frames:', error)
}
}
useEffect(() => {
if (!isFramesLoaded) {
loadFrames()
}
}, [isFramesLoaded])
const memoizedAnimation = useMemo(() => frameAnimation, [frameAnimation])
return (
<StyledFireworksAnimation>
{isFramesLoaded && <StyledAnimation animation={memoizedAnimation} />}
</StyledFireworksAnimation>
)
}
const StyledFireworksAnimation = styled.div`
width: 370px;
height: 200px;
position: absolute;
z-index: 3;
top: -110px;
`
const StyledAnimation = styled.div<StyledAnimationProps>`
width: 100%;
height: 100%;
animation: ${props => props.animation} 5s linear;
animation-fill-mode: forwards;
`
export default FireworksAnimation