angular-countUp.js 4.9 KB

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