40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
const COLOR_MAP = {
|
|
cyan: "from-cyan-400/60 to-cyan-300/30",
|
|
violet: "from-violet-400/60 to-violet-300/30",
|
|
fuchsia: "from-fuchsia-400/60 to-fuchsia-300/30",
|
|
} as const;
|
|
|
|
type ParticleColor = keyof typeof COLOR_MAP;
|
|
|
|
const PARTICLES = Array.from({ length: 60 }, (_, i) => ({
|
|
size: 2 + (i % 5),
|
|
left: (i * 17.3) % 100,
|
|
top: (i * 23.7) % 100,
|
|
duration: 12 + (i % 10),
|
|
delay: (i * 0.4) % 6,
|
|
color: (i % 3 === 0 ? "cyan" : i % 3 === 1 ? "violet" : "fuchsia") as ParticleColor,
|
|
}));
|
|
|
|
export function Particles() {
|
|
return (
|
|
<div className="pointer-events-none absolute inset-0 overflow-hidden">
|
|
{PARTICLES.map((p, i) => (
|
|
<div
|
|
key={i}
|
|
className={`absolute rounded-full bg-gradient-to-br ${COLOR_MAP[p.color]} blur-[0.5px]`}
|
|
style={{
|
|
width: `${p.size}px`,
|
|
height: `${p.size}px`,
|
|
left: `${p.left}%`,
|
|
top: `${p.top}%`,
|
|
animation: `float ${p.duration}s ease-in-out infinite, twinkle ${3 + (i % 4)}s ease-in-out infinite`,
|
|
animationDelay: `${p.delay}s`,
|
|
}}
|
|
/>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|