Image Trail Component

A cursor-driven effect that spawns a trail of images as the pointer moves across a scoped area — the editorial, portfolio-site look, built to stay out of the way of your interactive UI.

Features

  • Scoped to its own container — nothing spawns outside it, and the trail layer is pointer-events: none, so links and buttons underneath stay fully clickable.
  • Distance-based spawning: a still cursor emits nothing, fast movement reads as a trail.
  • Suppresses over interactive elements via a configurable ignoreSelector.
  • Five appearance styles — scale, fade, blur, rise, and tilt.
  • Fixed image budget (maxImages) with automatic recycling — no unbounded DOM growth.
  • Respects prefers-reduced-motion and only runs for a fine (mouse) pointer.

Move your cursor here

Interactive content underneath

The trail layer is pointer-events: none, so images can visually sit on top of buttons and links without ever intercepting clicks or hover. The effect also skips spawning while the cursor is over anything matching ignoreSelector (default a, button, input, [data-image-trail-ignore]), keeping interactive UI unobstructed. Sweep across the area below, then click the button or hover the link.

Sweep the cursor to spawn the trail, then click the button or the link — the images never block them.

A link that stays hoverable

Variants

Each appearance style has its own enter/exit motion. Set it via the variant prop.

Blur

Blur trail

Tilt

Tilt trail

Playground

Change the appearance style, spawn distance, image budget, and lifetime, then move your cursor across the area.

Move your cursor here
Controls
Controls

Installation

Usage

Props

PropertyTypeDefaultDescription
imagesstring[]requiredImage sources spawned in order as the pointer moves.
childrenReactNoderequiredThe content the effect is scoped to; the trail only spawns over this area.
classNamestringAdditional CSS classes for the container.
itemClassNamestring"w-40"Extra classes for each trail image (use for sizing, e.g. `"w-48"`).
thresholdnumber80Pointer distance in pixels travelled before the next image spawns.
maxImagesnumber8Maximum number of images alive at once.
lifetimenumber600How long an image stays before it animates out, in milliseconds.
variant"scale" | "fade" | "blur" | "rise" | "tilt""scale"Entrance and exit animation style.
ignoreSelectorstring"a, button, input, [data-image-trail-ignore]"CSS selector for elements that suppress the effect when hovered, keeping interactive UI unobstructed.
zIndexnumber10z-index of the trail layer.