Search code examples
javascripthtmljqueryprop

jQuery prop counter with updated iterations


I've used the jQuery prop-method with the counter-property to create an animation that counts from 0 to the value from the .count-string through an each-loop.

This works as intended, but I would like to increase this value by 3, 2 and 1 respectively, set by the variables cowsIncrement, sheepIncrement and pigsIncrement. Each increment has to happen in 3, 2 and 1-second intervals as well (similiar to the increment value), and it has to run infinitely with the same animation. How would I go about doing this?

Can somebody provide solution from jQuery/Vanilla Js?

// #count1
let cowsIncrement = 3;

// #count2
let sheepIncrement = 2;

// #count3
let pigsIncrement = 1;

$('.count').each(function() {
  $(this).prop('Counter', 0).animate({
    Counter: $(this).text()
  }, {
    duration: 1500,
    easing: 'swing',
    step: function(now) {
      $(this).text(Math.ceil(now).toLocaleString('de-DE'));
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<div class="count" id="count1">3000</div><span>cows</span>
<div class="count" id="count2">2000</div><span>sheep</span>
<div class="count" id="count3">1000</div><span>pigs</span>


Solution

  • Use an object that maps element IDs to the corresponding increments. Then use a complete: function that starts repeated animations with 3-second durations and the appropriate increment.

    The key to getting the animations to repeat at the end is to use a named function, so it can call itself in the complete: option.

    // #count1
    let cowsIncrement = 3;
    
    // #count2
    let sheepIncrement = 2;
    
    // #count3
    let pigsIncrement = 1;
    
    const increments = {
      count1: cowsIncrement,
      count2: sheepIncrement,
      count3: pigsIncrement
    };
    
    $('.count').each(function() {
      $(this).prop('Counter', 0).animate({
        Counter: $(this).text()
      }, {
        duration: 1500,
        easing: 'swing',
        step: function(now) {
          $(this).text(Math.ceil(now).toLocaleString('de-DE'));
        },
        complete: repeatAnimation
      });
    });
    
    function repeatAnimation() {
      let increment = increments[this.id];
      let current = Number($(this).prop('Counter'));
      console.log(this.id, current, increment);
      $(this).animate({
          Counter: current + increment
      }, {
        duration: 3000,
        easing: 'swing',
        step: function(now) {
          $(this).text(Math.ceil(now).toLocaleString('de-DE'));
        },
        complete: repeatAnimation
      });
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    
    <div class="count" id="count1">3000</div><span>cows</span>
    <div class="count" id="count2">2000</div><span>sheep</span>
    <div class="count" id="count3">1000</div><span>pigs</span>