[jquery] 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.

This question is related to jquery jquery-plugins timer counter

The answer is


I've created the tiniest code to do exactly that. It's not only for counting but for any task that needs to run in a given time. (let's say, do something for 5 seconds):

Demo:

var step = function(t, elapsed){
    // easing 
    t = t*t*t;

    // calculate new value
    var value = 300 * t; // will count from 0 to 300

    // limit value ("t" might be higher than "1")
    if( t > 0.999 )
        value = 300;

    // print value (converts it to an integer)
    someElement.innerHTML = value|0;
};

var done = function(){
    console.log('done counting!');
};


// Do-in settings object
var settings = {
    step     : step,
    duration : 3,
    done     : done,
    fps      : 24 // optional. Default is requestAnimationFrame
};

// initialize "Do-in" instance 
var doin = new Doin(settings);

A different approach. Use Tween.js for the counter. It allows the counter to slow down, speed up, bounce, and a slew of other goodies, as the counter gets to where its going.

http://jsbin.com/ekohep/2/edit#javascript,html,live

Enjoy :)

PS, doesn't use jQuery - but obviously could.


You can use jquery animate function for that.

$({ countNum: $('.code').html() }).animate({ countNum: 4000 }, {
        duration: 8000,
        easing: 'linear',
        step: function () {
        $('.code').html(Math.floor(this.countNum) );
        },
        complete: function () {
        $('.code').html(this.countNum);
        //alert('finished');
        }
    });

Here's the original article


Another way to do this without jQuery would be to use Greensock's TweenLite JS library.

Demo http://codepen.io/anon/pen/yNWwEJ

var display = document.getElementById("display");
var number = {param:0};
var duration = 1;

function count() {
  TweenLite.to(number, duration, {param:"+=20", roundProps:"param",
  onUpdate:update, onComplete:complete, ease:Linear.easeNone});
}

function update() {
  display.innerHTML = number.param;
}

function complete() {
  //alert("Complete");
}

count();

You can use the jQuery animate function

// Enter num from and to
$({countNum: 99}).animate({countNum: 1000}, {
  duration: 8000,
  easing:'linear',
  step: function() {
    // What todo on every count
    console.log(Math.floor(this.countNum));
  },
  complete: function() {
    console.log('finished');
  }
});

http://jsbin.com/upazas/958/


Needed a break, so I cobbled the following together. Not sure it would be worth creating a plugin from though.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>
            Counter
        </title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
        <script type="text/javascript">
            //<![CDATA[
                function createCounter(elementId,start,end,totalTime,callback)
                {
                    var jTarget=jQuery("#"+elementId);
                    var interval=totalTime/(end-start);
                    var intervalId;
                    var current=start;
                    var f=function(){
                        jTarget.text(current);
                        if(current==end)
                        {
                            clearInterval(intervalId);
                            if(callback)
                            {
                                callback();
                            }
                        }
                        ++current;
                    }
                    intervalId=setInterval(f,interval);
                    f();
                }
                jQuery(document).ready(function(){
                    createCounter("counterTarget",0,20,5000,function(){
                        alert("finished")
                    })
                })
            //]]>
        </script>
    </head>
    <body>
        <div id="counterTarget"></div>
    </body>
</html>

Don't know about plugins but this shouldn't be too hard:

;(function($) {        
     $.fn.counter = function(options) {
        // Set default values
        var defaults = {
            start: 0,
            end: 10,
            time: 10,
            step: 1000,
            callback: function() { }
        }
        var options = $.extend(defaults, options);            
        // The actual function that does the counting
        var counterFunc = function(el, increment, end, step) {
            var value = parseInt(el.html(), 10) + increment;
            if(value >= end) {
                el.html(Math.round(end));
                options.callback();
            } else {
                el.html(Math.round(value));
                setTimeout(counterFunc, step, el, increment, end, step);
            }
        }            
        // Set initial value
        $(this).html(Math.round(options.start));
        // Calculate the increment on each step
        var increment = (options.end - options.start) / ((1000 / options.step) * options.time);            
        // Call the counter function in a closure to avoid conflicts
        (function(e, i, o, s) {
            setTimeout(counterFunc, s, e, i, o, s);
        })($(this), increment, options.end, options.step);
    }
})(jQuery);

Usage:

$('#foo').counter({
    start: 1000,
    end: 4500,
    time: 8,
    step: 500,
    callback: function() {
        alert("I'm done!");
    }
});

Example:

http://www.ulmanen.fi/stuff/counter.php

I guess the usage is self-explanatory; in this example, the counter will start from 1000 and count up to 4500 in 8 seconds in 500ms intervals, and will call the callback function when the counting is done.


CodePen Working Example

For more GitHub repo

