Noob help: Making a circle grow by a mouse hovering over it and making it shrink when the mouse cursor is off of it

I’m a noob at pde and I’m trying to figure out to make a circle grow when the mouse is hovering over it and make it shrink when the mouse cursor is off of it

Since the circle’s size is going to change, you will probably want a variable to remember how big the circle currently is.

And then you will want to draw a circle that is as big as that variable says it should be.

With just that for a start, we can write some code:

float circle_size = 30;

void setup(){
  size(400,400);
}

void draw(){
  background(0);
  ellipse(200,200,circle_size, circle_size);
}

Try running this code. Are there any errors? Does it run? Do you understand it?


Now the next thing we know we are going to need to work out is if the mouse cursor is over the circle. We know the mouse cursor is always at the position (mouseX, mouseY). How far is it between the center of the circle and that position if the mouse is over the circle? That is, what can you say about the distance between the mouse and the center of the circle when you compare it to the size of the circle?

That’s right - when that distance is less that the circle’s radius, the mouse is over the circle. Let’s write a function that can determine if the mouse is over the circle:

boolean is_mouse_over_circle(){
  return( dist( mouseX, mouseY, 200, 200 ) < circle_size );
}

Look at that code again and make sure you understand it! It’s the CORE FUNCTIONALITY we want!

We are working out a distance.
Between the mouse position: ( mouseX, mouseY ),
And the circle’s center: ( 200, 200 )
If that distance is less than the circle’s size…
We return true because the mouse is on the circle.
Otherwise…
We return false because it is outside the circle.


Can we use our function to test if it works properly? Yes!
Let’s change the color of the circle if the mouse is over it:

float circle_size = 30;

void setup(){
  size(400,400);
}

void draw(){
  background(0);
  fill(255); // White.
  if( is_mouse_over_circle() ){
    fill(255,0,0); // Red if we are over it.
  }
  ellipse(200,200,circle_size, circle_size);
}

boolean is_mouse_over_circle(){
  return( dist( mouseX, mouseY, 200, 200 ) < circle_size );
}

Try running this! Are there errors? Does it work? Do you understand it? Do you understand what is wrong?!?

2 Likes

What’s wrong is that there is a software bug! We thought we did everything right, but our sketch doesn’t act the way we thought it would: If the mouse gets close to the circle, it turns red. It doesn’t have to be over it. So what’s the problem?

Our code is doing what we asked it to do. Exactly what we asked.
So we must have asked it to do the wrong thing!
That is, there is a discrepancy between what we think the code does and what it actually does.


In this case, the trouble is with circle_size. What does this value represent? The size of the circle, sure. But what does THAT ACTUALLY MEAN?!?

Is it the radius of the circle?
… or the diameter?

When we drew the circle, it was the diameter.
When our function used it to check if the mouse was over it, it used it like a radius!

We need to be clear about this: It’s a radius.
So we fix the code:

float circle_radius = 30;

void setup(){
  size(400,400);
}

void draw(){
  background(0);
  fill(255); // White.
  if( is_mouse_over_circle() ){
    fill(255,0,0); // Red if we are over it.
  }
  ellipse(200,200,circle_radius*2, circle_radius*2);
}

boolean is_mouse_over_circle(){
  return( dist( mouseX, mouseY, 200, 200 ) < circle_radius );
}

Now that we can see our is-mouse-over-circle code is working, we can use that check to change the circle’s radius:

float circle_radius = 30;

void setup() {
  size(400, 400);
}

void draw() {
  background(0);
  if ( is_mouse_over_circle() ) {
    fill(255, 0, 0); // Red if we are over it.
    circle_radius++; // And it grows bigger!
  } else { // Otherwise...
    fill(255); // It's white.
    circle_radius--; // It shrinks.
  }
  ellipse(200, 200, circle_radius*2, circle_radius*2);
}

boolean is_mouse_over_circle() {
  return( dist( mouseX, mouseY, 200, 200 ) < circle_radius );
}

Try running this. Does it have errors? Does it work? Oops! The circle implodes and then becomes very large super fast!

Maybe we should tweak the values:

float circle_radius = 30;

void setup() {
  size(400, 400);
}

void draw() {
  background(0);
  if ( is_mouse_over_circle() ) {
    fill(255, 0, 0);
    circle_radius++;
  } else {
    fill(255);
    circle_radius-=0.1; // It shrinks... slowly
  }
  ellipse(200, 200, circle_radius*2, circle_radius*2);
}

boolean is_mouse_over_circle() {
  return( dist( mouseX, mouseY, 200, 200 ) < circle_radius );
}

Well, that’s about what you wanted. But why did it grow super large when it shrunk fast before? Well, its size went negative… and got very largely negative. We should probably add bounds for the size of the circle:

float circle_radius = 30;

void setup() {
  size(400, 400);
}

void draw() {
  background(0);
  if ( is_mouse_over_circle() ) {
    circle_radius++;
  } else {
    circle_radius-=0.1;
  }
  // Limit circle size to sane values.
  circle_radius = constrain( circle_radius, 20, 190 );
  ellipse(200, 200, circle_radius*2, circle_radius*2);
}

boolean is_mouse_over_circle() {
  return( dist( mouseX, mouseY, 200, 200 ) < circle_radius );
}

Try running this! Does it run without errors? Does it do what we want? Do you understand it still? Do you see how we took small steps, making sure to maintain the properties of having no errors and understanding it?

2 Likes