Je suis novice en animation, mais j'ai récemment créé une animation en utilisant setTimeout
. Le FPS était trop bas, j'ai donc trouvé une solution pour utiliser requestAnimationFrame
, décrite dans ce 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 la fonction chopElement
.
Existe-t-il également un guide plus complet sur l'utilisation de cette API?
Attention! Cette question n'est pas sur la meilleure façon de shim requestAnimFrame
. Si vous recherchez cela, passez à toute autre réponse sur cette page.
Vous avez été trompé par l'insertion automatique de points-virgules. Essaye ça:
window.requestAnimFrame = function(){
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback){
window.setTimeout(callback, 1000 / 60);
}
);
}();
javascript place automatiquement un point-virgule derrière votre instruction return
. Il le fait car il est suivi d'une nouvelle ligne et la ligne suivante est une expression valide. En fait, il se traduit par:
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 return. Alors window.requestAnimFrame
est undefined
. Lorsque vous l'appelez dans animloop
, le javascript génère une erreur et arrête l'exécution. Vous pouvez résoudre le problème en mettant l'expression entre parenthèses.
Puis-je recommander le Chrome outils de développement ou firebug pour inspecter l'exécution javascript. Avec ces outils, vous auriez vu l'erreur. Vous devriez procéder au débogage comme suit (je suppose que Chrome):
TypeError non détecté: la propriété 'requestAnimFrame' de l'objet [objet DOMWindow] n'est pas une fonction
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 devez vous concentrer sur la première partie de votre code.Aussi, regardez cette vidéo pour quelques bonnes pratiques dans l'écriture de javascript, il mentionne également l'insertion automatique de points-virgules.
/*
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 œil à l'exemple jsfiddle ci-dessous; Cela illustre clairement ce que je veux dire;
http://jsfiddle.net/XQpzU/4358/light/
J'espère que cela t'aides!
"Limitation intelligente afin 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 ||
// polyfill - throttle fall-back for unsupported browsers
(function() {
var throttle = false,
FPS = 1000 / 60; // 60fps (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);
};
html, body{ height:300%; }
body::before{ content:'scroll here'; position:fixed; font:2em Arial; }