2010-04-19 4 views
0

J'essaie actuellement d'écrire ma propre bibliothèque JavaScript. Je suis en train d'écrire un rappel d'animation, mais j'ai des problèmes pour obtenir des valeurs finales précises, en particulier lorsque les durées d'animation sont plus courtes.JavaScript: Atteindre des valeurs finales d'animation précises?

En ce moment, je ne cible que l'animation positionnelle (gauche, haut, droite, bas). Quand mes animations sont terminées, elles ont une marge d'erreur de 5px ~ sur les animations plus rapides, et de 0.5px ~ sur les animations de 1000+ ms ou plus. Voici la majeure partie du rappel, avec des notes suivantes.

var current = parseFloat(this[0].style[prop] || 0) 
    // If our target value is greater than the current 
    , gt = !!(value > current) 
    , delta = (Math.abs(current - value)/(duration/13)) * (gt ? 1 : -1) 
    , elem = this[0] 
    , anim = setInterval(function(){ 
     elem.style[prop] = (current + delta) + 'px'; 
     current = parseFloat(elem.style[prop]); 
     if (gt && current >= value || !gt && current <= value) clearInterval(anim); 
    }, 13); 

this[0] et elem à la fois la référence de l'élément de DOM cible.

prop fait référence à la propriété pour animer, left, top, bottom, right, etc.

current est la valeur actuelle de la propriété de l'élément DOM.

value est la valeur souhaitée pour l'animation.

duration est la durée spécifiée (en ms) que l'animation doit durer.

13 est le délai setInterval (qui devrait être à peu près le minimum absolu pour tous les navigateurs).

gt est un var qui est true si value dépasse la initialecurrent, sinon il est false.

Comment puis-je résoudre la marge d'erreur?

Répondre

1

Vous pouvez rencontrer des erreurs d'arrondi qui finiront par atteindre une valeur différente de celle attendue. Vous pouvez jeter un oeil à une bibliothèque d'animation très simple et voir la méthode qu'ils utilisent pour surmonter cela (ainsi que certaines techniques d'assouplissement). Voici Emile Thomas Fuchs, qui est d'environ 50 lignes de code:

http://github.com/madrobby/emile/blob/master/emile.js

1

En plus de ce que dit Alex, vous êtes habituellement mieux d'utiliser le calcul en fonction du temps plutôt que d'essayer de faire des étapes discrètes. Cela garantit la précision et permet à l'animation de fonctionner à une vitesse raisonnable lorsque le navigateur n'est pas assez rapide pour vous rappeler de manière fiable toutes les n microsecondes.

function animate(element, prop, period, value) { 
    var v0= parseFloat(element.style[prop] || 0); // assume pre-set in px 
    var dv= value-v0; 
    var t0= new Date().getTime(); 
    var anim= setInterval(function() { 
     var dt= (new Date().getTime()-t0)/period; 
     if (dt>=1) { 
      dt= 1; 
      clearInterval(anim); 
     } 
     element.style[prop]= v0+dv*dt+'px'; 
    }, 16); 
} 
Questions connexes