Background Meteors
scrollxui/backgroundmeteorsFreeComponent
animated background featuring vertical meteor-like beams falling from the top to the bottom of the screen over a grid pattern.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/backgroundmeteors.jsonSource
1'use client';2import React, { useEffect, useState, ReactNode } from 'react';3import { motion } from 'motion/react';45interface Beam {6 id: number;7 x: number;8 duration: number;9}1011interface BackgroundMeteorsProps {12 children?: ReactNode;13}1415export default function BackgroundMeteors({16 children,17}: BackgroundMeteorsProps) {18 const [beams, setBeams] = useState<Beam[]>([]);19 const gridSize = 40;20 const totalLines = 35;2122 const generateSafeGridPositions = (count: number): number[] => {23 const available: number[] = [];24 for (let i = 0; i < totalLines - 1; i++) {25 available.push(i);26 }2728 const selected: number[] = [];29 while (available.length > 0 && selected.length < count) {30 const idx = Math.floor(Math.random() * available.length);31 const value = available[idx];32 selected.push(value);33 available.splice(34 0,35 available.length,36 ...available.filter((v) => Math.abs(v - value) > 1),37 );38 }3940 return selected.map((line) => line * gridSize);41 };4243 useEffect(() => {44 const generateBeams = () => {45 const count = Math.floor(Math.random() * 2) + 3;46 const xPositions = generateSafeGridPositions(count);4748 const newBeams: Beam[] = xPositions.map((x) => ({49 id: Math.random(),50 x,51 duration: 4 + Math.random() * 1.5,52 }));5354 setBeams(newBeams);5556 const maxDuration = Math.max(...newBeams.map((b) => b.duration));57 setTimeout(generateBeams, (maxDuration - 0.5) * 1000);58 };5960 generateBeams();61 }, []);6263 return (64 <div className='relative flex h-screen w-full items-center justify-center overflow-hidden bg-white dark:bg-black'>65 <div66 className='absolute inset-0'67 style={{68 backgroundSize: `${gridSize}px ${gridSize}px`,69 backgroundImage:70 'linear-gradient(to right, #e4e4e7 1px, transparent 1px), linear-gradient(to bottom, #e4e4e7 1px, transparent 1px)',71 }}72 />73 <div74 className='absolute inset-0 dark:block hidden'75 style={{76 backgroundSize: `${gridSize}px ${gridSize}px`,77 backgroundImage:78 'linear-gradient(to right, #262626 1px, transparent 1px), linear-gradient(to bottom, #024e6b 1px, transparent 1px)',79 }}80 />81 <div82 className='pointer-events-none absolute inset-0 flex items-center justify-center bg-white dark:bg-black83 mask-[radial-gradient(ellipse_at_center,transparent_20%,black)]'84// … truncated
What it pulls in
npm packages
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
