I have a simple function which is increasing the width of a div but its not doing it smoothly its kinda of “juddery”.
I’m using request animation frame to do this on Chrome.. and I decided not to round the numbers so I could get decimal width increments.. but I can’t get it to be smooth at all was wondering how I can improve on my method.
This is my function:
function test(data){
var start = parseInt(data.start);
var length = parseInt(data.length); //total length in minutes to complete
var dif = (new Date().getTime() / 1000) - start; //start holds seconds since epoch
var minutes = dif / 60; //convert seconds past into minutes past
var percentage = (minutes/length) * 100;
if(percentage > 100){ percentage = 100; }
if( percentage != 100 ){
document.getElementById('r').style.width = percentage+'%';
document.getElementById('rt').innerHTML = Math.round(percentage)+'%';
} else if (percentage == 100 ){
document.getElementById('r').style.width = percentage+'%';
document.getElementById('rt').innerHTML = 'COMPLETED';
}
}
My function is called like this:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback, element){
window.setTimeout(callback, 200 / 100);
};
})();
function Update(){
requestAnimFrame( Update );
test();
}
JSFIddle: http://jsfiddle.net/RmXr9/7/
Any suggestions on ways to improve the smoothness of div width incrementing ?
One of the biggest causes of ‘juddery’ animations for me has always been frame rate. If your frame rate is too slow, obviously the animation ‘judders’. But if it is too fast for the browser to handle, the browser gets confused, and you get a different kind of ‘juddery’.
I’d recommend a frame rate of between 13 and 30 milliseconds. JQuery is supposed to use 13ms, but I’ve found that that is sometimes still too fast. I generally start with 16ms, and experiment from there.
The key is to ensure that you time it so that one frame starts as or after the previous frame is finished. This will depend on the code you process. I notice that you call the next frame before you begin processing the current frame, so it may be possible that you’re still getting backed up. Perhaps try:
Your fallback function has a frame rate of
200 / 100, which is 2ms. It is extremely unlikely that your browser can complete the animation in 2ms, so it is likelyto get backed up.requestAnimationFrameuses a maximum frame rate of 16ms.UPDATE:
The problem you’re having, according to your jsfiddle, is that, while you’re calculating your percentage often, the changes to the percentage are very small, and they don’t translate into a change in the width of the div. This http://jsfiddle.net/RmXr9/13/ should demontrate the changes in the percentage, and show the corrsponding changes in actual width. So, although you do a calculation often (maybe 60 times a second), the actual visual change only happens once every 16 frames or so. So, your actual frame rate is only about 4 frames per second, which makes a ‘juddery’ animation. Your only options, I’m afraid, are to make the animation run faster (perhaps by decreasing your
lengthvariable), or to make the div much longer (or both).As an aside, I notice you don’t have a way to stop the animation at the end, and I’ve added that into the jsfiddle as well.