Grain Overlay
A canvas grain overlay that flickers frame by frame, in fine / coarse / vintage textures, adding film-like noise to gradients and images.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add grain-overlay.enPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<GrainOverlay/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
Installation
npx webberui@latest add https://webberui.com/r/grain-overlay.en.jsonOr, once registries are configured in components.json, install it as @webberui/grain-overlay.
Usage
GrainOverlay is one absolutely positioned layer: drop it into any relative container and it covers the whole background. Adding isolate to the container keeps the blend mode confined to the container instead of bleeding through to the page behind it.
import { GrainOverlay } from "@/components/ui/grain-overlay";
<div className="relative isolate overflow-hidden rounded-xl bg-gradient-to-br from-indigo-500 to-pink-500">
<GrainOverlay variant="coarse" />
{/* your content */}
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "fine" | "coarse" | "vintage" | "fine" | Grain texture preset; any parameter you do not override follows this preset |
intensity | number | Per variant | Overall opacity of the overlay (0–1) |
grainSize | number | Per variant | Edge length of a single grain (CSS px, integer) |
contrast | number | Per variant | Grain contrast (0–1) — the light/dark amplitude of each grain |
blendMode | GrainBlendMode | Per variant | Blend mode (overlay / soft-light and so on) |
fps | number | Per variant | Flicker update rate (1–60) |
animated | boolean | true | Whether to flicker frame by frame; when false it is a single static frame |
frameCount | number | 8 | Number of noise frames pre-generated and cycled (1–24) |
The defaults for the three variant presets: fine (grainSize 1, delicate and understated), coarse (grainSize 3, high contrast, rough), vintage (soft-light, slow flicker, imitating old film stock). Passing any numeric prop explicitly overrides that preset's value.
How it works
- The grain is drawn on canvas frame by frame:
frameCountindependent low-resolution grayscale noise frames are pre-generated, and each frame — throttled byfps— picks one at random and scales it up to fill the layer, producing a convincing film flicker. - Grain brightness is centered on mid-gray (128) with
contrastsetting the amplitude; paired with theoverlayblend mode, mid-gray leaves the underlying color untouched and only the light and dark grains are layered on. grainSizeis measured in CSS pixels, and image smoothing is turned off (blocky upscaling) to keep the grains sharp and consistently sized even on high-DPR displays.- Adjusting
intensityandblendModeis a pure styling change and does not rebuild the noise; only changes tograinSize,contrast,fps, and the like regenerate the frames. - A
ResizeObserverwatches the container size, and rebuilding the noise is debounced; the rAF, timers, and observers are all cleaned up on unmount.
Accessibility
- The overlay carries
aria-hiddenandpointer-events-none— decorative only, so it interferes with neither assistive technology nor interaction with the layer beneath. - When the user has "reduce motion" enabled at the system level, the frame-by-frame flicker stops automatically and a single static noise frame is rendered instead.
Beams Background
A canvas background of beams streaming continuously along a diagonal path, with palette, angle, glow, and cursor-driven acceleration.
Interactive Dot Grid
An interactive dot grid background — a full-bleed regular grid where dots near the cursor scale up and get pushed away, then ease smoothly back.