Cursor Image Trail

A trail of images that follows the cursor with fade, scale, and rotation animations powered by Motion.

Installation

File Structure

cursor-image-trail.tsx

Usage

import { CursorImageTrail } from "@/components/unlumen-ui/cursor-image-trail";

const IMAGES = [
  "https://example.com/photo-1.jpg",
  "https://example.com/photo-2.jpg",
  "https://example.com/photo-3.jpg",
];

<CursorImageTrail images={IMAGES} className="h-[480px] w-full bg-neutral-950">
  <p className="text-white/30 select-none">Move your cursor</p>
</CursorImageTrail>;

API Reference

CursorImageTrail

images
string[]

Array of image URLs to cycle through in the trail.

imageSize?
number
120

Width and height of each trail image in pixels.

trailLength?
number
8

Maximum number of images simultaneously visible in the trail.

spawnDistance?
number
80

Minimum cursor travel in pixels before a new image is spawned.

rotationRange?
number
20

Maximum random rotation (±degrees) applied to each image.

containerRef?
React.RefObject<HTMLElement>

Optional ref to a container element. Defaults to tracking the whole window.

className?
string

Additional className for the outer wrapper div.

children?
React.ReactNode

Optional content rendered inside the trail container.

Notes

  • Images are cycled in order from the images array, wrapping back to the start.
  • Each image is centered on the spawn point using CSS transform: translate(-50%, -50%).
  • Older trail images are progressively smaller and more transparent — the newest image is always fully opaque at full scale.
  • Add cursor-none to the container className to hide the default OS cursor for full effect.
  • Pass containerRef to confine tracking to a specific element rather than the whole window.

Credits

Built by Léo.

Keep in mind

Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.