| 1 |
/* https://github.com/mhuggins/jquery-countTo */ |
| 2 |
|
| 3 |
(function (factory) { |
| 4 |
if (typeof define === 'function' && define.amd) { |
| 5 |
// AMD |
| 6 |
define(['jquery'], factory); |
| 7 |
} else if (typeof exports === 'object') { |
| 8 |
// CommonJS |
| 9 |
factory(require('jquery')); |
| 10 |
} else { |
| 11 |
// Browser globals |
| 12 |
factory(jQuery); |
| 13 |
} |
| 14 |
}(function ($) { |
| 15 |
var CountTo = function (element, options) { |
| 16 |
this.$element = $(element); |
| 17 |
this.options = $.extend({}, CountTo.DEFAULTS, this.dataOptions(), options); |
| 18 |
this.init(); |
| 19 |
}; |
| 20 |
|
| 21 |
CountTo.DEFAULTS = { |
| 22 |
from: 0, // the number the element should start at |
| 23 |
to: 0, // the number the element should end at |
| 24 |
speed: 1000, // how long it should take to count between the target numbers |
| 25 |
refreshInterval: 100, // how often the element should be updated |
| 26 |
decimals: 0, // the number of decimal places to show |
| 27 |
formatter: formatter, // handler for formatting the value before rendering |
| 28 |
onUpdate: null, // callback method for every time the element is updated |
| 29 |
onComplete: null // callback method for when the element finishes updating |
| 30 |
}; |
| 31 |
|
| 32 |
CountTo.prototype.init = function () { |
| 33 |
this.value = this.options.from; |
| 34 |
this.loops = Math.ceil(this.options.speed / this.options.refreshInterval); |
| 35 |
this.loopCount = 0; |
| 36 |
this.increment = (this.options.to - this.options.from) / this.loops; |
| 37 |
}; |
| 38 |
|
| 39 |
CountTo.prototype.dataOptions = function () { |
| 40 |
var options = { |
| 41 |
from: this.$element.data('from'), |
| 42 |
to: this.$element.data('to'), |
| 43 |
speed: this.$element.data('speed'), |
| 44 |
refreshInterval: this.$element.data('refresh-interval'), |
| 45 |
decimals: this.$element.data('decimals') |
| 46 |
}; |
| 47 |
|
| 48 |
var keys = Object.keys(options); |
| 49 |
|
| 50 |
for (var i in keys) { |
| 51 |
var key = keys[i]; |
| 52 |
|
| 53 |
if (typeof(options[key]) === 'undefined') { |
| 54 |
delete options[key]; |
| 55 |
} |
| 56 |
} |
| 57 |
|
| 58 |
return options; |
| 59 |
}; |
| 60 |
|
| 61 |
CountTo.prototype.update = function () { |
| 62 |
this.value += this.increment; |
| 63 |
this.loopCount++; |
| 64 |
|
| 65 |
this.render(); |
| 66 |
|
| 67 |
if (typeof(this.options.onUpdate) == 'function') { |
| 68 |
this.options.onUpdate.call(this.$element, this.value); |
| 69 |
} |
| 70 |
|
| 71 |
if (this.loopCount >= this.loops) { |
| 72 |
clearInterval(this.interval); |
| 73 |
this.value = this.options.to; |
| 74 |
|
| 75 |
if (typeof(this.options.onComplete) == 'function') { |
| 76 |
this.options.onComplete.call(this.$element, this.value); |
| 77 |
} |
| 78 |
} |
| 79 |
}; |
| 80 |
|
| 81 |
CountTo.prototype.render = function () { |
| 82 |
var formattedValue = this.options.formatter.call(this.$element, this.value, this.options); |
| 83 |
this.$element.text(formattedValue); |
| 84 |
}; |
| 85 |
|
| 86 |
CountTo.prototype.restart = function () { |
| 87 |
this.stop(); |
| 88 |
this.init(); |
| 89 |
this.start(); |
| 90 |
}; |
| 91 |
|
| 92 |
CountTo.prototype.start = function () { |
| 93 |
this.stop(); |
| 94 |
this.render(); |
| 95 |
this.interval = setInterval(this.update.bind(this), this.options.refreshInterval); |
| 96 |
}; |
| 97 |
|
| 98 |
CountTo.prototype.stop = function () { |
| 99 |
if (this.interval) { |
| 100 |
clearInterval(this.interval); |
| 101 |
} |
| 102 |
}; |
| 103 |
|
| 104 |
CountTo.prototype.toggle = function () { |
| 105 |
if (this.interval) { |
| 106 |
this.stop(); |
| 107 |
} else { |
| 108 |
this.start(); |
| 109 |
} |
| 110 |
}; |
| 111 |
|
| 112 |
function formatter(value, options) { |
| 113 |
return value.toFixed(options.decimals); |
| 114 |
} |
| 115 |
|
| 116 |
$.fn.countTo = function (option) { |
| 117 |
return this.each(function () { |
| 118 |
var $this = $(this); |
| 119 |
var data = $this.data('countTo'); |
| 120 |
var init = !data || typeof(option) === 'object'; |
| 121 |
var options = typeof(option) === 'object' ? option : {}; |
| 122 |
var method = typeof(option) === 'string' ? option : 'start'; |
| 123 |
|
| 124 |
if (init) { |
| 125 |
if (data) data.stop(); |
| 126 |
$this.data('countTo', data = new CountTo(this, options)); |
| 127 |
} |
| 128 |
|
| 129 |
data[method].call(data); |
| 130 |
}); |
| 131 |
}; |
| 132 |
})); |