Search code examples
jqueryjquery-pluginstimercounter

jQuery counter to count up to a target number


I'm trying to find out if anyone knows about an already existing jQuery plugin that will count up to a target number at a specified speed.

For example, take a look at Google's number of MB of free storage on the Gmail homepage, under the heading that reads "Lots of space". It has a starting number in a <span> tag, and slowly counts upward every second.

I'm looking for something similar, but I'd like to be able to specify:

  • The start number
  • The end number
  • The amount of time it should take to get from start to end.
  • A custom callback function that can execute when a counter is finished.

Solution

  • I ended up creating my own plugin. Here it is in case this helps anyone:

    (function($) {
        $.fn.countTo = function(options) {
            // merge the default plugin settings with the custom options
            options = $.extend({}, $.fn.countTo.defaults, options || {});
            
            // how many times to update the value, and how much to increment the value on each update
            var loops = Math.ceil(options.speed / options.refreshInterval),
                increment = (options.to - options.from) / loops;
            
            return $(this).each(function() {
                var _this = this,
                    loopCount = 0,
                    value = options.from,
                    interval = setInterval(updateTimer, options.refreshInterval);
                
                function updateTimer() {
                    value += increment;
                    loopCount++;
                    $(_this).html(value.toFixed(options.decimals));
                    
                    if (typeof(options.onUpdate) == 'function') {
                        options.onUpdate.call(_this, value);
                    }
                    
                    if (loopCount >= loops) {
                        clearInterval(interval);
                        value = options.to;
                        
                        if (typeof(options.onComplete) == 'function') {
                            options.onComplete.call(_this, value);
                        }
                    }
                }
            });
        };
        
        $.fn.countTo.defaults = {
            from: 0,  // the number the element should start at
            to: 100,  // the number the element should end at
            speed: 1000,  // how long it should take to count between the target numbers
            refreshInterval: 100,  // how often the element should be updated
            decimals: 0,  // the number of decimal places to show
            onUpdate: null,  // callback method for every time the element is updated,
            onComplete: null,  // callback method for when the element finishes updating
        };
    })(jQuery);
    

    Here's some sample code of how to use it:

    <script type="text/javascript"><!--
        jQuery(function($) {
            $('.timer').countTo({
                from: 50,
                to: 2500,
                speed: 1000,
                refreshInterval: 50,
                onComplete: function(value) {
                    console.debug(this);
                }
            });
        });
    //--></script>
    
    <span class="timer"></span>
    

    View the demo on JSFiddle: http://jsfiddle.net/YWn9t/