1

I'm using the following code and am trying to work out how to increment a number by say 10 or 100 (a user-specified amount) until it reaches the countTo value.

The code below is working fine but incrementing by 1 each time.

function countUp() {
    $('.countup.counter span.number').each(function() {
        var num = jQuery(this), 
        countFrom = num.attr("data-from"), 
        countTo = num.attr("data-count"), 
        countIncrement = num.attr("data-increment"), 
        countSpeed = num.attr("data-duration");
        var decimal = 0;
        if (countTo.indexOf(".") > 0) { 
            decimal = countTo.toString().split(".")[1].length; 
        }
        $({ countNum: countFrom}).animate({ countNum: countTo }, {
            duration: parseInt(countSpeed), easing:"swing", 
            step: function() {
                num.text(parseFloat(this.countNum).toFixed(decimal));
            }, complete: function() {
                num.text(this.countNum);
            }
        });
    });
}

So for the example below I'd like it to count 0...100...200...300...400...500...600...700...800...900...1000.45

<div class="counter"><span class="prefix">£</span><span class="number" data-increment="100" data-from="500" data-count="1000.45" data-duration="2000"></span><span class="suffix"></span></div>
user9099702
  • 109
  • 8

1 Answers1

0

Using .animate isn't the same as a for (let i = countFrom; i<countTo; i+=countIncrement) so you can't increment by an amount over time.

You either increment by an amount (as in the for above) or you animate over time.

Having said that, you can provide the output in increments, using this answer:

var val = parseFloat(this.countNum);
num.text((Math.ceil(val/countIncrement)*countIncrement).toFixed(decimal));

Giving updated snippet:

$('.counter span.number').each(function() {
  var num = jQuery(this), 
      countFrom = num.attr("data-from"), 
      countTo = num.attr("data-count"), 
      countIncrement = num.attr("data-increment"), 
      countSpeed = num.attr("data-duration");
  var decimal = 0;
  if (countTo.indexOf(".") > 0) { 
    decimal = countTo.toString().split(".")[1].length; 
  }
  $({ countNum: countFrom }).animate({ countNum: countTo }, {
    duration: parseInt(countSpeed), 
    easing:"swing", 
    step: function() {
      var val = parseFloat(this.countNum);
        num.text((Math.ceil(val/countIncrement)*countIncrement).toFixed(decimal));
    }, complete: function() {
      num.text(this.countNum);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="counter">
  <span class="prefix">£</span>
  <span class="number" data-increment="50" data-from="500" data-count="1000.45" data-duration="2000"></span>
  <span class="suffix"></span>
</div>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
  • Thanks! I did try something like this but was using parseFloat instead of Math.ceil which just ignored the increment value. I wonder why? e.g. num.text((parseFloat(val/countIncrement/countIncrement) * countIncrement).toFixed(decimal)); – user9099702 Mar 16 '23 at 11:44
  • 1
    You need to parseFloat *only* on the inner value. Using on a float calculation does nothing or is too late - ie `parseFloat(txt) / 5` not `parseFloat(txt/5)`. Ideally parseFloat when you first retrieve the data: `parseFloat(num.attr("data-from"))` then you don't need to worry about numerics after that (note: using `num.data("from")` will give you a numeric without needing any parseFloats. – freedomn-m Mar 16 '23 at 11:53