Mark t
Mark t

Reputation: 95

Increment value in time

I am looking to increment the value of "time" with 0.01 each 10 miliseconds until it gets to the desired value. Right now it just increases it instantly to the conditioned value.

var time = 0;

function animate() {
  decreaseIncrement = -0.78;
  increaseIncrement = 0.78;

  if (
    (document.getElementById("but5").onclick = function () {
      if (time < increaseIncrement) {
        do {
          time += 0.01;
        } while (time < increaseIncrement);
      }
    })
  )
    if (
      (document.getElementById("but3").onclick = function () {
        if (decreaseIncrement < time) {
          do {
            time -= 0.01;
          } while (decreaseIncrement < time);
        }
      })
    )
      increaseIncrement = time + increaseIncrement;
  decreaseIncrement = time + decreaseIncrement;

}

https://jsfiddle.net/2epqg1wc/1/

Upvotes: 0

Views: 1018

Answers (2)

ibrahim tanyalcin
ibrahim tanyalcin

Reputation: 6491

You have 3 options:

  • requestAnimationFrame (rAF)
  • setTimeout/setInterval (sTo)
  • messageChannel

The first 2 options are more straightforward but they will lack the precision, because rAF fires every 17 milliseconds (assuming 60Hz) and sTO will fire at most 4ms after 4 successive recursions. Usually rAF is preferred over sTo because of better reliability in timing of firing these callbacks. Use sTO as a fallback if rAF is not supported.

Here is an implementation from a library for similar purposes:

var rafx = require("rafx");
rafx.async({ //create a ledger object to store values
   curr_time:0,
   desired:Math.random(),
   frames:0
}).animate(function(obj){ 
    //obj is the ledger above
    //increment obj.frames here if you want to
    return obj;
},).until(function(obj){
    obj.frames++;
    obj.curr_time = obj.frames * 17 / 10 * 0.01;
    return obj.curr_time >= obj.desired;
}).then(function(obj){
    console.log("sequence ended with values:" + JSON.stringify(obj));
});

You can copy paste the code above here and test it.

The last option uses MessageChannel to post message between ports, which gives extremely high precision because it is fired at the next event loop. You can combine this with performance.now to determine whether to increment your time or not.

Disclosure: I am the author of the aforementioned lib.

Upvotes: 1

marcelwgn
marcelwgn

Reputation: 979

You can solve that problem using setInterval which repeatedly runs a task every x milliseconds until you cancel it. Below code reduces the value to 0 in 0.01 steps with a step performed every 10 milliseconds.

var value = 1.0;
var decrement = 0.01;


function decreaseAnimation() {
  var interval = setInterval(() => {
    value -= decrement;
    console.log(value);
    if (value <= 0) {
      clearInterval(interval);
    }
  }, 10);
}

decreaseAnimation();

Upvotes: 1

Related Questions