Rachel Dockter
Rachel Dockter

Reputation: 986

Make a ball on a canvas slowly move towards the mouse

I am trying to make a ball move slowly towards my mouse.

Im using paper.js which is a simple animation library. Using this i have a ball moving on screen. These are some of the properties of the ball:

balls[0].vector.angle is its direction. 0 = right, 90 = down, 180 = left etc and everything in between

balls[0].point.x is its x position and .y for y position.

balls[0].vector.length is its speed.

I have put in a mouse move event and i think ive got the angle between them below:

    canvas.addEventListener("mousemove", function(e){

    var a = balls[0].point.y - e.clientY;
    var b = balls[0].point.x - e.clientX;
    var angleDeg = Math.atan2(a, b) * 180 / Math.PI;
});

So i have made the ball stationary to test this and moved my mouse around it. To the left of the ball gives me 0 degrees. Above gives me 90. To the right gives me 180. And below the ball gives me -90 etc and everything in between.

I then calculated the distance in the same event and changed the speed to reflect the distance giving it a cap as max speed:

var distance = Math.sqrt( a*a + b*b );

var maxSpeed = 20; 
balls[0].vector.length = (distance/30 > maxSpeed) ? maxSpeed : distance/30;

So ive tested the speed and this and it works perfect. When i give the ball the angle from earlier its going in all sorts of directions. The speed still works, its just the ball is going in the wrong direction and im not sure what ive done wrong.

Upvotes: 5

Views: 641

Answers (2)

9000
9000

Reputation: 40894

Frankly, you don't need trig functions. All you need is good old Pythagoras theorem.

var MAX_SPEED = 20;
var MIN_SPEED = 0.25; // Very slow if close but not frozen.
var ATTRACTION = 0.5; 
var diff_y = e.clientY - balls[0].point.y;
var diff_x = e.clientX - balls[0].point.x;
var distance = Math.sqrt(diff_x * diff_x + diff_y * diff_y)
var speed = distance * ATTRACTION;
if (speed > MAX_SPEED) speed = MAX_SPEED;
if (speed < MIN_SPEED) speed = MIN_SPEED;
// The rates along axes are proportional to speed;
// we use ratios instead of sine / cosine.
balls[0].point.x += (diff_x / distance) * speed;
balls[0].point.y += (diff_y / distance) * speed;

Much more fun can be had by introducing forces and inertia.

Upvotes: 2

user4843530
user4843530

Reputation:

Specify the direction in terms of deltas

var deltaX = e.clientX - balls[0].point.x;
var deltaY = e.clientY - balls[0].point.y;
var distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);
var maxSpeed = 20; 
balls[0].vector.length = (distance/30 > maxSpeed ) ? maxSpeed  : distance / 30;
balls[0].point.x = balls[0].point.x + (balls[0].vector.length * deltaX / distance);
balls[0].point.y = balls[0].point.y + (balls[0].vector.length * deltaY / distance);

I think that will work

Upvotes: 2

Related Questions