KQ-1426 · LOUVER/LIGHT
Louver Light
An architectural louvre wall as a background, drawn in one WebGL2 pass with the content in front: rows of fine slats, cut into blades by thin mullions, each turning rigidly on its long axis as a rolling wave crosses the wall, so a blade's face brightens and glints as it turns toward a soft light above and bands of light travel across, while blades turned edge-on open onto a shadowed recess. The pointer bends the wave around itself, its place on springs.glide and its pull on springs.drift, and a press flips the slats over in a ring that runs out from it, each blade landing its half turn on the recoil spring. It never takes focus; keyboard focus on a control inside bends the wave there and flips a small ring from it.
Fernworks Architects
A library lit by its own facade
1,200 cedar louvres turn with the sun
at rest · 40 slats at 20°, dawn light
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/louver-light
Props
- children
- React.ReactNode
- default —
- The content in front of the wall: a hero line, a heading, a call to action.
- slats
- number
- default 40
- Rows of slats down the wall, 8 to 160: fine louvres or broad blades.
- tilt
- number
- default 20
- The angle the slats rest at, in degrees from flat-on (−80 to 80); it decides where the light lands.
- light
- "dawn" | "noon" | "dusk" | "moon" | string
- default "dawn"
- The light's colour: a named light, or any CSS colour.
- swing
- number
- default 55
- How far the rolling wave turns each slat either side of its rest, in degrees (0 to 90).
- speed
- number
- default 1
- How fast the wave rolls, 0 (held) to 3.
- wavelength
- number
- default 420
- Distance between bands of light, in px.
- angle
- number
- default 35
- The direction the bands travel, in degrees; 0 runs left to right.
- segment
- number
- default 12
- Each slat's length between mullions, in slat pitches (2 to 40).
- finish
- string
- default "color-mix(in oklab, var(--background) 84%, var(--foreground))"
- The slats' paint, any CSS colour.
- glint
- number
- default 0.6
- How bright the glint is where a slat mirrors the light, 0 to 1.
- interactive
- boolean
- default true
- The pointer and keyboard focus bend the wave.
- pointerStrength
- number
- default 0.6
- How far the pointer bends the wave, 0 to 1.
- pulse
- boolean
- default true
- A press on the wall (not on a control) flips the slats over in a ring from it.
- intro
- boolean
- default true
- The slats open out of a closed wall the first time it comes into view.
- paused
- boolean
- default false
- Hold the wave still; the pointer can still bend it.
- seed
- number
- default 1
- Seeds the wave's phase and the slats' small irregularities.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- onActiveChange
- (active: boolean) => void
- default —
- Fires when the pointer or keyboard focus starts (true) or stops (false) bending the wave.
- className
- string
- default —
- Sizes and shapes the box; it fills its parent by default (h-full w-full).
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The content in front of the wall: a hero line, a heading, a call to action. |
| slats | number | 40 | Rows of slats down the wall, 8 to 160: fine louvres or broad blades. |
| tilt | number | 20 | The angle the slats rest at, in degrees from flat-on (−80 to 80); it decides where the light lands. |
| light | "dawn" | "noon" | "dusk" | "moon" | string | "dawn" | The light's colour: a named light, or any CSS colour. |
| swing | number | 55 | How far the rolling wave turns each slat either side of its rest, in degrees (0 to 90). |
| speed | number | 1 | How fast the wave rolls, 0 (held) to 3. |
| wavelength | number | 420 | Distance between bands of light, in px. |
| angle | number | 35 | The direction the bands travel, in degrees; 0 runs left to right. |
| segment | number | 12 | Each slat's length between mullions, in slat pitches (2 to 40). |
| finish | string | "color-mix(in oklab, var(--background) 84%, var(--foreground))" | The slats' paint, any CSS colour. |
| glint | number | 0.6 | How bright the glint is where a slat mirrors the light, 0 to 1. |
| interactive | boolean | true | The pointer and keyboard focus bend the wave. |
| pointerStrength | number | 0.6 | How far the pointer bends the wave, 0 to 1. |
| pulse | boolean | true | A press on the wall (not on a control) flips the slats over in a ring from it. |
| intro | boolean | true | The slats open out of a closed wall the first time it comes into view. |
| paused | boolean | false | Hold the wave still; the pointer can still bend it. |
| seed | number | 1 | Seeds the wave's phase and the slats' small irregularities. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| onActiveChange | (active: boolean) => void | — | Fires when the pointer or keyboard focus starts (true) or stops (false) bending the wave. |
| className | string | — | Sizes and shapes the box; it fills its parent by default (h-full w-full). |