Using GSAP and ScrollTrigger to create a number counter (where numbers exist)

I have a section which showcases statistics.

  • Some of these statistics are numbers (i.e. 145);
  • Some are numbers, characters and symbols (i.e. 65K+ or $20.00)
  • Some are just purely text (i.e. “text”)

When this section is in view, I want stats which contain a number to count up (and naturally stats that don’t contain numbers to not count up).

The effect I’m trying to achieve is:

  • All .statsBannerCard‘s are set to visibility: hidden
  • User scrolls to section
  • JS checks if first .statsBannerCard contains number; if yes, counts up (this single card is visibility: visible now).
  • Then once the counter for the first card is complete, make the second card visible and check if it contains a number, and so on.

The proceeding card is essentially shown once the previous card counter is complete. If a card just contains text (so we can’t count up), it will just show the card and move on.

Current issue:

In my demo below, I’m using the data-number attribute to determine what number the card needs to count up to. When scrolling down, the first counter works (because it is a pure integer), however, it stops working when characters, symbols or letters are involved.

Demo:

$(function() {

  gsap.registerPlugin(ScrollTrigger);


  $(".statsBannerCard__statistic").each(function(index, element) {
    var count = $(this),
      zero = {
        val: 0
      },
      num = count.data("number"),
      split = (num + "").split("."), // to cover for instances of decimals
      decimals = split.length > 1 ? split[1].length : 0;

    gsap.to(zero, {
      val: num,
      duration: 2,
      scrollTrigger: element,
      onUpdate: function() {
        count.text(zero.val.toFixed(decimals));
      }
    });
  });

});
.spacer{
  height: 100vh;
  background: lightblue;
}

.statsBanner{
  background: #F283D6;
  padding: 100px 0;
}

.statsBanner__intro{
  margin-bottom: 60px;
}

.statsBannerCard{
  /* visibility: hidden; */
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.0/ScrollTrigger.min.js"></script>

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">


<section class="spacer">
  Scroll down
</section>


<section class="statsBanner">
  <div class="container">

    <div class="row">
      <div class="col-12">
        <div class="statsBanner__intro text-center">
          <h2>Start counter when this section is in view.</h2>
        </div>
      </div>
    </div>

    <div class="row justify-content-evenly">


      <div class="col-12 col-sm-3">
        <div class="statsBannerCard text-center">
          <span class="statsBannerCard__statistic" data-number="145">145</span>
        </div>
      </div>

      <div class="col-12 col-sm-3">
        <div class="statsBannerCard text-center">
          <span class="statsBannerCard__statistic" data-number="Text">Text</span>
        </div>
      </div>

      <div class="col-12 col-sm-3">
        <div class="statsBannerCard text-center">
          <span class="statsBannerCard__statistic" data-number="$20,000">$20,000</span>
        </div>
      </div>

      <div class="col-12 col-sm-3">
        <div class="statsBannerCard text-center">
          <span class="statsBannerCard__statistic" data-number="60K+">60K+</span>
        </div>
      </div>



    </div>
  </div>
</section>