KQ-1446 · DRIFT/LINES
Drift Lines
A Canvas 2D background of long thin lines floating across the frame at different depths: each a gentle seeded curve drifting sideways at a pace set by its depth and bobbing on its own long period, so neighbours now and then cross, with near lines thicker, softer and lower in contrast and far ones hair-thin and crisp. The pointer shifts the parallax by depth on springs.glide, and a press racks focus to the depth of the line nearest the pointer on the glide spring, sharpening that plane and softening the rest, before it drifts back to rest on springs.drift; keyboard focus on a control inside racks focus to the line nearest it.
Coldbrook Labs
Every layer, in focus
24 lines · drifting
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/drift-lines
Props
- children
- React.ReactNode
- default —
- The content over the lines: a hero line, a heading, a call to action.
- count
- number
- default 24
- How many lines float in the field, 8 to 48.
- depth
- number
- default 0.6
- How far apart the depths are, 0 (one flat plane) to 1 (deep: thick soft near lines, strong parallax).
- color
- string
- default "var(--foreground)"
- The lines' colour, any CSS colour.
- accent
- string | null
- default "var(--accent-bright)"
- The colour of the one line that stands apart, or null for none.
- thickness
- number
- default 1
- Line weight, 0.5 (hairlines) to 2.
- contrast
- number
- default 0.6
- How strongly the lines read against the page, 0 to 1.
- curve
- number
- default 0.5
- How much the lines bend, 0 (straight) to 1.
- speed
- number
- default 0.6
- How fast the lines drift, 0 (still) to 2.
- focus
- number
- default 0
- The depth that rests in focus, 0 (the far lines) to 1 (the near ones).
- interactive
- boolean
- default true
- The pointer and keyboard focus shift the parallax, and a press racks focus.
- pointerStrength
- number
- default 0.6
- How far the hand shifts the parallax, 0 to 1.
- paused
- boolean
- default false
- Hold the lines still; the hand still shifts and focuses them.
- seed
- number
- default 1
- Seeds the field, so two never match.
- 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) moving the field.
- onFocusChange
- (depth: number, racked: boolean) => void
- default —
- Fires with the depth focus is racking to (0 far to 1 near) and whether a press or keyboard focus holds it there (false: back at rest).
- className
- string
- default "h-full w-full"
- Sizes and shapes the box.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The content over the lines: a hero line, a heading, a call to action. |
| count | number | 24 | How many lines float in the field, 8 to 48. |
| depth | number | 0.6 | How far apart the depths are, 0 (one flat plane) to 1 (deep: thick soft near lines, strong parallax). |
| color | string | "var(--foreground)" | The lines' colour, any CSS colour. |
| accent | string | null | "var(--accent-bright)" | The colour of the one line that stands apart, or null for none. |
| thickness | number | 1 | Line weight, 0.5 (hairlines) to 2. |
| contrast | number | 0.6 | How strongly the lines read against the page, 0 to 1. |
| curve | number | 0.5 | How much the lines bend, 0 (straight) to 1. |
| speed | number | 0.6 | How fast the lines drift, 0 (still) to 2. |
| focus | number | 0 | The depth that rests in focus, 0 (the far lines) to 1 (the near ones). |
| interactive | boolean | true | The pointer and keyboard focus shift the parallax, and a press racks focus. |
| pointerStrength | number | 0.6 | How far the hand shifts the parallax, 0 to 1. |
| paused | boolean | false | Hold the lines still; the hand still shifts and focuses them. |
| seed | number | 1 | Seeds the field, so two never match. |
| 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) moving the field. |
| onFocusChange | (depth: number, racked: boolean) => void | — | Fires with the depth focus is racking to (0 far to 1 near) and whether a press or keyboard focus holds it there (false: back at rest). |
| className | string | "h-full w-full" | Sizes and shapes the box. |