|
"use client" |
|
|
|
import { useEffect, useRef } from "react" |
|
import { motion } from "framer-motion" |
|
|
|
export default function FlameAnimation() { |
|
const flameRef = useRef<HTMLDivElement>(null) |
|
|
|
useEffect(() => { |
|
const flame = flameRef.current |
|
if (!flame) return |
|
|
|
const createFlameParticle = () => { |
|
const particle = document.createElement("div") |
|
particle.className = "flame-particle" |
|
particle.style.cssText = ` |
|
position: absolute; |
|
width: ${Math.random() * 6 + 2}px; |
|
height: ${Math.random() * 6 + 2}px; |
|
background: radial-gradient(circle, #ff6b35, #f7931e); |
|
border-radius: 50%; |
|
bottom: 0; |
|
left: ${Math.random() * 100}%; |
|
animation: flameRise ${Math.random() * 2 + 1}s ease-out forwards; |
|
pointer-events: none; |
|
` |
|
|
|
flame.appendChild(particle) |
|
|
|
setTimeout(() => { |
|
if (particle.parentNode) { |
|
particle.parentNode.removeChild(particle) |
|
} |
|
}, 3000) |
|
} |
|
|
|
const interval = setInterval(createFlameParticle, 100) |
|
|
|
return () => clearInterval(interval) |
|
}, []) |
|
|
|
return ( |
|
<div className="relative"> |
|
<style jsx>{` |
|
@keyframes flameRise { |
|
0% { |
|
transform: translateY(0) scale(1); |
|
opacity: 1; |
|
} |
|
50% { |
|
transform: translateY(-30px) scale(1.2); |
|
opacity: 0.8; |
|
} |
|
100% { |
|
transform: translateY(-60px) scale(0.5); |
|
opacity: 0; |
|
} |
|
} |
|
`}</style> |
|
|
|
<motion.div |
|
className="relative w-24 h-24 mx-auto" |
|
animate={{ |
|
scale: [1, 1.1, 1], |
|
rotate: [0, 5, -5, 0], |
|
}} |
|
transition={{ |
|
duration: 2, |
|
repeat: Number.POSITIVE_INFINITY, |
|
ease: "easeInOut", |
|
}} |
|
> |
|
<div |
|
ref={flameRef} |
|
className="relative w-full h-full overflow-hidden" |
|
style={{ |
|
background: "radial-gradient(ellipse at bottom, #ff6b35 0%, #f7931e 50%, transparent 70%)", |
|
borderRadius: "50% 50% 50% 50% / 60% 60% 40% 40%", |
|
}} |
|
/> |
|
|
|
{/* Core flame */} |
|
<motion.div |
|
className="absolute inset-0" |
|
style={{ |
|
background: "radial-gradient(ellipse at bottom, #ffaa00 0%, #ff6b35 40%, transparent 70%)", |
|
borderRadius: "50% 50% 50% 50% / 60% 60% 40% 40%", |
|
}} |
|
animate={{ |
|
scale: [0.8, 1, 0.8], |
|
opacity: [0.8, 1, 0.8], |
|
}} |
|
transition={{ |
|
duration: 1.5, |
|
repeat: Number.POSITIVE_INFINITY, |
|
ease: "easeInOut", |
|
}} |
|
/> |
|
</motion.div> |
|
</div> |
|
) |
|
} |
|
|