Canvas rotate circle in certain speed using RequestAnimationFrame

JohnPeterson picture JohnPeterson · Dec 7, 2013 · Viewed 7.6k times · Source

I made a quick simple solution in JSFiddle, for better and faster explaining:

var Canvas = document.getElementById("canvas");
var ctx = Canvas.getContext("2d");

var startAngle = (2*Math.PI);
var endAngle = (Math.PI*1.5);
var currentAngle = 0;

var raf = window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame;

function Update(){
    //Clears
    ctx.clearRect(0,0,Canvas.width,Canvas.height);

    //Drawing
    ctx.beginPath();                  
    ctx.arc(40, 40, 30, startAngle + currentAngle, endAngle + currentAngle, false);

    ctx.strokeStyle = "orange";
    ctx.lineWidth = 11.0;
    ctx.stroke();

    currentAngle += 0.02;
    document.getElementById("angle").innerHTML=currentAngle;
    raf(Update);
}
raf(Update);

http://jsfiddle.net/YoungDeveloper/YVEhE/3/

As the browser chooses the fps, how would I rotate the ring independently from frame speed. Because for now, if speed is 30fps it will rotate slower, but if 60fps faster, because its rotate amount is added for each call.

As i understand from couple of thread it has something to do with getTime, i really tried but could not get it done, i would need to rotate it once in 10 seconds.

The other thing is, angle, it will increase more and more, and after long long time it will crash because variable max amount will be exceeded, so how do i make seamless rotate cap ?

Thank you for reading!

Answer

markE picture markE · Dec 7, 2013

Some math will let you draw your shape at a specified speed inside an animation loop.

Demo: http://jsfiddle.net/m1erickson/9Z8pG/

Declare a startTime.

    var startTime=Date.now();

Declare the time-length of a 360 degree rotation (10seconds == 10000ms)

    var cycleTime=1000*10;  // 1000ms X 10 seconds

Inside each animation frame...

Use modulus math to divide the current time into 10000ms cycles.

        var elapsed=Date.now()-startTime;
        var elapsedCycle=elapsed%cycleTime;

In each animation frame, calculate the percent that the current time is through the current cycle.

        var elapsedCyclePercent=elapsedCycle/cycleTime;

The current rotation angle is a full circle (Math.PI*2) X the percentage.

        var radianRotation=Math.PI*2 * elapsedCyclePercent;

Redraw your object at the frame’s current rotation angle:

        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.beginPath();                  
        ctx.arc(40, 40, 30, -Math.PI/2, -Math.PI/2+radianRotation, false);
        ctx.strokeStyle = "orange";
        ctx.lineWidth = 11.0;
        ctx.stroke();