Animated Numbers Animation Problem.

I know this post is a bit old, but I am doing something similar so thought I would put the code in I came up with.

I did however make some modifications as I wanted the code to:

  • get the final number from the html (meaning I could design the page with final numbers in place)
  • allow multiple animations on the same page
  • get rid of the setInterval as the above code doesn’t stop the interval - which will slow the page
  • only have the animations play once

so what I did:

 class Counter = {
     constructor(target) {
         this.el = target;
         this.from = 0;
         this.to = target.text;
         this.run();
     }
     run() {
         if (this.from < this.to) {
             this.from++;
             this.el.text = this.from.toString();
             setTimeout(this.run.bind(this), 20); // <= 20ms delay
         }
     } 
 }

The Counter class is a reusable function I can call, passing it a Wix element, taking the text out as the to value, and setting the from value as 0. We then call the run function which uses a timeout to loop the run function, but only if the from value is less than the to value.

in order to stop this being called every time the element enters the viewport, we need to store a record of which elements have been animated. we do this simply but storing the ID’s of the animated elements in an array, and searching the array prior to instantiating the Counter function to make sure the ID doesn’t already exist…

const counterManager = {
    arr: [],
    add(event) {
        if (!this.arr.includes(event.target.id)) {
            this.arr.push(event.target.id);
            new Counter(event.target);
        }
    }
}

The only thing left is to add the viewport enter event to all the elements that we want to animate, I did this in the onReady function making use of the multi-element selector.

$w.onReady(function () {
    $w('#text28, #text30')
        .onViewportEnter( event => counterManager.add(event) );
});