Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying easing to setTimeout delays, within a loop

Tags:

javascript

I am calling multiple setTimeout's within a javascript loop. The delay is currently set to increase by 200ms upon every iteration making the 'self.turnpages()' function fire every 200ms.

However I would like to apply some sort of easing to these variable delays so that as the loop begins to reach the last few iterations the delay gets further apart causing the function firing to slow down.

var self = this;    
var time = 0; 

for( var i = hide, len = diff; i < len; i++ ) {
                     (function(s){
                             setTimeout(function(){                    
                                        self.turnPages(s);                           
                             }, time);
                       })(i);                                  
             time = (time+200);
}

I am at a complete loss how to start with this.

Hopefully someone can help.

like image 459
gordyr Avatar asked Aug 22 '12 21:08

gordyr


2 Answers

This sounds like a job for Robert Penner's easing equations! You can download the original ActionScript 2.0 versions here (just remove the strong-typing on the parameters to port to JavaScript) and there's a good explanation of the parameters here.

Something like the following will do what you want (fiddle):

var time = 0;
var diff = 30;

var minTime = 0;
var maxTime = 1000;

// http://upshots.org/actionscript/jsas-understanding-easing
/*
    @t is the current time (or position) of the tween. This can be seconds or frames, steps, seconds, ms, whatever – as long as the unit is the same as is used for the total time [3].
    @b is the beginning value of the property.
    @c is the change between the beginning and destination value of the property.
    @d is the total time of the tween.
*/
function easeInOutQuad(t, b, c, d) {
  if ((t /= d / 2) < 1) return c / 2 * t * t + b;
  return -c / 2 * ((--t) * (t - 2) - 1) + b;
}

function easeOutQuad(t, b, c, d) {
  return -c * (t /= d) * (t - 2) + b;
}

function easeInQuad(t, b, c, d) {
  return c * (t /= d) * t + b;
}

for (var i = 0, len = diff; i <= len; i++) {
  (function(s) {
    setTimeout(function() {
      //self.turnPages(s);                           
      console.log("Page " + s + " turned");
    }, time);
  })(i);

  time = easeInOutQuad(i, minTime, maxTime, diff);
  console.log(time);
}
like image 149
net.uk.sweet Avatar answered Oct 13 '22 19:10

net.uk.sweet


2019 answer: You don't need to make your own loop timings, or deal with single character variables, just to run functions with easing. Here's a quick example using easy-ease from npm:


import ease from 'easy-ease';

ease({
  startValue: 1,
  endValue: 33,
  durationMs: 2000,
  onStep: function(value) {
    console.log(value)
  }
});
like image 23
mikemaccana Avatar answered Oct 13 '22 19:10

mikemaccana