(function($) { var NumberProgressBar = function(element, options) { var settings = $.extend ({ duration: 10000, min: 0, max: 100, current: 0, shownQuery: '.number-pb-shown', numQuery: '.number-pb-num' }, options || {}); this.duration = settings.duration; if (settings.min < settings.max) { this.min = settings.min; this.max = settings.max; this.current = (settings.current >= this.min && settings.current <= this.max) ? settings.current : this.min; } else { this.min = 0; this.max = 100; this.current = 0; } this.interval = this.max - this.min; this.last = this.min; this.$element = $(element); this.$shownBar = this.$element.find(settings.shownQuery); this.$num = this.$element.find(settings.numQuery); this.reach(this.current); } NumberProgressBar.prototype.calDestination = function(dest) { return (dest < this.min) ? this.min : ( (dest > this.max) ? this.max : dest ) } NumberProgressBar.prototype.calDuration = function() { return this.duration * Math.abs(this.current - this.last) / this.interval; } NumberProgressBar.prototype.shuffle = function(callback) { var dest = Math.round(Math.random() * this.interval) + this.min; this.reach(dest, null, callback); } NumberProgressBar.prototype.calPercentage = function() { return (this.current - this.min) / this.interval * 100 } NumberProgressBar.prototype.reach = function(dest, duration, callback) { this.current = this.calDestination(dest); this.moveShown(duration); this.moveNum(duration, callback); this.last = this.current; } NumberProgressBar.prototype.moveShown = function(duration) { this.$shownBar.velocity({ width: this.calPercentage() + '%' }, { duration: duration || this.calDuration() }) } NumberProgressBar.prototype.moveNum = function(duration, callback) { var self = this; var duration = duration || this.calDuration(); this.$num.velocity({ left: this.calPercentage() + '%' }, { duration: duration, complete: callback }); // number $({num: this.last}).animate({ num: this.current }, { queue: true, duration: duration, step: function() { self.$num.text(Math.ceil(this.num)); }, complete: function() { self.$num.text(self.current); } }) } $.fn.NumberProgressBar = function(options) { return this.each(function () { var element = $(this); if (element.data('number-pb')) return; element.data('number-pb', new NumberProgressBar(this, options)); }) } $.fn.reach = function(dest, options) { var settings = $.extend ({ duration : null, complete : null }, options || {}); return this.each(function() { var element = $(this); var progressbar = element.data('number-pb'); if (!progressbar) return; if (typeof dest === "undefined") { progressbar.shuffle(settings.complete); } else { progressbar.reach(dest, settings.duration, settings.complete); } }) } })(jQuery);