forked from bfintal/Counter-Up2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
138 lines (111 loc) · 3.61 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const counterUp = (el, options = {}) => {
const {
action = 'start',
duration = 1000,
delay = 16,
lang = undefined
} = options;
// Allow people to use this as a stop method.
if (action === 'stop') {
stopCountUp(el);
return
}
stopCountUp(el);
// If no number, don't do anything.
if (!/[0-9]/.test(el.innerHTML)) {
return
}
const num = el.getAttribute('data-num') || el.innerHTML;
const nums = divideNumbers(num, {
duration: el.getAttribute('data-duration') || duration,
lang: lang || document.querySelector('html').getAttribute('lang') || undefined,
delay: delay || el.getAttribute('data-delay'),
});
// Remember the contents.
el._countUpOrigInnerHTML = num;
el.setAttribute('data-num', el._countUpOrigInnerHTML);
// Start counting.
el.innerHTML = nums[0];
el.style.visibility = 'visible';
// Function for displaying output with the set time and delay.
const output = function() {
el.innerHTML = nums.shift();
if (nums.length) {
clearTimeout(el.countUpTimeout);
el.countUpTimeout = setTimeout(output, delay)
} else {
el._countUpOrigInnerHTML = undefined
}
};
el.countUpTimeout = setTimeout(output, delay)
};
export default counterUp
const stopCountUp = el => {
clearTimeout(el.countUpTimeout);
if (el._countUpOrigInnerHTML) {
el.innerHTML = el._countUpOrigInnerHTML;
el._countUpOrigInnerHTML = undefined
}
el.style.visibility = ''
};
export const divideNumbers = (num, options = {}) => {
const {
duration = 1000,
delay = 16,
lang = undefined
} = options;
// Number of times the number will change.
const divisions = duration / delay;
// Split numbers and html tags.
const splitValues = num.toString().split(/(<[^>]+>|[0-9.][,.0-9]+[0-9]*)/);
// Contains all numbers to be displayed.
const nums = [];
// Set blank strings to ready the split values.
for (let k = 0; k < divisions; k++) {
nums.push('')
}
// Loop through all numbers and html tags.
for (let i = 0; i < splitValues.length; i++) {
// If number split it into smaller numbers and insert it to nums.
if (/([0-9.][,.0-9]+[0-9]*)/.test(splitValues[i]) && !/<[^>]+>/.test(splitValues[i])) {
let num = splitValues[i];
// Remove comma for computation purposes.
num = num.replace(/,/g, '');
// Test if values have point.
const isFloat = /^[0-9]+\.[0-9]+$/.test(num);
// Check number of decimals places.
const decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;
// Start adding numbers from the end.
let k = nums.length - 1;
// Create small numbers
for (let val = divisions; val >= 1; val--) {
let newNum = parseInt(num / divisions * val, 10);
if (isNaN(newNum)) {
break;
}
// If has decimal point, add it again.
if (isFloat) {
newNum = parseFloat(num / divisions * val).toFixed(decimalPlaces);
const splitNumber = newNum.split('.');
const options = {};
if (splitNumber.length > 1) {
var fractionDigits = splitNumber[1].length;
options.minimumFractionDigits = fractionDigits;
options.maximumFractionDigits = fractionDigits;
}
newNum = parseFloat(newNum).toLocaleString(lang, options);
} else {
newNum = newNum.toLocaleString(lang);
}
// Insert all small numbers.
nums[k--] += newNum
}
} else {
// Insert all non-numbers in the same place.
for (let k = 0; k < divisions; k++) {
nums[k] += splitValues[i]
}
}
}
return nums
};