Sarath
Sarath

Reputation: 9146

How to Optimize js animation with requestAnimationFrame and introduce delta?

I have a basic animation of a ball falling with a gradually increasing velocity.

DEMO

It is somewhat working as expected with an expected velocity initially. So on click on the canvas we can repeat the animation , so each time we can see the ball speed keeps increasing. After 5-6 click the ball is moving with high velocity.

So is the issue is with frame rate , and expected unit move per frame. ?

1. How to reduce/optimize the loop call ? , and get a constant velocity in each click.

I wont prefer to change the value inside Ball model, but the time of ball.update() must be reduced.

var ball = new Ball(10,10,20);

function animate() {    
    ctx.fillStyle = "#CCC";
    ctx.fillStyle = "#CCC";
    ctx.fillRect(0, 0, 500, 500);    
    ball.update();
    ball.draw(ctx);
    requestAnimationFrame(animate); // add timestamp to optimize ?
}

and on click the reset animation is like this

$("#element").on('click', function () {
      ball = new Ball(10,10,20)
      requestAnimationFrame(animate);
});

and 2. Why it is working with expected speed initialy ? and I prefer to clear the animation after the ball moves out of canvas.

Upvotes: 1

Views: 1184

Answers (2)

user1693593
user1693593

Reputation:

The main reason is that you are combining setTimeout with requestAnimationFrame which kind of defeat its purpose.

Not only are your rAF triggered by an inaccurate timer but when rAF kicks in it is not sure you will get a frame for that round which can produce jerky result.

Change these lines:

setTimeout(function () {
    animationId = requestAnimationFrame(animate);
}, 1000/60);

to

//setTimeout(function () {
animationId = requestAnimationFrame(animate);
//}, 1000/60);

Then reset your ball as with Greg's answer. There is no need to call rAF again as it is already running:

$(function(){    
    requestAnimationFrame(animate);    
    $("#element").on('click', function () {
      ball = new Ball(10,10,20);
    });
});

Modified fiddle

You could also reset the ball by updating its properties.

Upvotes: 2

Greg Jennings
Greg Jennings

Reputation: 1641

Here's a fork of your fiddle that works: http://jsfiddle.net/8egrw/

Comment out this line:

$("#element").on('click', function () {
  ball = new Ball(10,10,20)
  //animationId = requestAnimationFrame(animate);
});

Upvotes: 0

Related Questions