对使用 javascript setInterval 来执行动画作业感到困惑

Confuse about using javascript setInterval to do animate job

本文关键字:作业 动画 执行 javascript setInterval      更新时间:2023-09-26

我尝试使用setInterval在javascript中实现动画效果,我希望div的宽度增加200px(盒子的原点宽度为100px(1000ms

var MAX = 300, duration = 1000;
var inc = parseFloat( MAX / duration );
var div = $('div')[0];
var width = parseInt(div.style.width, 10);
function animate (id) {
    width += inc;
    if (width >= MAX) {
        clearInterval(id);
        console.timeEnd("animate");
    }
    div.style.width = width + "px";
}
console.time("animate");
var timer = setInterval(function () {
    animate(timer);
}, 0)

我用console.time来计算需要多少时间,但是,它总是需要 3 秒或更长时间,而不是 1 秒。

那么我的代码有什么问题呢?

演示在这里

但是当我使用 jquery Animate 时,它就像我指出的时间一样:

console.time("animate");
$('div').animate({
    width: '300px'
}, { 
    duration: 1000,
    complete: function () {
        console.timeEnd("animate");
    }
})

这是演示

那么为什么jquery可以实现它呢?秘诀是什么?

"秘诀"是计算每帧需要采取的步骤。

下面是一个更新的示例(进行了一些优化(:
http://jsfiddle.net/AbdiasSoftware/nVgTj/7/

//init some values
var div = $('div')[0].style;
var height = parseInt(div.height, 10);
var seconds = 1;
//calc distance we need to move per frame over a time
var max = 300;
var steps = (max- height) / seconds / 16.7;
//16.7ms is approx one frame (1000/60)
//loop
function animate (id) {
    height += steps; //use calculated steps
    div.height = height + "px";
    if (height < max) {
        requestAnimationFrame(animate);
    }
}
animate();

请注意,正如hh54188所指出的,requestAnimationFrame尚未在所有浏览器中都可用(Chrome和Firefox支持前缀(。

您可以使用此 polyfill,它允许您无论如何都使用调用,但如果requestAnimationFrame不可用,则会优雅地回退到setTimeout

http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

@Ken说的解决方案是可用的,但浏览器不支持requestAnimationFrame ,它可能无法工作;

我在代码中犯的错误是,我计算的增加每 1 毫秒增加一次,但计时器每 4 毫秒执行一次我的动画函数(根据最小延迟(。

所以对于一些保险,我们最好手动设置定时器延迟,比如13ms(jquery动画中的间隔(,增加应该是:

var inc = parseFloat( MAX / duration ) * 13;

使用 13 * perOneMillisecond 作为匹配13ms间隔的增加

这是演示,然后您可以检查时间成本几乎与jquery一样(但仍然慢一些,为什么?