4

I have a count up code here:

HTML:

<div id="value">700</div>
<div id="value2">1000</div>

JavaScript:

function animateValue(id, start, end, duration) {
    var start= 0 ;
    var end = parseInt(document.getElementById(id).textContent, 10);
    var duration = 10000;
    var range = end - start;
    var current = start;
    var increment = end > start? 1 : -1;
    var stepTime = Math.abs(Math.floor(duration / range));
    var obj = document.getElementById(id);
    var timer = setInterval(function() {
        current += increment;
        obj.innerHTML = current;
        if (current == end) {
            clearInterval(timer);
        }
    }, stepTime);
}
animateValue("value2",0,0,0);
animateValue("value",0,0,0);

In this code numbers start from 0 to end with 10000ms duration. How can I set this duration be slower than this when it's close to the end?

For example:

Numbers: 0 To 100.

Duration : 50ms To 10ms.

Drew Gaynor
  • 8,292
  • 5
  • 40
  • 53
  • Your second question is just that, a second question. Please post a [new question](https://stackoverflow.com/questions/ask) for it. – Drew Gaynor Sep 23 '15 at 14:05
  • To clarify, do you want the numbers to count slower near the end of the sequence, but still have the whole counting process take the same amount of time? Like an "easing" effect? – Serlite Sep 23 '15 at 14:43
  • yes yes , like an easing effect,ease out or something else – Amir Hosein Navari Sep 23 '15 at 14:47

1 Answers1

13

Use some easing functions instead of incrementing at a constant rate.

Please note, however, that your total execution time will likely always be at least somewhat inaccurate due to the fact that each increment of the value takes some execution time which is not accounted for using this setTimeout approach. The problem is exacerbated by higher values.

//No easing
function constant (duration, range, current) {
  return duration / range;
}

//Linear easing
function linear (duration, range, current) {
  return ((duration * 2) / Math.pow(range, 2)) * current;
}

//Quadratic easing
function quadratic (duration, range, current) {
  return ((duration * 3) / Math.pow(range, 3)) * Math.pow(current, 2);
}

function animateValue(id, start, duration, easing) {
  var end = parseInt(document.getElementById(id).textContent, 10);
  var range = end - start;
  var current = start;
  var increment = end > start? 1 : -1;
  var obj = document.getElementById(id);
  var startTime = new Date();
  var offset = 1;
  var remainderTime = 0;
  
  var step = function() {
    current += increment;
    obj.innerHTML = current;
    
    if (current != end) {
      setTimeout(step, easing(duration, range, current));
    }
    else {
      console.log('Easing: ', easing);
      console.log('Elapsed time: ', new Date() - startTime)
      console.log('');
    }
  };
  
  setTimeout(step, easing(duration, range, start));
}

animateValue("value", 0, 10000, constant);
animateValue("value2", 0, 10000, linear);
animateValue("value3", 0, 10000, quadratic);
<div id="value">100</div>
<div id="value2">100</div>
<div id="value3">100</div>
Drew Gaynor
  • 8,292
  • 5
  • 40
  • 53