Docs
Flickering Grid Backgroud
Flickering Grid Backgroud
A Flickering Grid Backgroud with canvas
Installation
Install the following dependencies:
npm install color-bits
Copy and paste the util code into your project.
import { ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
import * as Color from "color-bits"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
export const getRGBA = (
cssColor: React.CSSProperties["color"],
fallback: string = "rgba(180, 180, 180)"
): string => {
if (typeof window === "undefined") return fallback
if (!cssColor) return fallback
try {
// Handle CSS variables
if (typeof cssColor === "string" && cssColor.startsWith("var(")) {
const element = document.createElement("div")
element.style.color = cssColor
document.body.appendChild(element)
const computedColor = window.getComputedStyle(element).color
document.body.removeChild(element)
return Color.formatRGBA(Color.parse(computedColor))
}
return Color.formatRGBA(Color.parse(cssColor))
} catch (e) {
console.error("Color parsing failed:", e)
return fallback
}
}
// Helper function to add opacity to an RGB color string
export const colorWithOpacity = (color: string, opacity: number): string => {
if (!color.startsWith("rgb")) return color
return Color.formatRGBA(Color.alpha(Color.parse(color), opacity))
}
Copy and paste the Grid code into your project.
API Reference
Props
Name | Type | Default | Description |
---|---|---|---|
squareSize | number | 3 | Size of each square in pixels |
gridGap | number | 3 | Gap between squares in pixels |
flickerChance | number | 0.2 | Probability (0-1) of a square changing opacity on each frame |
color | string | "#B4B4B4" | Color of the squares (hex, rgb, rgba, hsl, or CSS variable) |
width | number | undefined | Optional fixed width in pixels (defaults to container width) |
height | number | undefined | Optional fixed height in pixels (defaults to container height) |
className | string | undefined | Additional CSS classes to apply to the container |
maxOpacity | number | 0.15 | Maximum opacity value for squares (0-1) |
text | string | "" | Optional text to display on the grid |
fontSize | number | 140 | Font size for the text in pixels |
fontWeight | `number | string` | 600 |
...props | React.HTMLAttributes<HTMLDivElement> | All standard HTML div attributes are also supported |
Usage Example
export default function HeroSection() {
return (
<div className="relative h-[600px] w-full">
<FlickeringGrid
squareSize={2.5}
gridGap={2.5}
color="#6f3cff"
maxOpacity={0.4}
flickerChance={0.03}
className="absolute inset-0"
/>
<div className="relative z-10 flex items-center justify-center h-full">
<h1 className="text-4xl font-bold">Your content here</h1>
</div>
</div>
);
}
Features
- Performance Optimized: Uses canvas for rendering and throttles frame rates
- Responsive: Automatically adjusts to container size with resize observer
- Intersection Observer: Only animates when visible in viewport
- Text Overlay: Supports displaying text with customizable font properties
- Gradient Compatible: Works with CSS gradients and opacity variations
Notes
- The component uses
useRef
to reference the canvas element and animation frame. - For optimal performance, the component throttles rendering to approximately 20fps.
- The component uses intersection observer to pause animation when not in view.
- Text rendering uses a separate canvas as a mask for performance optimization.
- The component supports device pixel ratio for crisp rendering on high-DPI displays.