Trailing Cursor

Canvas dots that trail behind the cursor, fading out toward the tail. Adjust trail length, follow speed, dot size, and color with the live controls.

Generated using Grepped's AI UI component generator — created from scratch, not pulled from a library.

cursorcanvastraildotsinteractive

Live Preview — customize or regenerate this in the workspace

Loading preview…

Design Intent

A canvas-based cursor trail of fading dots: each particle follows the next with a lerp factor, and opacity and radius decrease toward the tail.

CSS

css
* { margin: 0; padding: 0; box-sizing: border-box; }
    html, body { width: 100%; height: 100%; overflow: hidden; background: #0f0f0f; cursor: none; }
    .hint { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); font-family: sans-serif; font-size: 16px; color: #ffffff; opacity: 0.45; pointer-events: none; user-select: none; letter-spacing: 0.04em; }
    canvas { position: fixed; top: 0; left: 0; pointer-events: none; }

HTML

html
<p class="hint">Move your cursor here</p>
  <canvas id="c"></canvas>

Full Source

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    html, body { width: 100%; height: 100%; overflow: hidden; background: #0f0f0f; cursor: none; }
    .hint { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); font-family: sans-serif; font-size: 16px; color: #ffffff; opacity: 0.45; pointer-events: none; user-select: none; letter-spacing: 0.04em; }
    canvas { position: fixed; top: 0; left: 0; pointer-events: none; }
  </style>
</head>
<body>
  <p class="hint">Move your cursor here</p>
  <canvas id="c"></canvas>
  <script>
    var N    = 15;
    var RATE = 0.4;
    var COL  = '#6366f1';
    var SZ   = 6;

    var canvas = document.getElementById('c');
    var ctx = canvas.getContext('2d');
    var cur = {x: -999, y: -999};
    var pts = [];
    var initted = false;

    function resize() { canvas.width = innerWidth; canvas.height = innerHeight; }

    function frame() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      if (!initted) { requestAnimationFrame(frame); return; }
      var x = cur.x, y = cur.y;
      pts.forEach(function(p, i) {
        var np = pts[i+1] || pts[0];
        p.x = x; p.y = y;
        var prog = i / pts.length;
        ctx.beginPath();
        ctx.arc(p.x, p.y, Math.max(0.5, SZ * (1 - prog * 0.65)), 0, Math.PI * 2);
        ctx.fillStyle = COL;
        ctx.globalAlpha = 1 - prog;
        ctx.fill();
        x += (np.x - p.x) * RATE;
        y += (np.y - p.y) * RATE;
      });
      ctx.globalAlpha = 1;
      requestAnimationFrame(frame);
    }

    document.addEventListener('mousemove', function(e) {
      cur.x = e.clientX; cur.y = e.clientY;
      if (!initted) {
        initted = true;
        for (var i = 0; i < N; i++) pts.push({x: cur.x, y: cur.y});
      }
    });

    window.addEventListener('resize', resize);
    resize();
    frame();
  </script>
</body>
</html>

More Cursor Effects Animations