KQ-1362 · DEPTH/OF/FIELD
Depth of Field
A line shot through a fast lens: every word starts soft, a little smaller and faded, and a focal plane sweeps along the line kicking each word sharp on a spring that runs from snap to recoil with breath, so focus breathes past the word before it settles, with a focus-peaking edge flashing as it lands. Pointing at a word racks focus to it — the plane itself travels on a glide-weight spring, so a long pull passes through the words between and the rest fall off with distance — and leaving stops the lens down again. A keyboard handle racks word to word with Left and Right, Escape brings everything into focus and Enter plays the pull again.
Fieldline 35 mm · f/1.4 prime
Every frame finds its subject.
Left and Right rack the focus from word to word, Escape brings everything into focus, Enter plays the focus pull again.Point at a word to pull focus to it.
f/2.8 · racking focus
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/depth-of-field
Props
- children
- string
- default —
- The line, as a string. Wins over text.
- text
- string
- default —
- The line, when it is not given as children.
- as
- "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div"
- default "p"
- The element that carries the line.
- aperture
- number
- default 2.8
- The f-number, 1 to 16: lower is a wider aperture and softer out-of-focus words.
- sweep
- number
- default 1100
- How long the focal plane takes to cross the line, ms.
- breath
- number
- default 0.5
- How far focus breathes past each word: 0 lands dead on (snap), 1 breathes twice (recoil).
- depth
- number
- default 1.5
- Depth of field on a re-rack: words either side of the focused one that stay partly sharp.
- shrink
- number
- default 0.04
- Lens breathing: how much smaller a fully soft word reads, 0 to 0.12.
- fade
- number
- default 0.4
- How much opacity a fully soft word loses, 0 to 1.
- peaking
- boolean
- default true
- Flash a focus-peaking edge on a word as it comes sharp.
- peakColor
- string
- default "var(--accent-bright)"
- The peaking colour, any CSS colour.
- interactive
- boolean
- default true
- Pointing at a word, tapping it or the arrow keys rack focus to it.
- rest
- "deep" | "hold"
- default "deep"
- What leaving the line does: stop down so every word is sharp, or keep the pull.
- value / defaultValue
- number | null
- default null
- The focused word's index; null is everything in focus.
- onValueChange
- (index: number | null) => void
- default —
- Fires from the hover, tap or key that moved the focus.
- trigger
- "mount" | "inView" | "hover" | "manual"
- default "inView"
- When the sweep plays.
- once
- boolean
- default true
- Play once, or again each time it re-enters view or is hovered.
- delay
- number
- default 0
- Wait before the sweep, ms.
- play
- boolean
- default false
- With trigger "manual": true plays the sweep, false returns the line to soft.
- onComplete
- () => void
- default —
- The sweep has settled.
- className
- string
- default —
- Classes for the root; the type size and colour are inherited from here.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | string | — | The line, as a string. Wins over text. |
| text | string | — | The line, when it is not given as children. |
| as | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div" | "p" | The element that carries the line. |
| aperture | number | 2.8 | The f-number, 1 to 16: lower is a wider aperture and softer out-of-focus words. |
| sweep | number | 1100 | How long the focal plane takes to cross the line, ms. |
| breath | number | 0.5 | How far focus breathes past each word: 0 lands dead on (snap), 1 breathes twice (recoil). |
| depth | number | 1.5 | Depth of field on a re-rack: words either side of the focused one that stay partly sharp. |
| shrink | number | 0.04 | Lens breathing: how much smaller a fully soft word reads, 0 to 0.12. |
| fade | number | 0.4 | How much opacity a fully soft word loses, 0 to 1. |
| peaking | boolean | true | Flash a focus-peaking edge on a word as it comes sharp. |
| peakColor | string | "var(--accent-bright)" | The peaking colour, any CSS colour. |
| interactive | boolean | true | Pointing at a word, tapping it or the arrow keys rack focus to it. |
| rest | "deep" | "hold" | "deep" | What leaving the line does: stop down so every word is sharp, or keep the pull. |
| value / defaultValue | number | null | null | The focused word's index; null is everything in focus. |
| onValueChange | (index: number | null) => void | — | Fires from the hover, tap or key that moved the focus. |
| trigger | "mount" | "inView" | "hover" | "manual" | "inView" | When the sweep plays. |
| once | boolean | true | Play once, or again each time it re-enters view or is hovered. |
| delay | number | 0 | Wait before the sweep, ms. |
| play | boolean | false | With trigger "manual": true plays the sweep, false returns the line to soft. |
| onComplete | () => void | — | The sweep has settled. |
| className | string | — | Classes for the root; the type size and colour are inherited from here. |