Surface study no. 04
A studio for identities that move. We cast brands in liquid metal, then let them settle into something you can hold.
A photo laid on an invisible grid of square cells, live in WebGL. Sweeping the cursor drags the cells it passes over in the direction of the movement, like smearing wet paint: a faster sweep pulls further, and the displaced cells break into coarser pixels with a slight red and blue split at their edges. Each cell then eases back into place and the photo sharpens again; a still cursor leaves it alone. On arrival the photo grows softly out of the dark ground and resolves from big pixel blocks into the sharp image. Grid size, strength, radius, how quickly cells settle, color split, pixelation and grain are all props. Draws only while something moves, pauses offscreen, shows the sharp photo for reduced motion and falls back to the plain photo without WebGL.
The import and the props worth knowing about, in one place.
import { PixelDistort } from "@/components/beste/component/pixel-distort";
// As a layer behind content
<section className="relative min-h-[40rem]">
<PixelDistort
className="absolute inset-0"
src="https://images.unsplash.com/photo-1697128951362-e704be45d3da?w=2000&q=80"
alt="Raised hands against blue stage light"
/>
<div className="relative">...</div>
</section>
<PixelDistort
className="min-h-[32rem]"
src="https://images.unsplash.com/photo-1697128951362-e704be45d3da?w=2000&q=80"
grid={20} // chunkier cells
strength={0.9} // a sweep drags further
relax={0.2} // cells take longer to settle
/>Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
src* | string | — | Photo to distort. Loaded with CORS so WebGL can read it. |
alt | string | — | Description of the photo for screen readers. |
grid | number | — | Cells across the width of the grid, 12 to 72. Fewer cells make chunkier pixels. |
strength | number | — | How far a sweep of the cursor drags the cells, 0 to 1. |
radius | number | — | Size of the area the cursor drags, 0 to 1. |
relax | number | — | How quickly the cells ease back into place, 0 (slow) to 1 (quick). |
aberration | number | — | Red and blue split at the edges of displaced cells, 0 to 1. |
pixelate | number | — | How coarse displaced cells turn, 0 (smooth) to 1 (blocky). |
intro | boolean | — | The photo resolves from big pixels into the sharp image on arrival. |
grain | number | — | Film grain, 0 to 1. |
interactive | boolean | — | The cursor drags the grid. |
paused | boolean | — | Freeze the picture where it is. |
className | string | — | |
children | ReactNode | — |