UNPKG

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