Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why jquery can't animate number accurately?

i am trying to use the following code to increment number in a textbox

    // Animate the element's value from 0 to 1100000:
$({someValue: 0}).animate({someValue: 1100000}, {
    duration: 1000,
    step: function() { // called on every step
        // Update the element's text with value:
        $('#counterx').text(Math.floor(this.someValue+1));
    }
});

it is working with small numbers like from 0 to 100 but when it comes to large number like in the mentioned code, it is not giving the target number, it is animating to numbers like 1099933 or 1099610 or ..... and every time it changes.

so how can i make it to animate to the number i specify?

like image 633
medo ampir Avatar asked May 25 '12 17:05

medo ampir


3 Answers

I have the same issue. The reasoning is because animate function uses a mathematical formula that is time based. You don't really notice this when animating something css based because close enough in pixels is good enough. It will get close to the final value but may not always be exactly the end value. Solution is to use the complete event to set that last value.

Here is what you need to do:

function animateNumber(ele,no,stepTime){
$({someValue: 0}).animate({someValue: no}, {
        duration: stepTime,
        step: function() { // called on every step. Update the element's text with value:
            ele.text(Math.floor(this.someValue+1));
        },
        complete : function(){
            ele.text(no);
        }
});
}

animateNumber($('#counterx'),100,10000);
animateNumber($('#countery'),100,1000)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
counterx(slow): <span id=counterx>--</span>
<br/>
countery(fast): <span id=countery>--</span>
like image 101
Amir Raminfar Avatar answered Sep 20 '22 13:09

Amir Raminfar


1) Javascript is a single threaded application. Timeouts and animations ONLY push the event to the end of the stack based on an ideal stacking order. A long running section of script can cause the actual firing time of that event well past the accuracy you are looking for.

2) Animation approximates how much to increment, and on larger numbers that resolution is very inaccurate.

3) jQuery only has one animation buffer. You might run into some serious rendering issues if you invoke more than one "counter" using animation. Make sure to stop the previous animation before making any adjustments that effect it.

4) Even with a timeout of 0, you can expect the real world delay of ~15. Even if that is the only "thread" you have running.

Solution:

take a snapshot of the DTG
set your interval to something within the human experience, say ~200
on each interval, check how much time has passed from the original DTG
set your text field to that delta number.
stop the interval with the original DTG + "your target number" > the new DTG
like image 23
C.S. Avatar answered Sep 18 '22 13:09

C.S.


Animate is not designed to increment a counter as text (though it may work by accident, which could change with any new version of jQuery), it's designed to animate one or more CSS properties. You should be using setInterval instead.

http://jsfiddle.net/jbabey/mKa5r/

var num = 0;

var interval = setInterval(function () {
    document.getElementById('result').innerHTML = num;
    num++;

    if (num === 100) {
        clearInterval(interval);            
    }
}, 100);​
like image 22
jbabey Avatar answered Sep 19 '22 13:09

jbabey