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