KQ-1360 · AFTER/IMAGE

After Image

Every word keeps a short timestamped history of where it has been, and its echoes are placed where it was a few lag milliseconds ago — fainter and turned further round the hue circle the older they are — so motion fans out behind it as a chromatic afterglow that folds back in when it stops. Words arrive on curved paths (x on springs.glide, y on springs.snap), a dragged word follows 1:1 with its neighbours trailing, and on release every word springs home on springs.recoil with the throw's velocity while one faint echo breathes at rest. Arrow keys throw the words the same way and Enter brings them in again.

KQ-1360 · AFTER/IMAGE

Waylight · lamps that linger

Light that lingers

Arrow keys throw the words; Enter brings them in again.

settled · drag a word across

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/after-image

Props

text
string
default —
The words; each one trails its own echoes.
as
"h1" | "h2" | "h3" | "p" | "span" | "div"
default "p"
The element rendered.
echoes
number
default 5
Copies trailing each word, 1 to 8.
lag
number
default 40
Time between one echo and the next, ms: longer lags draw longer streaks.
hue
number
default 20
Hue drift from one echo to the next, degrees: 0 is one colour, 60 a spectrum.
color
string
default "var(--accent-bright)"
The nearest echo's colour, any CSS colour.
fade
number
default 0.55
Opacity of the nearest echo, 0 to 1; older echoes decay from it.
glow
number
default 0.4
A soft halo on the echoes, 0 to 1.
breathe
boolean
default true
One faint echo breathes behind the resting text.
enter
"sweep" | "rise" | "scatter"
default "sweep"
The path the words arrive on.
pull
number
default 0.55
How much a dragged word's neighbours follow it, 0 to 1.
sweep
number
default 0.4
How hard the pointer passing over a word kicks it, 0 (off) to 1.
trigger
"mount" | "inView" | "hover" | "manual"
default "inView"
What brings the words in.
once
boolean
default true
Arrive once; false sends the words out when it leaves view or the hover ends.
play
boolean
default —
Manual trigger: true brings the words in, false sends them out.
delay
number
default 0
Wait before the first word, ms.
stagger
number
default 80
Gap between words arriving, ms.
duration
number
default 500
Time scale of the arrival springs, ms; their damping ratios are kept.
interactive
boolean
default true
Drag, hover kicks and keyboard throws.
onMotionChange
(moving: boolean) => void
default —
The words started moving (true), or every echo has caught up (false).
onComplete
() => void
default —
The arrival has settled.
className
string
default —
Size and type; offsets are in em.