Skip to content

Instantly share code, notes, and snippets.

@shepelevstas
Created April 8, 2022 06:57
Show Gist options
  • Save shepelevstas/8db0dc53792ffeff8e62ec5001fc5564 to your computer and use it in GitHub Desktop.
Save shepelevstas/8db0dc53792ffeff8e62ec5001fc5564 to your computer and use it in GitHub Desktop.
counter up to big int
<script>
;window.addEventListener('load', () => {
/// пример <span data-count-from='0' data-count-to='8000000' data-count-duration='2000'>8.000.000</span>
function onceVisible(el, callback) {
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
callback(el, entry, observer)
observer.disconnect()
}
})
}).observe(el)
}
const randInt = max => Math.floor(Math.random() * max)
const formatInt = num => {
num = parseInt(num).toString()
let s = -3
let e = 0
const parts = []
let part = num.slice(s, e || undefined)
while (part) {
parts.push(part)
s -= 3
e -= 3
part = num.slice(s, e || undefined)
}
return parts.reverse().join('.')
}
function runCounter(el) {
const to = parseInt(el.dataset.countTo)
const from = parseInt(el.dataset.countFrom || 0)
const duration = parseInt(el.dataset.countDuration || 2000)
el.textContent = from
const start = Date.now()
const dist = to - from
const frame = () => {
const delta = Date.now() - start
let val = parseInt(from + dist * (delta / duration))
if (val < to) {
if (val > 1000)
val = parseInt(val/1000)*1000 + randInt(1000)
el.textContent = formatInt(val)
window.requestAnimationFrame(frame)
} else {
el.textContent = formatInt(to)
}
}
window.requestAnimationFrame(frame)
}
document.querySelectorAll('[data-count-to]').forEach(el => onceVisible(el, runCounter))
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment