Animated BlackBox with Meteors falling down.
"use client";
import { Meteors } from "@/components/ui/meteors";
import { cn } from "@/utils/cn";
import { useEffect, useState } from "react";
export const Meteors = ({ number, className }: { number?: number; className?: string }) => {
const [meteors, setMeteors] = useState<{ left: string; animationDelay: string; animationDuration: string }[]>([]);
useEffect(() => {
const generatedMeteors = new Array(number || 20).fill(true).map(() => ({
left: Math.floor(Math.random() * (400 - -400) + -400) + "px",
animationDelay: Math.random() * (0.8 - 0.2) + 0.2 + "s",
animationDuration: Math.floor(Math.random() * (10 - 2) + 2) + "s",
}));
setMeteors(generatedMeteors);
}, [number]);
return (
<>
{meteors.map((meteor, idx) => (
<span
key={"meteor" + idx}
className={cn(
"animate-meteor-effect absolute top-1/2 left-1/2 h-0.5 w-0.5 rounded-[9999px] rotate-180",
"before:content-[''] before:absolute before:top-1/2 before:transform before:-translate-y-[50%] before:w-[50px] before:h-[1px] before:bg-gradient-to-r before:from-[#64748b] before:to-transparent",
className
)}
style={{
top: 0,
left: meteor.left,
animationDelay: meteor.animationDelay,
animationDuration: meteor.animationDuration,
}}
></span>
))}
</>
);
};
const BlackBox = () => {
return (
<div className="absolute overflow-hidden h-[400px] w-[400px] rotate-45 z-0 backdrop-blur-sm bg-black/40 shadow-lg shadow-red-900">
<Meteors number={20} />
</div>
);
};
export default BlackBox;