countUp.module.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import {
  2. Directive,
  3. ElementRef,
  4. Input,
  5. HostListener,
  6. Inject,
  7. OnInit,
  8. NgModule
  9. } from '@angular/core';
  10. declare var CountUp;
  11. /**
  12. * Animates the inner text of the element to count up to endVal.
  13. */
  14. @Directive({
  15. selector: '[countUp]'
  16. })
  17. export class CountUpDirective implements OnInit {
  18. /**
  19. * Optional extra configuration, such as easing.
  20. */
  21. @Input('countUp')
  22. options: any;
  23. /**
  24. * Optional start value for the count. Defaults to zero.
  25. */
  26. @Input()
  27. startVal: number;
  28. /**
  29. * The value to count up to.
  30. */
  31. private _endVal: number;
  32. @Input()
  33. get endVal(): number {
  34. return this._endVal;
  35. }
  36. set endVal(value: number) {
  37. this._endVal = value;
  38. if (isNaN(value)) {
  39. return;
  40. }
  41. if (!this._countUp) {
  42. return;
  43. }
  44. this._countUp.update(value);
  45. }
  46. /**
  47. * Optional duration of the animation. Default is two seconds.
  48. */
  49. @Input()
  50. duration: number;
  51. /**
  52. * Optional number of decimal places. Default is two.
  53. */
  54. @Input()
  55. decimals: number;
  56. /**
  57. * Optional flag for specifying whether the element should re-animate when clicked.
  58. * Default is true.
  59. */
  60. @Input()
  61. reanimateOnClick: boolean;
  62. ngOnInit() {
  63. this._countUp = this.createCountUp(
  64. this.startVal, this.endVal, this.decimals, this.duration);
  65. this.animate();
  66. }
  67. /**
  68. * Re-animate if preference is set.
  69. */
  70. @HostListener('click')
  71. onClick() {
  72. if (this.reanimateOnClick) {
  73. this.animate();
  74. }
  75. }
  76. private _countUp;
  77. constructor(@Inject(ElementRef) private el: ElementRef) {}
  78. private createCountUp(sta, end, dec, dur) {
  79. sta = sta || 0;
  80. if (isNaN(sta)) sta = Number(sta.match(/[\d\-\.]+/g).join('')); // strip non-numerical characters
  81. end = end || 0;
  82. if (isNaN(end)) end = Number(end.match(/[\d\-\.]+/g).join('')); // strip non-numerical characters
  83. dur = Number(dur) || 2;
  84. dec = Number(dec) || 0;
  85. // construct countUp
  86. let countUp = new CountUp(this.el.nativeElement, sta, end, dec, dur, this.options);
  87. if (end > 999) {
  88. // make easing smoother for large numbers
  89. countUp = new CountUp(this.el.nativeElement, sta, end - 100, dec, dur / 2, this.options);
  90. }
  91. return countUp;
  92. }
  93. private animate() {
  94. this._countUp.reset();
  95. if (this.endVal > 999) {
  96. this._countUp.start(() => this._countUp.update(this.endVal));
  97. } else {
  98. this._countUp.start();
  99. }
  100. }
  101. }
  102. /**
  103. * Module providing the countUp directive.
  104. */
  105. @NgModule({
  106. declarations: [CountUpDirective],
  107. exports: [CountUpDirective]
  108. })
  109. export class CountUpModule {}