KQ-1480 · TILE/DRIFT
Tile Drift
A background of rows of tiles drifting sideways past each other on a plane tilted back in perspective, with your content on top: alternate rows run opposite ways at seeded speeds, and the tiles are generated prints in the page's pigments or your own images. A sweep of the pointer surges the rows near it — arriving on springs.flick and easing back on springs.drift — and a sideways drag grabs the row under the finger 1:1 and throws it on release, the throw relaxing back to the row's cruise on a velocity spring with drift's constants. Keyboard focus on a control inside surges the rows behind it.
Waylight Prints
New prints every Friday
48 editions · signed and numbered
4 rows · drifting
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/tile-drift
Props
- children
- React.ReactNode
- default —
- The content on top of the wall: a hero line, a heading, a call to action.
- rows
- number
- default 4
- Rows of tiles across the box, 2 to 8.
- speed
- number
- default 1
- How fast the rows cruise, 0 (still) to 2.
- tilt
- number
- default 14
- How far the plane leans back in perspective, degrees (0 to 35); it turns a third of that too.
- images
- readonly string[]
- default —
- Image URLs to show on the tiles, covering each one. Without them the tiles are generated prints.
- colors
- readonly string[]
- default five token-derived pigments
- The pigments the generated prints are made from, as CSS colours (2 to 6).
- aspect
- number
- default 1.3
- A tile's width over its height (0.5 to 2.5).
- gap
- number
- default 10
- Space between tiles and between rows, px (0 to 32).
- radius
- number
- default 8
- Tile corner radius, px (0 to 24).
- variation
- number
- default 0.5
- How differently the rows cruise, 0 (all alike) to 1.
- fade
- number
- default 0.5
- How far the wall fades into the page at its edges, 0 (hard edge) to 1.
- interactive
- boolean
- default true
- The pointer and keyboard focus stir the rows, and rows can be grabbed.
- pointerStrength
- number
- default 0.6
- How hard a sweep of the hand surges the rows near it, 0 to 1.
- grab
- boolean
- default true
- A sideways drag grabs the row under it and a release throws it.
- paused
- boolean
- default false
- Hold the cruise; the hand can still stir and throw the rows.
- seed
- number
- default 1
- Seeds the prints, the row speeds and where each row starts.
- onActiveChange
- (active: boolean) => void
- default —
- Fires when the rows start (true) or stop (false) answering the hand: a surge, a grab or a throw coasting.
- onFling
- (row: number, velocity: number) => void
- default —
- Fires when a grabbed row is let go, with its row (0 at the top) and its throw, px/s.
- className
- string
- default "h-full w-full"
- Sizes and shapes the box.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The content on top of the wall: a hero line, a heading, a call to action. |
| rows | number | 4 | Rows of tiles across the box, 2 to 8. |
| speed | number | 1 | How fast the rows cruise, 0 (still) to 2. |
| tilt | number | 14 | How far the plane leans back in perspective, degrees (0 to 35); it turns a third of that too. |
| images | readonly string[] | — | Image URLs to show on the tiles, covering each one. Without them the tiles are generated prints. |
| colors | readonly string[] | five token-derived pigments | The pigments the generated prints are made from, as CSS colours (2 to 6). |
| aspect | number | 1.3 | A tile's width over its height (0.5 to 2.5). |
| gap | number | 10 | Space between tiles and between rows, px (0 to 32). |
| radius | number | 8 | Tile corner radius, px (0 to 24). |
| variation | number | 0.5 | How differently the rows cruise, 0 (all alike) to 1. |
| fade | number | 0.5 | How far the wall fades into the page at its edges, 0 (hard edge) to 1. |
| interactive | boolean | true | The pointer and keyboard focus stir the rows, and rows can be grabbed. |
| pointerStrength | number | 0.6 | How hard a sweep of the hand surges the rows near it, 0 to 1. |
| grab | boolean | true | A sideways drag grabs the row under it and a release throws it. |
| paused | boolean | false | Hold the cruise; the hand can still stir and throw the rows. |
| seed | number | 1 | Seeds the prints, the row speeds and where each row starts. |
| onActiveChange | (active: boolean) => void | — | Fires when the rows start (true) or stop (false) answering the hand: a surge, a grab or a throw coasting. |
| onFling | (row: number, velocity: number) => void | — | Fires when a grabbed row is let go, with its row (0 at the top) and its throw, px/s. |
| className | string | "h-full w-full" | Sizes and shapes the box. |