Search code examples
javascriptjqueryanimationjquery-animatecounter

How do I start my scroll counter again if the user scrolls back to the section?


I've made a animated counter that starts counting once you scroll into view. How do I restart the counter when a user scrolls back to the counter?

I'm sure it will be something simple that I don't know yet. Thanks for any help given, much appreciated.

var a = 0;

$(window).scroll(function() {
  var oTop = $('#counter').offset().top - window.innerHeight;
  
  if (a == 0 && $(window).scrollTop() > oTop) {
    $('.counter-value').each(function() {
      var $this = $(this),
        countTo = $this.attr('data-count');
        
      $({
        countNum: $this.text()
      }).animate({
        countNum: countTo
      }, {
        duration: 2000,
        easing: 'swing',
        step: function() {
          $this.text(Math.floor(this.countNum));
        },
        complete: function() {
          $this.text(this.countNum);
          //alert('finished');
        }
      });
    });

    a = 1;
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<section class="numbers">
  <div class="container" id="counter">
    <h6 class="red-title">BY THE NUMBERS</h6>
    <h2 class="stats-heading">We’ll always measure up to your expectations</h2>

    <div class="numbers-box">
      <h1 class="counter-value" data-count="50">0</h1>
      <h6>years of experience</h6>
    </div>

    <div class="numbers-box">
      <h1 class="counter-value" data-count="37">0</h1>
      <h6>countires supplied</h6>
    </div>

    <div class="numbers-box">
      <h1 class="counter-value" data-count="128">0</h1>
      <h6>group automation employees</h6>
    </div>
  </div>
</section>


Solution

  • How's this?

    https://codepen.io/jonolayton/pen/MWmLJze

    You'll probably want to fiddle with it to make it fire accurately... I've edited some of the CSS in CodePen too, so check it on there.

    Also - it only restarts when the counting has already stopped. Otherwise it could get really annoying.

    var runAlready;
    var counting;
    
    function startCounter(a) {
      runAlready = true;
      counting = true;
      $('.counter-value').each(function() {
        var $this = $(this);
        $this.text(a);
        countTo = $this.attr('data-count');
        $({
          countNum: $this.text()
        }).animate({
          countNum: countTo
        }, 
        {
          duration: 2000,
          easing: 'swing',
          step: function() {
            $this.text(Math.floor(this.countNum));
          },
          complete: function() {
            $this.text(this.countNum);
            counting = false;
          }
        });
      })
    }
    
    $(window).scroll(function() {
      var oTop = $('#counter').offset().top;
      var a = 0;
      if (!runAlready && $(window).scrollTop() > oTop || !counting && $(window).scrollTop() < oTop) {
        startCounter(a);
      }
    });