52 votes

Comment utiliser requestAnimationFrame ?

Je suis novice en matière d'animation, mais j'ai récemment créé une animation à l'aide de setTimeout . Le FPS était trop faible, j'ai donc trouvé une solution pour utiliser requestAnimationFrame décrite dans le présent document. lien .

Jusqu'à présent, mon code est :

//shim layer with setTimeout fallback
    window.requestAnimFrame = (function(){
        return  
            window.requestAnimationFrame       || 
            window.webkitRequestAnimationFrame || 
            window.mozRequestAnimationFrame    || 
            window.oRequestAnimationFrame      || 
            window.msRequestAnimationFrame     || 
            function(/* function */ callback){
                window.setTimeout(callback, 1000 / 60);
            };
    })();
    (function animloop(){
        //Get metrics
        var leftCurveEndX = finalLeft - initialLeft;
        var leftCurveEndY = finalTop + finalHeight - initialTop;
        var rightCurveEndX = finalLeft + finalWidth - initialLeft - initialWidth;
        var rightCurveEndY = leftCurveEndY;

        chopElement(0, 0, 0, 0, leftCurveEndX, leftCurveEndY, rightCurveEndX, rightCurveEndY);//Creates a new frame 
        requestAnimFrame(animloop);
    })();

Cela s'arrête pendant la première image. J'ai une fonction de rappel requestAnimFrame(animloop); dans le chopElement fonction.

Par ailleurs, existe-t-il un guide plus complet sur l'utilisation de cette API ?

83voto

Jan Points 4766

Attention ! Cette question ne porte pas sur la meilleure façon de caler requestAnimFrame . Si c'est ce que vous cherchez, passez à une autre réponse de cette page.


Vous vous êtes fait avoir par l'insertion automatique de points-virgules. Essayez ceci :

window.requestAnimFrame = function(){
    return (
        window.requestAnimationFrame       || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     || 
        function(/* function */ callback){
            window.setTimeout(callback, 1000 / 60);
        }
    );
}();

javascript met automatiquement un point-virgule derrière votre return déclaration. Elle le fait parce qu'elle est suivie d'un saut de ligne et que la ligne suivante est une expression valide. En fait, elle est traduite en :

return;
window.requestAnimationFrame       || 
window.webkitRequestAnimationFrame || 
window.mozRequestAnimationFrame    || 
window.oRequestAnimationFrame      || 
window.msRequestAnimationFrame     || 
function(/* function */ callback){
    window.setTimeout(callback, 1000 / 60);
};

Ce code renvoie undefined et n'exécute jamais le code derrière l'instruction de retour. Donc window.requestAnimFrame est undefined . Lorsque vous l'appelez en animloop le javascript produit une erreur et arrête l'exécution. Vous pouvez résoudre le problème en mettant l'expression entre parenthèses.

Je vous recommande les outils de développement de Chrome ou firebug pour inspecter l'exécution du javascript. Avec ces outils, vous auriez vu l'erreur. Vous devriez procéder au débogage de la manière suivante (en supposant Chrome) :

  1. Exécuter le code (il produit des résultats inattendus)

  2. Ouvrez les outils de développement (clic droit -> Inspecter l'élément). Vous verrez un x rouge dans la barre d'état à droite (cela signifie qu'il y a une erreur dans l'exécution).

  3. Ouvrez l'onglet console

  4. Vous verrez

    Erreur de type non détectée : La propriété 'requestAnimFrame' de l'objet [object DOMWindow] n'est pas une fonction.

  5. Tapez dans la console : window.requestAnimFrame et appuyez sur entrée, vous verrez que c'est undefined . Vous savez maintenant que le problème n'est en fait pas lié à requestAnimationFrame et que vous devriez vous concentrer sur la première partie de votre code.

  6. Il s'agit maintenant de réduire le code jusqu'au point où il renvoie quelque chose. C'est la partie la plus difficile et si vous ne trouvez toujours pas de réponse à ce stade, vous pouvez vous tourner vers Internet pour obtenir plus d'aide.

Aussi, regardez cette vidéo pour quelques bonnes pratiques dans l'écriture de javascript, Il mentionne également le mal de l'insertion automatique des points-virgules.

8voto

Gokhan Tank Points 2365
 /*
  Provides requestAnimationFrame in a cross browser way.
  http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 */

if (!window.requestAnimationFrame) {

    window.requestAnimationFrame = (function() {

        return window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame || // comment out if FF4 is slow (it caps framerate at ~30fps: https://bugzilla.mozilla.org/show_bug.cgi?id=630127)
        window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {

                window.setTimeout(callback, 1000 / 60);

        };

    })();

}

animate();

function animate() {
    requestAnimationFrame(animate);
    draw();
}

function draw() {
    // Put your code here
}

Jetez un coup d'œil à l'exemple jsfiddle ci-dessous ; il illustre clairement ce que je veux dire ;

http://jsfiddle.net/XQpzU/4358/light/

J'espère que cela vous aidera !

0voto

vsync Points 11280

Utilisation d'une régulation intelligente pour que l'événement ne soit pas déclenché plus de fois que l'écran ne peut repeindre le changement :

var requestFrame =  window.requestAnimationFrame || 
                    window.webkitRequestAnimationFrame || 
                    // throttle fall-back for unsupported browsers
                    (function(){ 
                        var throttle = false,
                            FPS = 60 / 1000; // time in ms           
                        return function(CB) {
                            if( throttle ) return;
                            throttle = true;
                            setTimeout(function(){ throttle = false; }, FPS);
                            CB(); // do your thing
                        }
                    })();

// use case:
function doSomething(){
    console.log('fired');
}

window.onscroll = function(){ requestFrame(doSomething); };

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X