ln / components /flame-animation.tsx
MoShow's picture
Upload 252 files
78d0e31 verified
"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>
)
}