123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- (function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // CommonJS
- factory(require('jquery'));
- } else {
- // Browser globals
- factory(jQuery);
- }
- }(function ($) {
- var CountTo = function (element, options) {
- this.$element = $(element);
- this.options = $.extend({}, CountTo.DEFAULTS, this.dataOptions(), options);
- this.init();
- };
-
- CountTo.DEFAULTS = {
- from: 0, // the number the element should start at
- to: 0, // 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
- formatter: formatter, // handler for formatting the value before rendering
- onUpdate: null, // callback method for every time the element is updated
- onComplete: null // callback method for when the element finishes updating
- };
-
- CountTo.prototype.init = function () {
- this.value = this.options.from;
- this.loops = Math.ceil(this.options.speed / this.options.refreshInterval);
- this.loopCount = 0;
- this.increment = (this.options.to - this.options.from) / this.loops;
- };
-
- CountTo.prototype.dataOptions = function () {
- var options = {
- from: this.$element.data('from'),
- to: this.$element.data('to'),
- speed: this.$element.data('speed'),
- refreshInterval: this.$element.data('refresh-interval'),
- decimals: this.$element.data('decimals')
- };
-
- var keys = Object.keys(options);
-
- for (var i in keys) {
- var key = keys[i];
-
- if (typeof(options[key]) === 'undefined') {
- delete options[key];
- }
- }
-
- return options;
- };
-
- CountTo.prototype.update = function () {
- this.value += this.increment;
- this.loopCount++;
-
- this.render();
-
- if (typeof(this.options.onUpdate) == 'function') {
- this.options.onUpdate.call(this.$element, this.value);
- }
-
- if (this.loopCount >= this.loops) {
- clearInterval(this.interval);
- this.value = this.options.to;
-
- if (typeof(this.options.onComplete) == 'function') {
- this.options.onComplete.call(this.$element, this.value);
- }
- }
- };
-
- CountTo.prototype.render = function () {
- var formattedValue = this.options.formatter.call(this.$element, this.value, this.options);
- this.$element.text(formattedValue);
- };
-
- CountTo.prototype.restart = function () {
- this.stop();
- this.init();
- this.start();
- };
-
- CountTo.prototype.start = function () {
- this.stop();
- this.render();
- this.interval = setInterval(this.update.bind(this), this.options.refreshInterval);
- };
-
- CountTo.prototype.stop = function () {
- if (this.interval) {
- clearInterval(this.interval);
- }
- };
-
- CountTo.prototype.toggle = function () {
- if (this.interval) {
- this.stop();
- } else {
- this.start();
- }
- };
-
- function formatter(value, options) {
- return value.toFixed(options.decimals);
- }
-
- $.fn.countTo = function (option) {
- return this.each(function () {
- var $this = $(this);
- var data = $this.data('countTo');
- var init = !data || typeof(option) === 'object';
- var options = typeof(option) === 'object' ? option : {};
- var method = typeof(option) === 'string' ? option : 'start';
-
- if (init) {
- if (data) data.stop();
- $this.data('countTo', data = new CountTo(this, options));
- }
-
- data[method].call(data);
- });
- };
- }));
|