KQ-1371 · LETTER/RAIN
Letter Rain
A headline whose letters fall off the line: on its trigger each letter lets go — nearest the press first, cascade-staggered inside 600ms — and drops as a rigid box the size of its own ink, landing on corners, toppling, bouncing and piling at the foot of the box under a small real engine (separating-axis contacts, sequential impulses with friction, restitution and warm starting, sleep). Any letter can be picked up and follows the pointer 1:1, shoving the pile, then leaves with the release velocity and spin; Reassemble flies every letter home in reading order, x on springs.glide and y and rotation on springs.snap, each starting from its own velocity. The stage is a button: Enter drops the line or knocks the pile, Left and Right shove it, Up tosses it, and the Reassemble button brings it home.
Fieldline · end of season
Everything must go
Press or Enter drops the letters off the line. Drag a letter to pick it up and throw it.Up to 40% off the spring range, this week only.
standing · press the line to drop it
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/letter-rain
Props
- text
- string
- default —
- The line whose letters fall.
- as
- "p" | "h1" | "h2" | "h3" | "span" | "div"
- default "p"
- The element that carries the line for assistive technology.
- gravity
- number
- default 1
- Gravity, times 60 em/s² — so a caption and a hero fall alike. 0.25 to 2.
- bounce
- number
- default 0.35
- How much a landing bounces, 0 (a dead drop) to 1 (lively).
- friction
- number
- default 0.5
- How much letters grip each other and the floor, 0 (ice) to 1 (felt).
- trigger
- "press" | "hover" | "inView" | "mount" | "manual"
- default "press"
- What drops the line: a press, the pointer arriving, coming into view, mounting, or only fallen.
- fallen / defaultFallen
- boolean
- default false
- Controlled: the letters are down (true) or on the line (false); or the initial state when uncontrolled.
- onFallenChange
- (fallen: boolean) => void
- default —
- Fires from the press, key or gesture that dropped or reassembled the line.
- depth
- number
- default 1.75
- How far below the line the floor sits, em.
- floor
- boolean
- default true
- Draw the floor the letters land on, as a hairline.
- throwable
- boolean
- default true
- Letters can be picked up and thrown.
- delay
- number
- default 0
- Wait before an automatic drop (hover, in view, mount), ms.
- stagger
- number
- default 28
- Between letters letting go of the line, ms; capped so the whole line goes inside 600ms.
- once
- boolean
- default false
- Automatic triggers drop the line only once.
- reassembleAfter
- number
- default 0
- Reassemble on its own this long after the pile comes to rest, ms; 0 waits for a press.
- reassembleLabel
- string
- default "Reassemble"
- The reassemble button's label.
- onComplete
- () => void
- default —
- The pile has come to rest, or the line has reassembled.
- sound
- boolean
- default false
- Play the landings the visitor causes. Off unless asked for.
- disabled
- boolean
- default false
- No dropping, throwing or reassembling.
- className
- string
- default —
- Classes for the root; set the type here — the physics scales with the font size.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | — | The line whose letters fall. |
| as | "p" | "h1" | "h2" | "h3" | "span" | "div" | "p" | The element that carries the line for assistive technology. |
| gravity | number | 1 | Gravity, times 60 em/s² — so a caption and a hero fall alike. 0.25 to 2. |
| bounce | number | 0.35 | How much a landing bounces, 0 (a dead drop) to 1 (lively). |
| friction | number | 0.5 | How much letters grip each other and the floor, 0 (ice) to 1 (felt). |
| trigger | "press" | "hover" | "inView" | "mount" | "manual" | "press" | What drops the line: a press, the pointer arriving, coming into view, mounting, or only fallen. |
| fallen / defaultFallen | boolean | false | Controlled: the letters are down (true) or on the line (false); or the initial state when uncontrolled. |
| onFallenChange | (fallen: boolean) => void | — | Fires from the press, key or gesture that dropped or reassembled the line. |
| depth | number | 1.75 | How far below the line the floor sits, em. |
| floor | boolean | true | Draw the floor the letters land on, as a hairline. |
| throwable | boolean | true | Letters can be picked up and thrown. |
| delay | number | 0 | Wait before an automatic drop (hover, in view, mount), ms. |
| stagger | number | 28 | Between letters letting go of the line, ms; capped so the whole line goes inside 600ms. |
| once | boolean | false | Automatic triggers drop the line only once. |
| reassembleAfter | number | 0 | Reassemble on its own this long after the pile comes to rest, ms; 0 waits for a press. |
| reassembleLabel | string | "Reassemble" | The reassemble button's label. |
| onComplete | () => void | — | The pile has come to rest, or the line has reassembled. |
| sound | boolean | false | Play the landings the visitor causes. Off unless asked for. |
| disabled | boolean | false | No dropping, throwing or reassembling. |
| className | string | — | Classes for the root; set the type here — the physics scales with the font size. |