La idea
Animamos un valor t de 0 a 1 a lo largo del tiempo. En cada
frame calculamos qué número mostrar: final × t. Pero si usáramos
t tal cual, subiría a velocidad constante y aburrida. Por eso lo
pasamos por una curva de easing que lo hace frenar al final.
const e = 1 - Math.pow(1 - t, 3); num.textContent = Math.round(1200 * e);
El bucle con requestAnimationFrame
const dur = 1400, t0 = performance.now();
(function paso(now){
const t = Math.min((now - t0) / dur, 1);
const e = 1 - Math.pow(1 - t, 3);
num.textContent = Math.round(final * e);
if (t < 1) requestAnimationFrame(paso);
})(t0);
Que arranque al verse
No queremos que cuente antes de que el usuario lo vea. Con
IntersectionObserver disparamos la animación justo cuando el número
entra en pantalla.
const io = new IntersectionObserver(entradas => {
entradas.forEach(en => { if (en.isIntersecting) animar(); });
}, { threshold: 0.5 });
io.observe(numero);
Ideal para 🎯
Secciones de estadísticas: “+1.200 usuarios”, “98% satisfacción”. El conteo llama la atención y se siente premium.