Confuse about using javascript setInterval to do animate job

给你一囗甜甜゛ 提交于 2019-12-12 01:06:45

问题


I try to use setInterval to achieve animate effect in javascript, I want a div's width increase 200px(the box's origin width is 100px) in 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)

and I use the console.time to calculate how much time it take, however, it always take 3 second and more, not 1 second.

So what's wrong with my code?

the Demo is here

but when I use jquery animate, it just as the same time as I pointed:

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

Here is the Demo

So why jquery could achieve it?What's the secret?


回答1:


The "secret" is to calculate the steps you need to take per frame.

Here is an updated example (with some optimizations):
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();

Note that as hh54188 points out, requestAnimationFrame is not available in all browsers yet (Chrome and Firefox supports it with prefixes).

You can use this polyfill which allow you to use the call no matter, but fall backs gracefully to setTimeout if requestAnimationFrame shouldn't be available.

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




回答2:


The solution @Ken said is an available one, but the browser don't support requestAnimationFrame, it could't work;

The mistake I made in my code is, what I calculate the increasement is increased per 1ms, but the timer execute my animate function per 4ms (according to the minimum delay).

So for some insurance,we better set the timer delay by hand, like 13ms (the interval in jquery animation), and the increasement should be:

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

use the 13 * perOneMillisecond as the increasement for matching the 13ms interval

Here is the Demo, then you can check time cost almost as the jquery(but still slower some, why?)



来源:https://stackoverflow.com/questions/17143007/confuse-about-using-javascript-setinterval-to-do-animate-job

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!