abidibo.net

Bootstrap progress bar animation

bootstrap javascript tips

Boostrap progress bar is a nice component that comes in handy when loading async contents, large images or, for example, when rendering a complex google map.

But as is, it is quite useless if you want to implement a dynamic loader, which progress value changes over time. There are two major problems:

  1. when updating the value there is no animation, but just a jump to the new provided value;
  2. if the value updates are set immediately one after another, you can't perceive any changes, since it just seems that the progress goes from 0 to 100 instantly.

So I wrote a simple js object which wraps the common functionality for this kind of component. Let's begin from the html part:

<div id="progress-bar">
    <progress class="progress progress-striped progress-success" value="1" max="100">
        <div class="progress">
            <span class="progress-bar" style="width: 1%;">1%</span>
        </div>
    </progress>
    <div class="progress-info">init</div>
</div>

As you can notice I've wrapped the progress element inside a container and added a progress-info element.

Now the js:

var progressBarContainer = $('#progress-bar');
var progressBar = {
    chain: [],
    progress: progressBarContainer.children('progress'),
    progressBar: progressBarContainer.find('.progress-bar'),
    progressInfo: progressBarContainer.children('.progress-info'),
    set: function(value, info, noPush) {
        if(!noPush) {
            this.chain.push(value);
        }
        if(this.chain[0] == value) {
            this.go(value, info);
        }
        else {
            var self = this;
            setTimeout(function() {
                self.set(value, info, true)
            }, 200);
        }
    },
    go: function(value, info) {
        this.progressInfo.text(info);
        var self = this;
        var interval = setInterval(function() {
            var curr = self.progress.attr('value');
            if(curr >= value) {
                clearInterval(interval);
                self.progress.attr('value', value);
                self.progressBar.css('width', value + '%');
                self.chain.shift()
            }
            else {
                self.progress.attr('value', ++curr);
                self.progressBar.css('width', curr + '%');
            }
        }, 5)
    }
};

Just to explain it a bit:

  • there is a chain array which tracks the value updates. Every update is run only if is the first in the chain, otherwise a check is made after 200 ms.
  • When an update runs, a setInterval is used in order to obtain a smooth animation, and when the animation is complete, the value is shifted from the chain array so that the following update will be run after the next check.
  • The set function is used to update the progress value
  • I've made this using jQuery for convenience, but it's not that hard to make the same thing in vanilla js.

Let's see an example in action

See the Pen Bootstrap Progress Bar Animation by abidibo (@abidibo) on CodePen.

Subscribe to abidibo.net!

If you want to stay up to date with new contents published on this blog, then just enter your email address, and you will receive blog updates! You can set you preferences and decide to receive emails only when articles are posted regarding a precise topic.

I promise, you'll never receive spam or advertising of any kind from this subscription, just content updates.

Subscribe to this blog

Comments are welcome!

blog comments powered by Disqus

Your Smartwatch Loves Tasker!

Your Smartwatch Loves Tasker!

Now available for purchase!

Featured