Advertisement

Footstep Cursor Trailer

| by Vladimir | 2 min read | code by Ksenia Kondrashova
Intermediate

Tech & Dependencies

HTML CSS JavaScript
GSAP

Features

  • Cursor Tracking
  • SVG Symbols
  • Dynamic Rotation
  • Intro Animation

Browser Support

Chrome 51+ Edge 79+ Firefox 52+ Safari 10+

Core

This is a Footstep Cursor Trailer. It draws a decaying trail of alternating left and right vector footprints that follow the user’s pointer. Its function is to add a highly stylized, playful layer of interaction to empty background spaces, gamifying the simple act of moving a mouse.

Specs

  • Weight: ~75 KB (Dependencies: GSAP Core).
  • Performance: High. Uses GSAP to animate SVG <use> attributes (x, y, rotation, opacity) without triggering expensive DOM reflows. The logic loop runs efficiently via requestAnimationFrame.
  • Theming / Customization: Easily modifiable via JS constants (stepsNumber, iconSize, mouseRepel). The footprint graphic can be swapped by editing the <path id="feet-shape"> in the HTML.
  • Responsiveness: Native. Tracks both mousemove and touchmove events, adapting the SVG viewBox dynamically on window resize.
  • Web APIs: requestAnimationFrame.
  • Graceful Degradation: Fails invisibly. If JavaScript is disabled or crashes, the script simply does not execute, leaving a blank white screen with no broken geometry or errors visible to the user.

Anatomy

  • HTML: An inline <svg> acting as a sprite sheet. It defines a single <path id="feet-shape"> and creates two reusable <symbol> templates (#feet-left, #feet-right), utilizing scale(-1, 1) to horizontally flip the shape for the right foot.
  • CSS: Stripped down. It removes margins and overflow to ensure the SVG canvas perfectly spans the viewport.
  • JS: The logic engine. It handles array management for the step history, calculates travel distance via Pythagorean theorem, computes trigonometric rotation (Math.atan2), and drives the fading opacity lifecycle within a continuous render loop.

Logic

The script’s elegance lies in how it paces the footprint generation based on distance rather than time.

accumDx += pointer.dx;
accumDy += pointer.dy;
pointer.angle = Math.atan2(pointer.dx, pointer.dy);
accumDist = Math.sqrt(Math.pow(accumDx, 2) + Math.pow(accumDy, 2));

if (accumDist > 70) {
    stepsCnt++;
    accumDx = 0;
    accumDy = 0;
    accumDist = 0;
    // ... spawn footprint
}

Instead of spawning footprints inside a rigid setInterval, the code accumulates the X and Y deltas of the cursor movement to calculate the absolute distance traveled (Math.sqrt(...)). A new footprint is only generated when the cursor travels exactly 70 pixels from the last step. This ensures the spacing between footsteps remains perfectly consistent, regardless of whether the user moves the mouse rapidly or slowly.

Feel

Playful and precise. The footsteps don’t just appear; they alternate seamlessly, matching the exact trajectory and angle of the cursor. When the mouse stops, the script performs a “catch-up” sequence, bringing the feet together into a natural standing position. The gradual fading of older footprints gives the interaction a satisfying, ephemeral quality, like walking through fresh snow.

Advertisement