UNPKG

5.04 kBJavaScriptView Raw
1(function (angular) {
2
3 // Count-Up directive
4 // --------------------------------------------
5 //
6 // * **Class:** CountUp
7 // * **Author:** Jamie Perkins
8 //
9 // Creates a counting animation for numbers
10 // REQUIRED attributes:
11 // - endVal
12 //
13 // DEPENDENCY: countUp.js
14
15 'use strict';
16
17 var module = angular.module('countUpModule', []);
18
19 /**
20 * count-up attribute directive
21 *
22 * @param {number} startVal - (optional) The value you want to begin at, default 0
23 * @param {number} countUp - The value you want to arrive at
24 * @param {number} duration - (optional) Duration in seconds, default 2.
25 * @param {number} decimals - (optional) Number of decimal places in number, default 0
26 * @param {boolean} reanimateOnClick - (optional) Config if reanimate on click event, default true.
27 * @param {string} filter - (optional) Filter expression to apply to animated values
28 * @param {object} options - (optional) Provides for extra configuration, such as easing.
29 */
30 module.directive('countUp', [ '$filter', function($filter) {
31
32 return {
33 restrict: 'A',
34 scope: {
35 startVal: '=?',
36 endVal: '=?',
37 duration: '=?',
38 decimals: '=?',
39 reanimateOnClick: '=?',
40 filter: '@',
41 options: '=?'
42 },
43 link: function ($scope, $el, $attrs) {
44
45 var options = {};
46
47 if ($scope.filter) {
48 var filterFunction = createFilterFunction();
49 options.formattingFn = filterFunction;
50 }
51
52 if ($scope.options) {
53 angular.extend(options, $scope.options);
54 }
55
56 var countUp = createCountUp($scope.startVal, $scope.endVal, $scope.decimals, $scope.duration);
57
58 function createFilterFunction() {
59 var filterParams = $scope.filter.split(':');
60 var filterName = filterParams.shift();
61
62 return function(value) {
63 var filterCallParams = [value];
64 Array.prototype.push.apply(filterCallParams, filterParams);
65 value = $filter(filterName).apply(null, filterCallParams);
66 return value;
67 };
68 }
69
70 function createCountUp(sta, end, dec, dur) {
71 sta = sta || 0;
72 if (isNaN(sta)) sta = Number(sta.match(/[\d\-\.]+/g).join('')); // strip non-numerical characters
73 end = end || 0;
74 if (isNaN(end)) end = Number(end.match(/[\d\-\.]+/g).join('')); // strip non-numerical characters
75 dur = Number(dur) || 2;
76 dec = Number(dec) || 0;
77
78 // construct countUp
79 var countUp = new CountUp($el[0], sta, end, dec, dur, options);
80 if (end > 999) {
81 // make easing smoother for large numbers
82 countUp = new CountUp($el[0], sta, end - 100, dec, dur / 2, options);
83 }
84
85 return countUp;
86 }
87
88 function animate() {
89 countUp.reset();
90 if ($scope.endVal > 999) {
91 countUp.start(function() {
92 countUp.update($scope.endVal);
93 });
94 }
95 else {
96 countUp.start();
97 }
98 }
99
100 // fire on scroll-spy event, or right away
101 if ($attrs.scrollSpyEvent) {
102 // listen for scroll spy event
103 $scope.$on($attrs.scrollSpyEvent, function (event, data) {
104 if (data === $attrs.id) {
105 animate();
106 }
107 });
108 }
109 else {
110 animate();
111 }
112
113 // re-animate on click
114 var reanimateOnClick = angular.isDefined($scope.reanimateOnClick) ? $scope.reanimateOnClick : true;
115 if (reanimateOnClick) {
116 $el.on('click', function() {
117 animate();
118 });
119 }
120
121 $scope.$watch('endVal', function (newValue, oldValue) {
122 if (newValue === null || newValue === oldValue) {
123 return;
124 }
125
126 if (countUp !== null) {
127 countUp.update($scope.endVal);
128 } else {
129 countUp = createCountUp($scope.startVal, $scope.endVal, $scope.decimals, $scope.duration);
130 animate();
131 }
132 });
133 }
134 };
135 }]);
136})(angular);
\No newline at end of file