AnimationMeteorsA simple meteor shower effect using Tailwind CSS and React.Preview Code global.css@theme { /* -------------------- Tailwind v4 ------------------------ */ --animate-meteor: meteor 0.2s linear infinite; @keyframes meteor { 0% { transform: rotate(200deg) translateX(0); opacity: 0%; } 70% { opacity: 100%; } 100% { transform: rotate(200deg) translateX(-500px); opacity: 0; } } } Meteors.tsx"use client"; import React, { useEffect, useState } from "react"; import clsx from "clsx"; import { twMerge } from "tailwind-merge"; const cn = (...args: any[]) => { return clsx(twMerge(...args)); }; export interface MeteorsProps { number?: number; } export const Meteors = ({ number = 20 }: MeteorsProps) => { const [meteorStyles, setMeteorStyles] = useState<Array<React.CSSProperties>>( [] ); useEffect(() => { const styles = [...new Array(number)].map(() => ({ top: -5, left: Math.floor(Math.random() * window.innerWidth) + "px", animationDelay: Math.random() * 1 + 0.2 + "s", animationDuration: Math.floor(Math.random() * 8 + 2) + "s", })); setMeteorStyles(styles); }, [number]); return ( <> {[...meteorStyles].map((style, idx) => ( <span key={idx} className={cn( "pointer-events-none absolute left-1/2 top-1/2 h-0.5 w-0.5 rotate-[215deg] animate-meteor rounded-[9999px] bg-white shadow-[0_0_90px_10px_#ffffff10]" )} style={style} > <div className="pointer-events-none absolute top-1/2 -z-10 h-[1px] w-[50px] translate-x-[-50px] -translate-y-1/2 bg-linear-to-l from-slate-500 to-transparent" /> </span> ))} </> ); }; Usage index.tsximport { Meteors } from "@/components/library/general/Meteors"; export default function MeteorsPage() { return ( <div> <Meteors number={20} /> </div> ); } Props PropTypeDefaultnumber?number-Edit on GitHubLast updated on Magic TextSimple animated text component that reveals as we scroll down the page.ParticlesParticles are small, interactive elements that can be used to create a variety of effects.