使用javascript setInterval函数来实现动画效果:比我预期的要慢

Using javascript setInterval function to achieve animate effect:slower than I expected

本文关键字:函数 setInterval javascript 实现 动画 使用      更新时间:2023-09-26

我想使用 javascript setInterval函数来实现盒子旋转动画效果,我希望动画保持 1.5 秒,在 1.5 秒内盒子会旋转 360 度,所以我计算一毫秒的增量,并使用 setInterval 函数每毫秒。这是我的代码:

var duration= 1500;//The animation duration time
var rotate = 360;//The rotate need to be rotate
var degPerSec = rotate / parseFloat(duration); //the increment per millisecond
var degree = 0;//the begin degree
console.time('rotate');
var timer = setInterval(function () {
    degree = degree + degPerSec;
    $('#test')[0].style.MozTransform = 'rotate(' + degree + 'deg)';
     $('#test')[0].style.WebkitTransform = 'rotate(' + degree + 'deg)';
    if (degree >= rotate) { //if reach 360 degree , clear the interval
        clearInterval(timer);
        console.timeEnd('rotate');// caculate the duration 
    }
    }, 1)
})

动画可以成功执行,但似乎它不仅持续 1.5 秒,当我使用 console.time 计算整个持续时间时,它持续大约 6 秒!不是 1.5 秒。为什么会这样?如何解决这个问题?

这是演示

更新::为什么我不使用 css3:cuz 旋转度是一个参数,它需要在外面传递形式,尚未定义

当您可以使用简单的样式表时,为什么要使用 Jquery 呢? 您已经在使用 Mozilla 和 Webkit 特定的分支代码。 不妨用 CSS3 做这件事,然后用它完成。 更快(使用本机 C 代码而不是 JS)和更简单。

#test{
    width:30px;
    height:30px;
    background:red;
    position:absolute;
    left:20px;
    top:20px;
    -webkit-transition: all 1.5s ease;
    -moz-transition: all 1.5s ease;
    -o-transition: all 1.5s ease;
    transition: all 1.5s ease;
}

编辑:如果您需要使用可变参数作为旋转度数,这仍然非常可行,使用 JS:

var degrees = 360;
var incrementer = 1;
setInterval(function() {
  var deg = "rotate(" + (degrees * incrementer) + "deg)";
  var obj = document.getElementById("test");
  if (typeof(obj.style.transform) !== "undefined") {
    obj.style.transform = deg;
  } else if (typeof(obj.style.MozTransform) !== "undefined") {
    obj.style.MozTransform= deg;
  } else if (typeof(obj.style.WebkitTransform) !== "undefined") {
   obj.style.WebkitTransform = deg;
  }
  incrementer = incrementer + 1;
}, 1500);

这是因为您更改了 DOM,然后发生重排并且重排会更新整个视图(需要一段时间)。 要解决此问题,请降低更新频率或使用CSS3动画/过渡。

1 毫秒的间隔在某些操作系统(例如 Windows)上没有意义,因为调度程序的时间片在那里大约是 10 毫秒。此外,您的函数总共可能需要 1 毫秒以上。这两个人同意你的减速。

为了安全起见,您可以测量函数调用之间的实际延迟。

这样做有什么原因吗? 为什么不直接使用 transition 来定义转换的持续时间?

...
-webkit-transform: rotate(360deg);  
-webkit-transition:-webkit-transform 1s ease-in-out;  
...

以上所有关于 css 使用的评论当然都是正确的。还值得注意的是,每毫秒运行这么多代码是过分的 - 你只需要~30帧/秒就可以让动画在人眼中流畅地显示,而这里你运行了1000帧/秒。如果将帧间隔得更多一点,每 ~33 毫秒运行一次动画,则动画将运行得更快,看起来更平滑。

最后,有一个工具可以确定最佳帧速率并为我们执行内置于浏览器中的运行循环,称为requestAnimationFrame。您可以向它传递回调,它将确定最有效的帧速率(如果可能,通常为 60),并以最有效的方式运行动画,从而最大限度地减少与重绘相关的开销。

对于此示例,只需将setInterval替换为requestAnimationFrame并对旋转值进行一些细微调整即可。