Cursor Trail Effect

How do I implement a cursor trail effect?

A cursor trail effect can be created by storing recent mouse positions and drawing them with decreasing opacity. Here's how to implement it:

#include <SDL.h>
#include <cmath>
#include <iostream>
#include <vector>
#include "Window.h"

class CursorTrail {
 public:
  void Tick() {
    // Get current mouse position
    int MouseX, MouseY;
    SDL_GetMouseState(&MouseX, &MouseY);

    // Add new position to trail
    TrailPoints.push_back({MouseX, MouseY});

    // Remove old positions if trail is too long
    while (TrailPoints.size() > MaxTrailLength) {
      TrailPoints.erase(TrailPoints.begin());
    }

    // Print current trail for demonstration
    PrintTrail();
  }

 private:
  struct Point {
    int X, Y;
  };

  static const size_t MaxTrailLength = 10;
  std::vector<Point> TrailPoints;

  void PrintTrail() {
    std::cout << "Trail: ";
    for (size_t i = 0; i < TrailPoints.size(); ++i) {
      float Opacity = static_cast<float>(i)
        / TrailPoints.size();
      std::cout << "(" << TrailPoints[i].X
        << "," << TrailPoints[i].Y << "|"
        << std::round(Opacity * 100) << "%) ";
    }
    std::cout << "\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  Window GameWindow;
  CursorTrail Trail;
  SDL_Event E;

  while (true) {
    while (SDL_PollEvent(&E)) {
      // Handle other events...
    }

    Trail.Tick();
    GameWindow.Update();
  }

  SDL_Quit();
  return 0;
}
Trail: (100,150|10%) (102,152|20%) (105,155|30%) (108,158|40%) (112,162|50%)
Trail: (100,150|10%) (102,152|20%) (105,155|30%) (108,158|40%) (112,162|50%) (115,165|60%)

Enhanced Version

Here's a more advanced version with smoothing and custom trail behavior:

#include <SDL.h>
#include <cmath>
#include <vector>

class AdvancedCursorTrail {
 public:
  void Tick() {
    // Get current time and position
    Uint32 CurrentTime = SDL_GetTicks();
    int MouseX, MouseY;
    SDL_GetMouseState(&MouseX, &MouseY);

    // Only add new point if moved enough
    if (TrailPoints.empty() ||
      DistanceToLastPoint(MouseX, MouseY)
        > MinDistance) {
      TrailPoint NewPoint{
        static_cast<float>(MouseX),
        static_cast<float>(MouseY),
        CurrentTime
      };

      TrailPoints.push_back(NewPoint);
    }

    // Remove expired points
    while (!TrailPoints.empty() &&
      CurrentTime - TrailPoints.front().Time
        > TrailDuration
    ) {
      TrailPoints.erase(TrailPoints.begin());
    }

    // Smooth existing points
    SmoothTrail();
  }

 private:
  struct TrailPoint {
    float X, Y;
    Uint32 Time;
  };

  std::vector<TrailPoint> TrailPoints;
  // Trail Duration in Milliseconds
  static const Uint32 TrailDuration = 500;
  static const float MinDistance = 5.0f;

  float DistanceToLastPoint(int X, int Y) {
    if (TrailPoints.empty()) {
      return MinDistance + 1;
    }

    auto& Last = TrailPoints.back();
    float DX = X - Last.X;
    float DY = Y - Last.Y;
    return std::sqrt(DX * DX + DY * DY);
  }

  void SmoothTrail() {
    for (
      size_t i = 1;
      i < TrailPoints.size() - 1;
      ++i
    ) {
      TrailPoints[i].X = (
        TrailPoints[i - 1].X +
        TrailPoints[i].X * 2 +
        TrailPoints[i + 1].X
      ) / 4;

      TrailPoints[i].Y = (
        TrailPoints[i - 1].Y +
        TrailPoints[i].Y * 2 +
        TrailPoints[i + 1].Y
      ) / 4;
    }
  }
};

This enhanced version includes:

  • Time-based trail duration instead of fixed length
  • Minimum distance between points to prevent clustering
  • Smooth interpolation between points
  • Floating-point positions for smoother curves
  • Automatic cleanup of old trail points

You can customize the trail effect by adjusting:

  • TrailDuration: How long points remain visible
  • MinDistance: Minimum distance between points
  • Smoothing algorithm parameters
  • Trail point fade out behavior
  • Trail thickness and color gradients

This system can be used for:

  • Cursor effects in menus
  • Spell casting trails in games
  • Motion visualization
  • Drawing guides in art programs

Mouse State

Learn how to monitor mouse position and button states in real-time using SDL's state query functions

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Calculating Mouse Pointer Angle
How can I get the mouse pointer's angle relative to a position on the screen?
Calculating Mouse Speed
Can I get the mouse speed or how fast it's moving?
Click and Drag Detection
How do I detect if the user is clicking and dragging?
Events vs State for Mouse Input
What's the difference between using events and using state checking for mouse position?
Smooth Mouse Following
How can I make an object follow the mouse cursor smoothly?
Click-and-Drag Selection
How do I implement a click-and-drag selection rectangle?
Or Ask your Own Question
Purchase the course to ask your own questions