KQ-1356 · LENS/WARP

Lens Warp

A headline under a moving glass bead: letters near its centre magnify and are pushed outward with a smooth radial falloff, letters at its rim are squeezed and drawn in, and a faint highlight rides the glass — per-letter offsets and scale only, no filters. Every letter follows its target on its own spring, integrated in one loop: the springs.snap constants while the bead is on the words, so the type tracks it crisply, and a softer under-damped spring when it leaves, so the type relaxes with a wobble. The bead follows a mouse or pen 1:1, comes down under a finger, and makes one pass across the words when the trigger fires; with keyboard focus it lands on the first word, Left and Right walk it word by word on springs.glide, Home/End jump and Escape lifts it.

KQ-1356 · LENS/WARP

Gaugeworks · loupes and lenses

Every detail, a little closer

Use Left and Right to move the lens across the words; Escape lifts it.

resting · move over the words or tab in

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/lens-warp

Props

text
string
default —
The headline under the glass.
as
"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "div"
default "h2"
The text element rendered.
radius
number
default 52
The bead's radius, px — never more than 1.5 times the type size; the piece reserves room above and below the words for it.
power
number
default 0.55
Magnification and bulge, 0 to 1.
specular
number
default 0.6
The highlight riding the bead, 0 to 1.
rim
number
default 0.5
How much the letters at the bead's rim are squeezed, 0 to 1.
wobble
number
default 0.5
How much the type wobbles as it relaxes when the bead leaves, 0 (none) to 1.
bead
boolean
default true
Draw the glass disc itself; off leaves only the letters bending.
tint
string
default "var(--accent-bright)"
The colour letters lean toward at the bead's centre.
interactive
boolean
default true
The pointer and the keyboard move the bead.
trigger
"mount" | "inView" | "hover" | "manual"
default "inView"
When the bead makes its one pass across the words: on mount, when scrolled into view, never (hover only), or when active turns true.
once
boolean
default true
Make the pass only the first time.
delay
number
default 250
Wait before the pass, ms.
duration
number
default 1600
How long the pass takes to cross the words, ms.
active
boolean
default —
For trigger="manual": true runs the pass.
onComplete
() => void
default —
Fires when the pass is over and the type has relaxed.
onWordChange
(word: string | null) => void
default —
Fires when the visitor moves the bead onto another word — by pointer or keys — and with null when it lifts; the automatic pass is not reported.
className
string
default —
Classes for the wrapper; set the type size, weight and colour here.