KQ-1554 · OPTICAL/MIX
Optical Mix
A headline painted in dabs of separate pure pigments laid in an ordered dither on a hex lattice, so no two touching dabs share a colour and from reading distance they fuse into one tone; the real text stays the element's own selectable text and the paint is sampled from its exact layout. Hovering opens a soft lens whose fisheye pushes the dabs apart and swells them, each pigment opening on the glide spring 45 ms after the last like light through a prism and closing on the slower drift spring, while idle dabs breathe and the line is painted on left to right on the snap spring. Keyboard focus sweeps the lens along the line; Left and Right move it word to word, Home and End jump, Enter sweeps again and Escape closes it.
Fieldline Gallery · Summer rooms
Light, one dot at a time
Arrow keys move a lens along the line to see its separate colours; Escape closes it.Forty paintings made of nothing but points. Until 14 September.
at rest · four pigments read as one tone
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/optical-mix
Props
- text
- string
- default —
- The headline; it stays the element's real, selectable text.
- as
- "h1" | "h2" | "h3" | "p" | "span" | "div"
- default "h2"
- The element that carries the text.
- dotSize
- number
- default 2.5
- Diameter of one dab, px on a 60 px line; dabs scale with the type.
- palette
- "field" | "dusk" | "press" | "tide"
- default "field"
- The pigments the line is painted in, each set at one lightness so it fuses.
- colors
- string[]
- default —
- Any CSS colours, two to six; replaces palette.
- density
- number
- default 0.8
- How tightly the dabs pack, 0 (open weave) to 1 (just overlapping).
- spread
- number
- default 0.6
- How far the lens pulls the dabs apart, 0 (they only swell) to 1.
- magnify
- number
- default 2.2
- How much the dabs swell under the lens, 1 to 4.
- lensRadius
- number
- default 70
- The lens radius, px; held to about 1.3 times the font size.
- twinkle
- number
- default 0.5
- How much the dabs breathe while idle, 0 (still) to 1.
- interactive
- boolean
- default true
- The pointer and the keyboard can bring the lens.
- trigger
- "mount" | "inView"
- default "inView"
- When the dabs are painted on.
- once
- boolean
- default true
- Paint on only the first time the line is seen.
- delay
- number
- default 0
- Wait before painting on, ms.
- paused
- boolean
- default false
- Hold the idle breathing; the lens still works.
- seed
- number
- default 1
- Twists the dither so two lines never share a pattern.
- dpr
- number
- default 2
- Cap on the canvas pixel ratio, 1 to 2.
- onComplete
- () => void
- default —
- The dabs have all been painted on.
- onLensChange
- (word: string | null) => void
- default —
- The word under the lens, or null when it closes.
- className
- string
- default —
- Size, weight and alignment; the type is inherited.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | — | The headline; it stays the element's real, selectable text. |
| as | "h1" | "h2" | "h3" | "p" | "span" | "div" | "h2" | The element that carries the text. |
| dotSize | number | 2.5 | Diameter of one dab, px on a 60 px line; dabs scale with the type. |
| palette | "field" | "dusk" | "press" | "tide" | "field" | The pigments the line is painted in, each set at one lightness so it fuses. |
| colors | string[] | — | Any CSS colours, two to six; replaces palette. |
| density | number | 0.8 | How tightly the dabs pack, 0 (open weave) to 1 (just overlapping). |
| spread | number | 0.6 | How far the lens pulls the dabs apart, 0 (they only swell) to 1. |
| magnify | number | 2.2 | How much the dabs swell under the lens, 1 to 4. |
| lensRadius | number | 70 | The lens radius, px; held to about 1.3 times the font size. |
| twinkle | number | 0.5 | How much the dabs breathe while idle, 0 (still) to 1. |
| interactive | boolean | true | The pointer and the keyboard can bring the lens. |
| trigger | "mount" | "inView" | "inView" | When the dabs are painted on. |
| once | boolean | true | Paint on only the first time the line is seen. |
| delay | number | 0 | Wait before painting on, ms. |
| paused | boolean | false | Hold the idle breathing; the lens still works. |
| seed | number | 1 | Twists the dither so two lines never share a pattern. |
| dpr | number | 2 | Cap on the canvas pixel ratio, 1 to 2. |
| onComplete | () => void | — | The dabs have all been painted on. |
| onLensChange | (word: string | null) => void | — | The word under the lens, or null when it closes. |
| className | string | — | Size, weight and alignment; the type is inherited. |