Make a moving circle fade over time

Hi!

I’m having a bit of a hard time understand how I can make a moving circle fade over time. I tried drawing a rectangle with an alpha of 50 (I also tried other value) and my circle fade over time, but it still leaves a trace that doesn’t disappear over time.

I also tried the filter() method with BLUR, but the results aren’t what I’m expecting.

I also tried different combinations of background(rgb, alpha) in the setup() and in the draw() function, doesn’t work…

I also tried to play with the display() function in my Mover class.

I notice that when I put a high alpha value (100 for example) in the fill() function, it looks like it solve the problem, but if I look closely I can still see the the whole trail from the very beginning…

So, just to be clear, my circle is moving around the screen. I want it to leave a trail behind it that will fade slowly over time and finally disappear completely. Here’s my code:

Mover mover;

void setup() {
  size(1000, 1000);
  mover = new Mover();
  background(100);
}

void draw() {
  //background(100, 50);
  noStroke();
  fill(100, 20);
  rect(0, 0, width, height);
  mover.update();
  mover.checkEdges();
  mover.display();
  println(frameRate);
}

and here is my “mover” class, just in case you want to run the thing…

class Mover {

  PVector location;
  PVector velocity;
  PVector acceleration;
  float topspeed;
  float ty = 0;
  float tx = 10000;

  Mover() {
    location = new PVector(width/2, height/2);
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
    topspeed = 10;
  }

  void update() {

    acceleration.x = map(noise(tx), 0, 1, -2, 2);
    acceleration.y = map(noise(ty), 0, 1, -2, 2);
    
    tx += 0.05;
    ty += 0.05;


    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
  }

  void display() {
    stroke(0);
    fill(175);
    ellipse(location.x, location.y, 16, 16);
  }

  void checkEdges() {
    if (location.x > width) {
      location.x = 0;
    } else if (location.x < 0) {
      location.x = width;
    }

    if (location.y > height) {
      location.y = 0;
    } else if (location.y < 0) {
      location.y = height;
    }
  }
}

Thanks! I hope my post is not too long! :slight_smile:

Hi @yanfqc,

When you draw something with transparency on top of something else, it won’t become the color that you set. In other words, It is not because you draw 255 times a grey color with a 1 value as opacity that the end result will that grey color.

Check this exemple to see what I mean:

void setup() {
  size(1000, 1000);
  background(255,0,0);
}

void draw() {
  noStroke();
  fill(100, 1);
  rect(0, 0, width, height);
}

I start with a red background and every frame draw a grey transparent rectangle. The end result is a less bright red but it is not a grey 100.

Now to tackle your problem, what you need to do is to keep track of the previous positions of your mover in an array.
Every loop you erase everything that was drawn on the previous frame and you use your array of previous positions to draw the circles from the older position to the newer one. You then just need to brighten the color of each circle a bit more every time.

1 Like

Thank you for your reply!

I now understand better and I will certainly try your solution!

1 Like