#384
Cursor trail
A chain of 14 dots that eases after the pointer, each one shrinking and following the dot ahead; autoplay traces a looping path.
Hand this to your AI. It names the exact library parts, timings and accessibility promises of this demo.
Build the "Cursor trail" pattern (@codeatlasdev/ui demo #384, motion/hero-ambient) in my app.
Call get_demo({ ids: ["#384"] }) first and keep its structure. It needs @codeatlasdev/[email protected].
Use: Playful hero sections, creative portfolios and empty canvases where the cursor should leave a soft, short-lived mark.
Keep these library parts, with the props and tokens the demo uses:
- MotionStage, MotionCtx from "@codeatlasdev/ui"
Behaviour to keep:
- `const N = 14` dots in a fixed pool: no node is created while the pointer moves
- Each frame every dot moves `0.32` of the way toward the dot ahead (`p.x += (prev.x - p.x) * 0.32`), the head follows the pointer
- Only `transform` is written: `translate3d(${p.x}px, ${p.y}px, 0) scale(${1 - i / (N + 4)})`
- The `requestAnimationFrame` loop stops when the demo leaves the viewport (`IntersectionObserver`) and when every dot has settled
- Autoplay drives a Lissajous path (`Math.cos(k * 2.1)`, `Math.sin(k * 3.2)`); under reduced motion no dots render
- `@media (pointer: coarse)` sets `touch-action: none` so a finger draws the trail instead of scrolling
Exact motion (do not approximate):
- transform: translate3d, scale (per dot): per frame, 0.32, stagger 0.32
Reduced motion: the demo handles it; keep that branch.
Keyboard: not an interactive control.
Change only the copy and the data. Use the theme tokens (--ca-*), never raw colours. Library parts
- MotionStage
@codeatlasdev/ui
How it is built
- `const N = 14` dots in a fixed pool: no node is created while the pointer moves
- Each frame every dot moves `0.32` of the way toward the dot ahead (`p.x += (prev.x - p.x) * 0.32`), the head follows the pointer
- Only `transform` is written: `translate3d(${p.x}px, ${p.y}px, 0) scale(${1 - i / (N + 4)})`
- The `requestAnimationFrame` loop stops when the demo leaves the viewport (`IntersectionObserver`) and when every dot has settled
- Autoplay drives a Lissajous path (`Math.cos(k * 2.1)`, `Math.sin(k * 3.2)`); under reduced motion no dots render
- `@media (pointer: coarse)` sets `touch-action: none` so a finger draws the trail instead of scrolling
Related
Loading source.