Animated Grid Pattern
magicui/animated-grid-patternFreeComponent
A animated background grid pattern made with SVGs, fully customizable using Tailwind CSS.
Live preview
live · rendered by the registry
Rendered by magicui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://magicui.design/r/animated-grid-pattern.jsonSource
1"use client"23import {4 useCallback,5 useEffect,6 useId,7 useRef,8 useState,9 type ComponentPropsWithoutRef,10} from "react"11import { motion } from "motion/react"1213import { cn } from "@/lib/utils"1415export interface AnimatedGridPatternProps extends ComponentPropsWithoutRef<"svg"> {16 width?: number17 height?: number18 x?: number19 y?: number20 strokeDasharray?: number21 numSquares?: number22 maxOpacity?: number23 duration?: number24 repeatDelay?: number25}2627type Square = {28 id: number29 pos: [number, number]30 iteration: number31}3233export function AnimatedGridPattern({34 width = 40,35 height = 40,36 x = -1,37 y = -1,38 strokeDasharray = 0,39 numSquares = 50,40 className,41 maxOpacity = 0.5,42 duration = 4,43 repeatDelay = 0.5,44 ...props45}: AnimatedGridPatternProps) {46 const id = useId()47 const containerRef = useRef<SVGSVGElement | null>(null)48 const [dimensions, setDimensions] = useState({ width: 0, height: 0 })49 const [squares, setSquares] = useState<Array<Square>>([])5051 const getPos = useCallback((): [number, number] => {52 return [53 Math.floor((Math.random() * dimensions.width) / width),54 Math.floor((Math.random() * dimensions.height) / height),55 ]56 }, [dimensions.height, dimensions.width, height, width])5758 const generateSquares = useCallback(59 (count: number) => {60 return Array.from({ length: count }, (_, i) => ({61 id: i,62 pos: getPos(),63 iteration: 0,64 }))65 },66 [getPos]67 )6869 const updateSquarePosition = useCallback(70 (squareId: number) => {71 setSquares((currentSquares) => {72 const current = currentSquares[squareId]73 if (!current || current.id !== squareId) return currentSquares7475 const nextSquares = currentSquares.slice()76 nextSquares[squareId] = {77 ...current,78 pos: getPos(),79 iteration: current.iteration + 1,80 }8182 return nextSquares83 })84 },85 [getPos]86 )8788 useEffect(() => {89 if (dimensions.width && dimensions.height) {90 setSquares(generateSquares(numSquares))91 }92 }, [dimensions.width, dimensions.height, generateSquares, numSquares])9394 useEffect(() => {95 const element = containerRef.current96 let resizeObserver: ResizeObserver | null = null9798 if (element) {99 resizeObserver = new ResizeObserver((entries) => {100 for (const entry of entries) {101 setDimensions((currentDimensions) => {102 const nextWidth = entry.contentRect.width103// … truncated
What it pulls in
npm packages
Files it writes
More from magicui
All 247 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Androidandroid | magicui | Components | Free | no deps | |
| Animated Beamanimated-beam | magicui | Components | Free | 1 dep | |
| Animated Circular Progress Baranimated-circular-progress-bar | magicui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | magicui | Components | Free | no deps | |
| Animated Listanimated-list | magicui | Components | Free | 1 dep | |
| Animated Shiny Textanimated-shiny-text | magicui | Components | Free | no deps | |
| Theme Toggleranimated-theme-toggler | magicui | Components | Free | 1 dep | |
| Aurora Textaurora-text | magicui | Components | Free | no deps |
