requestAnimationFrame not working in Safari/Opera. Tearing my hair out

html, javascript, opera, requestanimationframe, safari

Solution

Some versions of Safari don't have support for the `window.requestAnimationFrame` function.

To fix it: Throw in this shim to define `window.requestAnimationFrame` before you make the call to it.

// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel

// MIT license

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

Problem

I have a problem to which I have no answer for and needing an extra pair of eyes to shed some light on the situation, so here it goes: In Chrome and FF, my little animation works fine (4 circles are being drawn at the same time when a user hovers over the div they reside in). BUT...as far as Safari and Opera are concerned, they just don't want to show my animation. I've been on the Error Console and the message i'm getting is: Type Error: 'undefined is not a function (evaluating 'requestAnimationFrame (function { animate(curPerc/100) })') And i'm not sure what is happening here but I think that the 'animate' function is looping round, only working on a 'hover' function and when it finishes its first loop, the function is looking for another input, doesn't receive one, which then results in an 'undefined' error?? I could be way out on this though! Plus..this doesn't explain why it would work in Chrome and FF and not Safari or Opera Here is the code for one of the circles animation to give you an idea: HTML: ``` <canvas id="myCanvasVD" width="200" height="200"></canvas> ``` Javascript: ``` (function() { var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; window.requestAnimationFrame = requestAnimationFrame; })(); $(document).ready(function() { $("#aboutPageDiv").hover(function() { var myCanvas = document.getElementById('myCanvasVD'); var ctx = myCanvas.getContext("2d"); var x = myCanvas.width / 2; var y = myCanvas.height / 2; var radius = 75; var endPercentVD = 87; var curPerc = 0; var counterClockwise = false; var circ = Math.PI * 2; var quart = Math.PI / 2; ctx.lineWidth = 32; ctx.strokeStyle = '#34c3e5'; ctx.lineCap = "round"; function animate(current) { ctx.clearRect(0, 0, ctx.width, ctx.height); ctx.beginPath(); ctx.arc(x, y, radius, -(quart), ((circ) * current) - quart, false); ctx.stroke(); curPerc++; if (curPerc < endPercentVD) { requestAnimationFrame(function () { animate(curPerc / 100) }); } } animate(); } ); }); ``` If anyone knows a solution to get this to work on Safari and Opera, It'd really appreciated and a Christmas card would be coming to you in the post... Oh and yes, I do have the latest version of Safari and Opera! Thanks very much, Tim

Original source