JSFiddle - React, Tailwind, and code Playground
by BurpmanJunior
HTML
<p>A number: <span data-countup="231561"></span>
</p>
<div style="height: 500px;"></div>
<p>Some number: <span data-countup="500"></span>
</p>
<p>Another number: <span data-countup="77"></span>
</p>
<p>More numbers: <span data-countup="99.9"></span>
</p>
<div style="height: 300px;"></div>
<p>Last number: <span data-countup="78453.42"></span>
</p>
CSS
body {
font-family: monospace;
}
JavaScript
/*
* COUNT UP
*/
var countup = {
duration: 2000,
fps: 24,
frameLength: 100,
init: function () {
this.frameLength = (1000 / this.fps);
setTimeout(this.bindEvents, 100);
var elems = document.querySelectorAll('[data-countup]');
for (var i = 0; i < elems.length; i++) {
elems[i].innerHTML = 0;
}
},
bindEvents: function () {
var _c = countup;
_c.checkPos();
window.addEventListener('scroll', function (e) {
_c.checkPos();
});
window.addEventListener('resize', function (e) {
_c.checkPos();
});
},
checkPos: function () {
var _c = countup;
var elems = document.querySelectorAll('[data-countup]');
var wY = window.innerHeight;
var sY = window.scrollY;
for (var i = 0; i < elems.length; i++) {
if (elems[i].offsetTop <= (sY + wY)) {
_c.count(elems[i]);
}
}
},
count: function (elem) {
if (typeof elem.processing !== 'undefined') {
return false;
}
elem.processing = true;
var _c = countup;
var limit = elem.getAttribute('data-countup');
limit = parseFloat(limit);
var current = 0;
var step = ((limit - current) / (_c.duration / _c.frameLength));
current = step;
var numFloat = false;
if (limit % 1 !== 0) {
numFloat = true;
}
elem.looper = setInterval(function () {
current = Math.min(current, limit);
elem.innerHTML = (numFloat ? parseFloat(current.toFixed(1)) : Math.ceil(current));
if (current < limit) {
current += step;
} else {
window.clearInterval(elem.looper);
elem.innerHTML = limit;
}
}, _c.frameLength);
}
}
countup.init();