Web Analytics

How to: Animate Numbers When Scrolled Into View

by Utsab Karki, Senior WordPress Developer

Statistics are a huge part of your organization’s story and can help you to differentiate from your competitors, influencing your users by providing specific, quantitive data.

Visualizing your data can help enhance user experience, increase user engagement, and better tell your story.

We’ve talked previously about creating charts for better data visualization, but if your data is better shared as impactful numbers, you can do much more than just using a bold, large font. Instead, why not make your data more visually compelling and eye-catching by animating the numbers when they come in view?

In order to make your numbers animate and count up from 0, we’ll utilize the Intersection Observer API to determine when the section comes into view onscreen and then run a function to make the numbers count up.

Displaying the Statistics via HTML

In the below HTML, we’ll store the value we want to count up to in a data-number attribute and put 0 inside the span tag with the class statistics–single__data–number.

This way, when the section is first displayed on the page, only the number 0 will show, and we’ll use some Javascript to count up to the desired number stored in the data-number attribute.

<section class="statistics">
     <div class="statistics–single">
          <div class="statistics–single__data">
               <span class="statistics–single__data–number" data-number="97">0</span>%
          </div>
     </div>
     <div class="statistics–single">
          <div class="statistics–single__data">
               $<span class="statistics–single__data–number" data-number="20">0</span> Million
          </div>
     </div>
     <div class="statistics–single">
          <div class="statistics–single__data">
               <span class="statistics–single__data–number" data-number="87.93">0</span>%
          </div>
     </div>
</section>

Any words or characters that should be prepended or appended to the number (ie, % or a descriptor of the amount) can be added outside the span tags.

Counting Up and Animating When In View

Let’s use the Intersection Observer API to determine when the section with the statistics comes into view on the user’s screen. First, we’ll define an observer instance.

var observerInstance = new IntersectionObserver(onIntersection, {
     root: null,   // default is the viewport
     rootMargin: '-40% 0% -40% 0%',
     threshold: 0 // percentage of target's visible area. Triggers "onIntersection"
});

In this instance, we’ll define the rootMargin to be -40% 0% -40% 0%, which means that the callback function onIntersection is only called when the section is in the middle 20% of the screen.

Next, let’s add the Javascript to tell the observer instance to look for a span with class statistics–single__data–number and to run the callback function when it comes into view.

$('span.statistics–single__data–number').each(function(){
     document.querySelectorAll('.statistics–single__data–number').forEach(
          i => observerInstance.observe( i )
     );
});

Finally, we’ll add the onIntersection callback function that is called when the section comes into view.

function onIntersection(entries, opts){
     entries.forEach(entry => {
          if (entry.isIntersecting) {
               var dataNumber = entry.target.getAttribute('data-number').split('.');
               var fractionDigits = 0;
               if (dataNumber[1]) {
                    var fractionDigits = dataNumber[1].length;
               }
               let startTimestamp = null;
               const step = (timestamp) => {
                    // Formatter for currency
                    var formatter = new Intl.NumberFormat('en-US', {maximumFractionDigits: fractionDigits})
                    if (!startTimestamp) startTimestamp = timestamp;
                    const progress = Math.min((timestamp - startTimestamp) / duration, 1);
                    obj.innerHTML = formatter.format(progress * (end - start) + start);
                    if (progress < 1) {
                         window.requestAnimationFrame(step);
                    }
               };
               window.requestAnimationFrame(step);
               opts.unobserve(entry.target);
          }
     });
}

Let’s break down this code.

First, we determine if the user has scrolled to the content by checking if entry.isIntersecting; when that happens, we grab the data-number attribute and, using the split function, create an array of numbers before and after the decimal point. Then, we create a NumberFormat object using the Intl.NumberFormat object and pass the length of the numbers after the decimal point to animate only up to certain decimal points.

When then call the Math.min function to calculate the next value to display for the number, and the innerHTML of the span tag is updated with this number. Then the requestAnimationFrame function is called to keep animating the number until the target value is reached.

From there, we have our statistics – animating and counting up to their final values – all happening when the user scrolls to the appropriate place on the page.

Here’s how it looks when you visit the website for the Maryland Hospital Association:

Displaying statistics on your website can help capture your user’s attention and better tell your organization’s story. If you need help implementing animated statistics on your website or for any other digital marketing needs, reach out to us.

Avatar photo
About Utsab Karki

Utsab Karki is the Senior WordPress Developer at Digital Ink. He builds new websites, manages functionality requests and changes, and makes clients' sites run better. Digital Ink tells stories for forward-thinking businesses, mission-driven organizations, and marketing and technology agencies in need of a creative and digital partner.

Other Stories You May Like

What’s your story?

Let’s share it with the world.

Let’s Do This

Close Window
All the Cool Kids are Doing it

Sign Up for the Digital Ink Newsletter

All the cool kids are doing it.