JavaScript的动画持续时间不正确 [英] JavaScript Duration of animation isn't exact

查看:139
本文介绍了JavaScript的动画持续时间不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我想提两件事,

一个:我的代码并不完美(尤其是评估部分)-但我想尝试自己的东西,看看我是否可以复制jQuery Animation函数,所以请原谅我的不良做法,也请不要建议我使用jQuery,我想尝试一下。

二:该代码尚未完成,我只是想找出是什么原因使其无法正常工作。

First of all I want to mention two things,
One: My code isn't perfect (esspechially the eval parts) - but I wanted to try something for my self, and see if I could duplicate the jQuery Animation function, so please forgive my "bad" practices, and please don't suggest that I'll use jQuery, I wanted to experiment.
Two: This code isn't done yet, and I just wanted to figure out what makes it work badly.

所以动画运行了大约12秒钟,而我输入的持续时间参数是15秒钟,我在做什么错了?

So the animation runs for about 12 seconds while the duration parameter I entered was 15 seconds, What am I doing wrong?

function animate(elem, attr, duration){
  if(attr.constructor === Object){//check for object literal
    var i = 0;
    var cssProp = [];
    var cssValue = [];
    for(key in attr) {
          cssProp[i] =  key;
          cssValue[i] = attr[key];
    }
    var fps = (1000 / 60);
    var t = setInterval(function(){
      for(var j=0;j<cssProp.length;j++){
        if(document.getElementById(elem).style[cssProp[j]].length == 0){
          //asign basic value in css if the object dosn't have one.
         document.getElementById(elem).style[cssProp[j]]= 0;
        }
        var c = document.getElementById(elem).style[cssProp[j]];
        //console.log(str +" | "+c+"|"+cssValue[j]);
        if(c > cssValue[j]){
            document.getElementById(elem).style[cssProp[j]] -= 1/((duration/fps)*(c-cssValue[j]));
        }else if(c < cssValue[j]){
            document.getElementById(elem).style[cssProp[j]] += 1/((duration/fps)*(c-cssValue[j]));
        }else if(c == cssValue[j]){
            window.clearInterval(t);
        }
      }
    },fps);
  }
}
  animate('hello',{opacity:0},15000);

html:

  <p id="hello" style="opacity:1;">Hello World</p>

注意:我想


(持续时间/ fps)*(c-cssValue [j])

(duration/fps)*(c-cssValue[j])

setInterval的部分或/和间隔(fps变量)。



Part or/and the interval of the setInterval (fps variable).


预先感谢

推荐答案

我不会尝试对其进行重构并弄清楚,因为它很虚幻。就是说...几件事。

I'm not gonna try and refactor that and figure it out, cause it's pretty wonky. That said... a few things.

不要依靠您设置的动画值来了解动画的进度

通常,您的方法不正确。您最好自己跟踪进度。另外,由于采用这种方法,您的数学似乎太费劲了,应该会更简单。

In general your approach is unsound. You are better off keeping track of progress yourself. Also, as a result of your approach your math seems like it's trying too hard, and should be much simpler.

这样想:动画是在时间已经过去,而不是在动画值似乎表明它处于最终位置时。

Think of it like this: your animation is complete when the time has elapsed, not when the animated value seems to indicate that it's at the final position.

不要递增,设置

浮点数学是不精确的,像这样的重复加法累加也会累积浮点错误。而且,使一些变量来跟踪您的进度更容易阅读,您可以在计算中使用它们。

Floating point math is inexact, and repeated addition cumulation like this is going accumulate floating point errors as well. And it's far more readable to make some variables to keep track of progress for you, which you can use in calculations.

animatedValue += changeOnThisFrame // BAD!
animatedValue = valueOnThisFrame   // GOOD!

不要做正/负条件舞蹈

结果是 10 + 10 10-(-10)确实是同一回事。这意味着您可以始终添加值,但变化率可以是负值或正值,并且值将沿适当的方向进行动画处理。

It turns out that 10 + 10 and 10 - (-10) is really the same thing. Which means you can always add the values, but the rate of change can be negative or positive, and the value will animate in the appropriate direction.

超时和间隔不精确

结果 setTimeout(fn,50)实际上意味着安排fn至少在50毫秒后致电。在这50毫秒后执行的下一个JS运行循环将运行该函数,因此您不能依靠它来达到完美的准确性。

Turns out setTimeout(fn, 50) actually means to schedule the fn to be call at least 50ms later. The next JS run loop to execute after those 50ms will run the function, so you can't rely on it to be perfectly accurate.

那通常是在几步之内毫秒。但是60fps的帧约为16ms,实际上该计时器可能会在16-22ms的可变时间内触发。因此,当您基于帧速率进行计算时,它根本与实际经过的时间完全不匹配。

That said it's usually within a few milliseconds. But 60fps is about 16ms for frame, and that timer may actually fire in a variable amount of time from 16-22ms. So when you do calculations based on frame rate, it's not matching the actual time elapsed closely at all.

重构复杂的数学

在这里解构此行会很困难。

Deconstructing this line here is gonna be hard.

document.getElementById(elem).style[cssProp[j]] -= 1/((duration/fps)*(c-cssValue[j]));

为什么要更复杂地分解它,以便您可以轻松了解此处的情况。仅重构此行,我可以这样做:

Why for more complex break it up so you can easily understand what's going on here. refactoring this line alone, I might do this:

var style = document.getElementById(elem).style;
var changeThisFrame = duration/fps;
var someOddCalculatedValue = c-cssValue[j];
style[cssProp[j]] -= 1 / (changeThisFrame * someOddCalculatedValue);

这样做可以更清楚数学中每个表达式的含义和用途。而且由于您在这里没有这样做,我很难理解为什么 c-cssValue [j] 在那里以及它代表什么。

Doing this makes it clearer what each expression in your math means and what it's for. And because you didn't do it here, I had a very hard time wondering why c-cssValue[j] was in there and what it represents.

简单示例

此功能不如您所拥有,但它显示了您应该使用的方法正在服用。它使用动画的开始时间来创造完美的价值,具体取决于动画的完成程度,动画的开始位置和进行的方向。它不会使用当前的动画值来确定任何内容,并保证可以运行动画的整个长度。

This is less capable than what you have, but it shows the approach you should be taking. It uses the animation start time to create the perfect value, depending on how complete the animation should be, where it started, and where it's going. It doesn't use the current animated value to determine anything, and is guaranteed to run the full length of the animation.

var anim = function(elem, duration) {

    // save when we started for calculating progress
    var startedAt = Date.now();

    // set animation bounds
    var startValue = 10;
    var endValue   = 200;

    // figure out how much change we have over the whole animation
    var delta = endValue - startValue;

    // Animation function, to run at 60 fps.
    var t = setInterval(function(){

        // How far are we into the animation, on a scale of 0 to 1.
        var progress = (Date.now() - startedAt) / duration;

        // If we passed 1, the animation is over so clean up.
        if (progress > 1) {
            alert('DONE! Elapsed: ' + (Date.now() - startedAt) + 'ms');
            clearInterval(t);
        }

        // Set the real value.
        elem.style.top = startValue + (progress * delta) + "px";

    }, 1000 / 60);
};

anim(document.getElementById('foo'), 5000);
​

JSFiddle: http://jsfiddle.net/DSRst/

JSFiddle: http://jsfiddle.net/DSRst/

这篇关于JavaScript的动画持续时间不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