Hole Background
animate-ui/components-backgrounds-holeFreeComponent
A background component featuring an animated hole grid.
Install it
npx shadcn@latest add https://animate-ui.com/r/components-backgrounds-hole.jsonSource
1/* eslint-disable @typescript-eslint/no-explicit-any */23'use client';45import * as React from 'react';6import { motion } from 'motion/react';78import { cn } from '@/lib/utils';910type HoleBackgroundProps = React.ComponentProps<'div'> & {11 strokeColor?: string;12 numberOfLines?: number;13 numberOfDiscs?: number;14 particleRGBColor?: [number, number, number];15};1617function HoleBackground({18 strokeColor = '#737373',19 numberOfLines = 50,20 numberOfDiscs = 50,21 particleRGBColor = [255, 255, 255],22 className,23 children,24 ...props25}: HoleBackgroundProps) {26 const canvasRef = React.useRef<HTMLCanvasElement>(null);27 const animationFrameIdRef = React.useRef<number>(0);28 const stateRef = React.useRef<any>({29 discs: [] as any[],30 lines: [] as any[],31 particles: [] as any[],32 clip: {},33 startDisc: {},34 endDisc: {},35 rect: { width: 0, height: 0 },36 render: { width: 0, height: 0, dpi: 1 },37 particleArea: {},38 linesCanvas: null,39 });4041 const linear = (p: number) => p;42 const easeInExpo = (p: number) => (p === 0 ? 0 : Math.pow(2, 10 * (p - 1)));4344 const tweenValue = React.useCallback(45 (start: number, end: number, p: number, ease: 'inExpo' | null = null) => {46 const delta = end - start;47 const easeFn = ease === 'inExpo' ? easeInExpo : linear;48 return start + delta * easeFn(p);49 },50 [],51 );5253 const tweenDisc = React.useCallback(54 (disc: any) => {55 const { startDisc, endDisc } = stateRef.current;56 disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);57 disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, 'inExpo');58 disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);59 disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);60 },61 [tweenValue],62 );6364 const setSize = React.useCallback(() => {65 const canvas = canvasRef.current;66 if (!canvas) return;67 const rect = canvas.getBoundingClientRect();68 stateRef.current.rect = { width: rect.width, height: rect.height };69 stateRef.current.render = {70 width: rect.width,71 height: rect.height,72 dpi: window.devicePixelRatio || 1,73 };74 canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;75 canvas.height =76 stateRef.current.render.height * stateRef.current.render.dpi;77 }, []);7879 const setDiscs = React.useCallback(() => {80 const { width, height } = stateRef.current.rect;81 stateRef.current.discs = [];82 stateRef.current.startDisc = {83 x: width * 0.5,84// … truncated
What it pulls in
npm packages
Files it writes
More from Animate UI
All 580 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Avatar Groupcomponents-animate-avatar-group | Animate UI | Components | Free | 1 dep | |
| Codecomponents-animate-code | Animate UI | Components | Free | 1 dep | |
| Code Tabscomponents-animate-code-tabs | Animate UI | Components | Free | 1 dep | |
| Cursorcomponents-animate-cursor | Animate UI | Components | Free | no deps | |
| GitHub Stars Wheelcomponents-animate-github-stars-wheel | Animate UI | Components | Free | 1 dep | |
| Tabscomponents-animate-tabs | Animate UI | Components | Free | no deps | |
| Tooltipcomponents-animate-tooltip | Animate UI | Components | Free | 1 dep | |
| Bubble Backgroundcomponents-backgrounds-bubble | Animate UI | Components | Free | 1 dep |
