Question

So I want to animate the drawing of a line on the HTML 5 canvas using requestAnimationFrame.

I've done this

function animateWrapper(centerX, centerY, xAngle, yAngle, width, height) {
    var request = requestAnimationFrame(animate);
    var canvas = document.getElementById("drawing");
    var context = canvas.getContext('2d');  
    function animate (centerX, centerY, xAngle, width, height) {
        drawLine(centerX,centerY, centerX, centerY - height, context, request);
    }
}

function drawLine(startX, startY, endX, endY, context, request) {
    context.beginPath();
    context.moveTo(startX, startY);
    step += 0.05;
    // if (step > 1) step = 1;
    var newX = startX + (endX - startX) * step;
    var newY = startY + (endY - startY) * step;
    context.lineTo(newX, newY);
    context.stroke();
    if (Math.abs(newX) >= Math.abs(endX) && Math.abs(newY) >= Math.abs(endY)) {
        cancelAnimationFrame(request);
        step = 0;
    }
}

$(document).ready(function(){
    animateWrapper(100, 100, 40, 40, 400, 400);
});

Right now centerY, xAngle, width, height are all undefined(which makes sense - they aren't being passed in). This causes endY to become a NaN, so the animation does not occur.

I'm not sure how to fix this - how do I pass in those arguments in the request animation frame?

Was it helpful?

Solution 2

There is a first issue in your code : no animation will occur, since you only call requestAnimationFrame (rAF) once. You can think of rAF as a setTimeout that will trigger once the next time screen is available, not a setInterval that will call again and again each time.

Second issue is a classical javascript closure/binding/scope issue.
So first solution would be to switch to a more modern language like google Dart (:-)).
Other solution is, for instance, to bind your animate function to its parameters.
In javascript, if your do :

var myBoundFunction = someFunction.bind(null, arg1, arg2, arg3);

then later, calling

myBoundFunction();

will have the same effect as calling :

someFunction(arg1, arg2, arg3);

look here for more details, and about the use of the first argument :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

I could give you a hint on how to change your code, but anyway i guess you'll want to animate several lines, so you must change the way it works to make it more flexible.
I strongly encourage you to go object and define a line as an object having (x,y,...) and a draw and update method.

Something like (using a closure this time) :

var canvas   = ... ;    // do the DOM access only once
var context  = ... ;   // do the DOM accessd only once      
var myObjectsToDraw = [];

function animate() {
       ... return and stop animation if some condition is met ...
       requestAnimationFrame(animate);
       ... clear screen ..
       // draw all objects
       for (var i in myObjectsToDraw) myObjectsToDraw[i].draw();
       // update all objects
       for (var i in myObjectsToDraw) myObjectsToDraw[i].update();
}

myObjectsToDraw.push ( ... some object ... );
animate();

(( if you're interested, here's the animation loop i use : http://jsfiddle.net/gamealchemist/KVDsc/
and my base fiddle with a bunch of small utilities http://jsfiddle.net/gamealchemist/Vn2Nt/ ))

OTHER TIPS

This should work:

function animateWrapper(centerX, centerY, xAngle, yAngle, width, height) {
    function animate () {
        drawLine(centerX,centerY, centerX, centerY - height, context, request);
    }

    var request = requestAnimationFrame(animate);
    var canvas = document.getElementById("drawing");
    var context = canvas.getContext('2d');  
}

You don't have to call animate() with any arguments since the variables centerX, centerY, ... and height are in scope when animate() is defined (i.e. they were known at that time, so you can simply use them inside of the function).

The answer to this question lists all kinds of ways that variables are/become visible/usable in JavaScript: What is the scope of variables in JavaScript?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top