noise-texture
componentry/noise-textureFreeComponent
An animated noise/grain texture overlay effect with customizable grain size and blend modes.
Live preview
live · rendered by the registry
Rendered by componentry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://componentry.dev/r/noise-texture.jsonSource
1"use client"23import { useEffect, useRef } from "react"4import { cn } from "@/lib/utils"56interface NoiseTextureProps {7 className?: string8 opacity?: number9 speed?: number10 grain?: "fine" | "medium" | "coarse"11 blend?: "overlay" | "soft-light" | "multiply" | "screen" | "normal"12 animate?: boolean13}1415export function NoiseTexture({16 className,17 opacity = 0.4,18 speed = 10,19 grain = "medium",20 blend = "normal",21 animate = true,22}: NoiseTextureProps) {23 const canvasRef = useRef<HTMLCanvasElement>(null)24 const animationRef = useRef<number | NodeJS.Timeout>(0)2526 useEffect(() => {27 const canvas = canvasRef.current28 if (!canvas) return2930 const ctx = canvas.getContext("2d")31 if (!ctx) return3233 const grainSizes: Record<string, number> = {34 fine: 1,35 medium: 2,36 coarse: 3,37 }38 const grainSize = grainSizes[grain] ?? 23940 const resize = () => {41 const rect = canvas.getBoundingClientRect()42 const dpr = Math.min(window.devicePixelRatio || 1, 2)43 canvas.width = Math.ceil(rect.width / grainSize) * dpr44 canvas.height = Math.ceil(rect.height / grainSize) * dpr45 canvas.style.width = `${rect.width}px`46 canvas.style.height = `${rect.height}px`47 }4849 resize()50 window.addEventListener("resize", resize)5152 const renderNoise = () => {53 const { width, height } = canvas54 if (width === 0 || height === 0) return5556 const imageData = ctx.createImageData(width, height)57 const data = imageData.data5859 for (let i = 0; i < data.length; i += 4) {60 const value = Math.random() * 25561 data[i] = value62 data[i + 1] = value63 data[i + 2] = value64 data[i + 3] = 25565 }6667 ctx.putImageData(imageData, 0, 0)68 }6970 renderNoise()7172 if (animate) {73 const animateNoise = () => {74 renderNoise()75 animationRef.current = setTimeout(() => {76 requestAnimationFrame(animateNoise)77 }, 1000 / speed)78 }79 animateNoise()80 }8182 return () => {83 window.removeEventListener("resize", resize)84 if (animationRef.current) {85 clearTimeout(animationRef.current as NodeJS.Timeout)86 }87 }88 }, [grain, speed, animate])8990 const grainSizes: Record<string, number> = {91 fine: 1,92 medium: 2,93 coarse: 3,94 }9596 return (97 <canvas98 ref={canvasRef}99 className={cn("pointer-events-none absolute inset-0", className)}100 style={{101 opacity,102 mixBlendMode: blend,103// … truncated
More from componentry
All 59 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradientanimated-gradient | componentry | Components | Free | no deps | |
| ASCII Effectascii-effect | componentry | Components | Free | no deps | |
| Aurora Flowaurora-flow | componentry | Components | Free | no deps | |
| auth-modalauth-modal | componentry | Components | Free | no deps | |
| border-beamborder-beam | componentry | Components | Free | no deps | |
| circuit-boardcircuit-board | componentry | Components | Free | no deps | |
| closing-plasmaclosing-plasma | componentry | Components | Free | no deps | |
| collection-surfercollection-surfer | componentry | Components | Free | no deps |
