简体   繁体   中英

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

I want use javascript setInterval function to achieve a box rotate animate effect, I want the animation keep 1.5 second, in 1.5s the box would rotate 360 degree, so I calculate the increment in one millisecond , and use setInterval function per millisecond.Here is my code:

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)
})

The animation could execute successfully,but it seems it last not only 1.5s, when I use console.time to calculate the whole duration ,it last about 6s!Not 1.5s.Why this happened?How can I solve this problem?

Here is the demo

update: : Why I don't use css3:cuz the rotate degree is as a parameter,which needed pass form outside, not defined already

its because you change the dom, then re-flow occurs and re-flow updates the entire view (takes a while). to get around this either update less frequently or use css3 animations/transitions.

1 ms interval does not make sense on certain OSes (eg Windows), as the scheduler time slice is around 10 ms there. Moreover, your function can take more than 1 ms in total. These two agree with your slowdown.

To be on the safe side, you can measure the real delay between function invocations.

Is there a reason you are doing it this way? Why not just use transition to define the duration of the transform?

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

Why on earth are you using Jquery for this when you could use a simple stylesheet? You're already using Mozilla- & Webkit-specific branching code. Might as well just do it with CSS3 and be done with it. Much faster (uses native C code rather than JS) and much simpler.

#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;
}

EDIT: If you need to use a variable parameter for the degrees of rotation, this is still very do-able using 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);

All the above comments regarding css use are certainly true. It's also worth noting that running that much code every milisecond is way overboard - you only need ~30 frames/sec to have the animation appear smoothly to human eyes, and here you are running through 1000 frames/sec. If space out the frames a bit more and run the animation every ~33 ms, the animation will go quicker and appear much smoother.

Finally, there is a tool for determining the best frame rate and executing a run loop for us built in to browsers called requestAnimationFrame . You can pass this a callback and it will determine the most efficient frame rate (usually 60 if possible) and run the animation in the most efficient way possible, minimizing overhead associated with the repaint.

For this example, it would be as easy as replacing setInterval with requestAnimationFrame and making some slight adjustments to your rotation values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM