Animate Numbers on Scroll

Let's see how we can create a counter which counts up as you scroll down. For this, we will be using a basic text element which will be targeted in Motion.page. We will also be using a pinned element for this example, as well as the ScrollTrigger.

Build your Elements

First, let's set up the necessary elements in the builder of your choice. For this example, we will be using Oxygen Builder. Here, we will use a section set to 100vh, and we will place some text in the center. Feel free to set these elements however you wish! The most important thing is to have a section with a text element inside of it.

Editing in Motion.page

Next, we can open up Motion.page and create a new timeline. Let's go ahead and name our timeline something convenient, such as Number Counter.

We will go ahead and select Scroll Trigger as our main trigger. And then we will set the following settings:

  • Lock to Scrollbar: check
  • Delay: 0.2s (you can choose anything that you see fit)
  • Pinned element: check
  • Select your section's ID as your pinned element

Under Starts When, let's go ahead and select "Pinned Element's Top" reaches "0%". This will mean that the section will begin to pin once it reaches 0% (the top of the viewport)

Under Ends When, we will choose "Pinned Element's Top" reaches "-100%". This will stop pinning when the top of the section reaches -100% (the height of itself). You can change this number to something like -200% if you would like the animation to last longer.

Here is how our settings look:

Next, we can go ahead to the Animation section and select your text element under the Animation Selector.

Ensure you are using the FROM timeline, and go ahead to Custom. You may need to toggle the CSS/GSAP button so that we have an open box where we can add JavaScript.

Next, we can add some JavaScript to the Custom box to control the text. Below we will provide two different examples:

JS Example 1:

innerText: 0,
modifiers: {
  innerText: innerText => {
    const parsedNumber = parseFloat(innerText);
    if (!isNaN(parsedNumber)) {
      return Math.floor(parsedNumber).toLocaleString();
    }
    return innerText;
  }
}

JS Example 2 (Extremely Simple):

innerText: 0,
snap:{innerText:1}

This will also work if you choose the PageLoad trigger. This is useful if the number is above the fold when your web page loads.

Also, a nice effect would be to have this run as you scroll and have the counter count up automatically where it is not dependent on the scroll bar, to achieve this, you would simply need to uncheck the "Lock to Scrollbar" option.

You may notice that the counter slows down towards the end. In this case, be sure to set the Ease (located at the bottom of the Animation section) to none, to make sure the animation is linear.

100 %