<!DOCTYPE html>
<html>
<head>
    <title>Count Up Numbers Example</title>
    <script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>

    <style type="text/css">
        /* 
        Courtesy: abcc.com
        https://abcc.com/en
        https://abcc.com/en/at-mining 
        */
        .rewards {
            background-color: #160922;
        }

        .th-num-bold {
            font-family: "Arial" ;
        }

        .ff-arial {
            font-family: "Arial" ;
        }

        .scroll-wrap .scroll-exchange-fee .exchange_time {
            color: hsla(0,0%,100%,.7);
            font-size: 13px;
        }

        .f14 {
            font-size: 14px;
        }

        .flex {
            display: -webkit-box;
            display: -ms-flexbox;
            display: flex;
        }

        .jcsb {
            -ms-flex-pack: justify!important;
            -webkit-box-pack: justify!important;
            justify-content: space-between!important;
        }

        .aic {
            -ms-flex-align: center!important;
            -webkit-box-align: center!important;
            align-items: center!important;
        }


        li {
            list-style: none;
        }

        .pull-left {
            float: left!important;
        }

        .rewards-wrap {
            height: 100%;
        }

        .at-equity-wrap .rewards .calculate_container {
            -webkit-box-shadow: rgba(0,0,0,.03) 0 5px 10px 0;
            background: url(https://s.abcc.com/portal/static/img/home-bg-pc.c9207cd.png);
            background-repeat: no-repeat;
            background-size: 1440px 100%;
            box-shadow: 0 5px 10px 0 rgba(0,0,0,.03);
            margin: 0 auto;
            max-width: 1200px;
            overflow: hidden;
            position: relative;
        }

        .rewards-pc-wrap .current-profit .point {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .current-profit .integer {
            color: #fff;
            font-size: 45px;
        }

        .rewards-pc-wrap .current-profit .decimal {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .current-profit .unit {
            color: #fff;
            font-size: 24px;
            margin-right: 5px;
            margin-top: 18px;
        }

        .rewards-pc-wrap .yesterday-profit .point {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .yesterday-profit .integer {
            color: #fff;
            font-size: 45px;
        }

        .rewards-pc-wrap .yesterday-profit .decimal {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .yesterday-profit .unit {
            color: #fff;
            font-size: 24px;
            margin-right: 5px;
            margin-top: 18px;
        }

        .rewards-pc-wrap .profit-rate-100 .point {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .profit-rate-100 .integer {
            color: #fff;
            font-size: 45px;
        }

        .rewards-pc-wrap .profit-rate-100 .decimal {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .profit-rate-100 .unit {
            color: #fff;
            font-size: 24px;
            margin-right: 5px;
            margin-top: 18px;
        }

        .rewards-pc-wrap .total-profit .point {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .total-profit .integer {
            color: #fff;
            font-size: 45px;
        }

        .rewards-pc-wrap .total-profit .decimal {
            color: #fff;
            font-size: 25px;
        }

        .rewards-pc-wrap .total-profit .unit {
            color: #fff;
            font-size: 24px;
            margin-right: 5px;
            margin-top: 18px;
        }

        .rewards-pc-wrap {
            height: 400px;
            margin-left: 129px;
            padding-top: 100px;
            width: 630px;
        }

        .itm-rv {
            -ms-flex: 1;
            -webkit-box-flex: 1;
            flex: 1;
            font-family: "Arial";
        }

        .fb {
            font-weight: 700;
        }

        .main-p {
            color: hsla(0,0%,100%,.7);
            font-size: 13px;
            margin-bottom: 8px;
            margin-top: 10px;
        }

        .sub-p {
            color: hsla(0,0%,100%,.5);
            font-size: 12px;
            margin-top: 12px;
        }

        .fb-r {
            font-weight: 300;
        }

        .price-btc {
            color: hsla(0,0%,100%,.5);
            font-size: 13px;
            margin-top: 10px;
        }

    </style>
</head>
<body>
    <div class="at-equity-wrap">
        <div  class="rewards" >
            <div  class="calculate_container">
                <div  class="rewards-wrap">
                    <div class="flex jcc aic">
                        <div  class="rewards-pc-wrap slideInUp" id="nuBlock">
                            <div  class="flex jcsb aic">
                                <div  class="itm-rv" style="margin-right: 60px;">
                                    <div  class="current-profit th-num-bold fb"><span  class="unit pull-left">$</span> <span class="integer" id="cr_prft_int" >0</span> <span  class="point">.</span> <span class="decimal" id="cr_prft_dcml" >00</span></div>
                                    <p  class="main-p">Platform Rewards to Be Distributed Today</p>
                                    <p  class="sub-p fb-r">Total circulating KAT eligible for rewards:100,000,000</p>
                                </div>
                                <div  class="itm-rv">
                                    <div  class="profit-rate-100 th-num-bold"><span  class="unit pull-left">$</span> <span  class="integer" id="dly_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="dly_prft_dcml" >00</span></div>
                                    <p  class="main-p">Daily Rewards of 1000 KAT</p>
                                    <div  class="profit-rate sub-p fb-r"><span >Daily KAT Rewards Rate</span> <span  class="integer">0</span> <span  class="decimal">.00</span> <span  class="unit">%</span></div>
                                </div>
                            </div>
                            <div  class="flex jcsb aic" style="margin-top: 40px;">
                                <div  class="itm-rv" style="margin-right: 60px;">
                                    <div  class="yesterday-profit th-num-bold fb'"><span  class="unit pull-left">$</span> <span  class="integer" id="ytd_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="ytd_prft_dcml" >00</span></div>
                                    <div  class="price-btc fb-r">/ 0.00000000 BTC</div>
                                    <p  class="main-p fb-r">Platform Rewards Distributed Yesterday</p>
                                </div>
                                <div  class="itm-rv">
                                    <div  class="total-profit th-num-bold fb'"><span  class="unit pull-left">$</span> <span  class="integer" id="ttl_prft_int" >0</span> <span  class="point">.</span><span  class="decimal" id="ttl_prft_dcml" >00</span></div>
                                    <div  class="price-btc fb-r">/ 0.00000000 BTC</div>
                                    <p  class="main-p fb-r">Cumulative Platform Rewards Distributed</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script type="text/javascript">

    $(document).on('ready', function(){

        setTimeout(function(){ 
            cr_countUp();
            dly_countUp();
            ytd_countUp();
            ttl_countUp();
        }, 2000);

    });

    unit = "$";

    var cr_data, dly_data, ytd_data, ttl_data;
    cr_data = dly_data = ytd_data = ttl_data = ["670.0000682", "670.002", "660.000068", "660.002", "650.000000063", "650.01", "640.00000006", "640.01", "630.0000000602", "630.01", "620.0000000622", "620.01", "610.00000016", "610.002", "600.00000015998", "600.002", "590.00000094", "590.002", "580.0000009", "580.002", "760.0000682", "760.002", "660.000068", "660.002", "560.000000063", "560.01", "460.00000006", "460.01", "360.0000000602", "360.01", "260.0000000622", "260.01", "160.00000016", "160.002", "060.00000015998", "060.002", "950.00000094", "950.002", "850.0000009", "850.002"];

    cr_start = 0;
    cr_stop = cr_data.length - 1;
    cr_nu = 20;

    function cr_countUp(){
        setTimeout(function(){
            $("#cr_prft_int").text(cr_data[cr_start].split(".")[0]);
            $("#cr_prft_dcml").text(cr_data[cr_start].split(".")[1]);
            if(cr_start < cr_stop){
                cr_start += 1;
                cr_countUp();
            }
        }, cr_nu);
    }

    dly_start = 0;
    dly_stop = dly_data.length - 1;
    dly_nu = 20;

    function dly_countUp(){
        setTimeout(function(){
            $("#dly_prft_int").text(dly_data[dly_start].split(".")[0]);
            $("#dly_prft_dcml").text(dly_data[dly_start].split(".")[1]);
            if(dly_start < dly_stop){
                dly_start += 1;
                dly_countUp();
            }
        }, dly_nu);
    }

    ytd_start = 0;
    ytd_stop = ytd_data.length - 1;
    ytd_nu = 20;

    function ytd_countUp(){
        setTimeout(function(){
            $("#ytd_prft_int").text(ytd_data[ytd_start].split(".")[0]);
            $("#ytd_prft_dcml").text(ytd_data[ytd_start].split(".")[1]);
            if(ytd_start < ytd_stop){
                ytd_start += 1;
                ytd_countUp();
            }
        }, ytd_nu);
    }

    ttl_start = 0;
    ttl_stop = ttl_data.length - 1;
    ttl_nu = 20;

    function ttl_countUp(){
        setTimeout(function(){
            $("#ttl_prft_int").text(ttl_data[ttl_start].split(".")[0]);
            $("#ttl_prft_dcml").text(ttl_data[ttl_start].split(".")[1]);
            if(ttl_start < ttl_stop){
                ttl_start += 1;
                ttl_countUp();
            }
        }, ttl_nu);

    }
</script>
</html>


I do not know about any existing plugins, but it seems fairly easy to write one yourself using the JavaScript Timing Events.


Try jCounter, it has a customRange setting where you can specify the start and end number, it can count up as well including the fallback you want at the end.


Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to jquery-plugins

How to use a jQuery plugin inside Vue How add spaces between Slick carousel item Bootstrap carousel multiple frames at once Can someone explain how to implement the jQuery File Upload plugin? Correct way to integrate jQuery plugins in AngularJS Call Jquery function Twitter bootstrap remote modal shows same content every time Jquery Chosen plugin - dynamically populate list by Ajax How to show all rows by default in JQuery DataTable Change Placeholder Text using jQuery

Examples related to timer

Flutter Countdown Timer How to do a timer in Angular 5 Create a simple 10 second countdown Python loop to run for certain amount of seconds Error 1053 the service did not respond to the start or control request in a timely fashion Wait some seconds without blocking UI execution The simplest possible JavaScript countdown timer? How can I perform a short delay in C# without using sleep? How to add a "sleep" or "wait" to my Lua Script? How to use timer in C?

Examples related to counter

HTML/Javascript Button Click Counter How to sort Counter by value? - python How to count the number of words in a sentence, ignoring numbers, punctuation and whitespace? Counter increment in Bash loop not working Get loop counter/index using for…of syntax in JavaScript Count characters in textarea Counter in foreach loop in C# jQuery counter to count up to a target number How to count the frequency of the elements in an unordered list? Code for a simple JavaScript countdown timer?