KQ-1884 · ZELLIGE/WALL

Zellige Wall

A picture rebuilt from small glazed tiles, each an unevenly cut square set a hair askew in grout, its colour box-averaged from the picture and pulled toward the picture's own glazes, lit per pixel in one instanced WebGL2 draw with a pillowed face, a rolled rim that catches the light and a hairline of bare clay. Every tile has its own tilt spring, between the springs.snap and springs.recoil constants by wobble: tiles under the pointer lean toward it so a ring of glints follows the hand and rings back as it passes, and a click sends a ripple across the whole wall that kicks each tile outward as the front reaches it. Arrow keys move a keyboard lamp the tiles lean toward, and Enter or Space sends the ripple from it.

KQ-1884 · ZELLIGE/WALL

Basinworks Tile Co.

Courtyard, hand-cut

Set by hand, one tile at a time.

Move the pointer over the tiles, or use the arrow keys to move a lamp, and the tiles lean toward it. Click, or press Enter or Space, to send a ripple across the wall.

hover to tilt · click to ripple · tile 14 px · glaze 0.60

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/zellige-wall

Props

src
string
default —
A picture to set in tiles (same-origin, or served with CORS). Without one, a drawn courtyard door is used.
alt
string
default a description of the drawn courtyard
Describes the picture.
tile
number
default 14
Tile size, px, 8 to 28.
glaze
number
default 0.6
Glaze shine, 0 (matte clay) to 1 (wet glass): the strength and tightness of every highlight.
tilt
number
default 18
How far a tile leans toward the pointer, degrees, 0 to 35.
radius
number
default 90
How far from the pointer tiles lean, px.
rippleSpeed
number
default 520
How fast a click's ripple crosses the wall, px per second.
wobble
number
default 0.5
How the tiles settle, 0 (one crisp overshoot, springs.snap) to 1 (a ringing wobble, springs.recoil).
jitter
number
default 0.5
How unevenly the tiles are cut, 0 (machine-square) to 1 (hand-cut).
askew
number
default 2.5
How far a tile is set off square, degrees.
grout
string
default a mix of the page background and ink
The grout between the tiles, any CSS colour.
light
number
default -135
The key light's direction, degrees (−135 is from the upper left).
interactive
boolean
default true
Tiles answer the pointer and keys; off, the wall is a still picture with role="img".
seed
number
default 7
Seeds the cut and set of every tile.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
onRipple
(origin: { x: number; y: number }) => void
default —
Fires from the click or key that sent a ripple, with its origin as shares of the wall (0–1).
label
string
default "Glazed tile wall"
The wall's accessible name.
disabled
boolean
default false
No pointer, clicks or keys; the wall dims.
className
string
default —
Sizes the wall; it fills its parent by default.