asciiblaster

- draw irc art in your web browser
git clone git://git.acid.vegas/asciiblaster.git
Log | Files | Refs | Archive | README

oktween.js (4680B)

      1 /*
      2   oktween.add({
      3     obj: el.style,
      4     units: "px",
      5     from: { left: 0 },
      6     to: { left: 100 },
      7     duration: 1000,
      8     easing: oktween.easing.circ_out,
      9     update: function(obj){
     10       console.log(obj.left)
     11     }
     12     finished: function(){
     13       console.log("done")
     14     }
     15   })
     16 */
     17 
     18 var oktween = (function(){
     19   var oktween = {}
     20   var tweens = oktween.tweens = []
     21   var last_t = 0
     22   var id = 0
     23   oktween.speed = 1
     24   oktween.raf = requestAnimationFrame
     25   oktween.add = function(tween){
     26     tween.id = id++
     27     tween.obj = tween.obj || {}
     28     if (tween.easing) {
     29       if (typeof tween.easing == "string") {
     30         tween.easing = oktween.easing[tween.easing]
     31       }
     32     }
     33     else {
     34       tween.easing = oktween.easing.linear
     35     }
     36     if (! ('from' in tween) && ! ('to' in tween)) {
     37       tween.keys = []
     38     }
     39     else if (! ('from' in tween) ) {
     40       tween.from = {}
     41       tween.keys = Object.keys(tween.to)
     42       tween.keys.forEach(function(prop){
     43         tween.from[prop] = parseFloat(tween.obj[prop])
     44       })
     45     }
     46     else {
     47       tween.keys = Object.keys(tween.from)
     48     }
     49     tween.delay = tween.delay || 0
     50     tween.start = last_t + tween.delay
     51     tween.done = false
     52     tween.after = tween.after || []
     53     tween.then = function(fn){ tween.after.push(fn); return tween }
     54     tween.cancel = function(){
     55       var index = tweens.indexOf(tween)
     56       if (index != -1) tweens.splice(index, 1)
     57       tween.obj = null
     58       tween.after = null
     59       tween.done = null
     60     }
     61     tween.tick = 0
     62     tween.skip = tween.skip || 1
     63     tween.dt = 0
     64     tweens.push(tween)
     65     return tween
     66   }
     67   oktween.update = function(t) {
     68     oktween.raf(oktween.update)
     69     last_t = t * oktween.speed
     70     if (tweens.length == 0) return
     71     var done = false
     72     tweens.forEach(function(tween, i){
     73       var dt = Math.min(1.0, (t - tween.start) / tween.duration)
     74       tween.tick++
     75       if (dt < 0 || (dt < 1 && (tween.tick % tween.skip != 0))) return
     76       var ddt = tween.dt = tween.easing(dt)
     77       tween.keys.forEach(function(prop){
     78         val = lerp( ddt, tween.from[prop], tween.to[prop] )
     79         if (tween.round) val = Math.round(val)
     80         if (tween.units) val = (Math.round(val)) + tween.units
     81         tween.obj[prop] = val
     82       })
     83       tween.update && tween.update(tween.obj, dt)
     84       if (dt == 1) {
     85         tween.finished && tween.finished(tween)
     86         if (tween.after.length) {
     87           var twn = tween.after.shift()
     88           twn.obj = twn.obj || tween.obj
     89           twn.after = tween.after
     90           oktween.add(twn)
     91         }
     92         if (tween.loop) {
     93           tween.start = t + tween.delay
     94         }
     95         else {
     96           done = tween.done = true
     97         }
     98       }
     99     })
    100     if (done) {
    101       tweens = tweens.filter(function(tween){ return ! tween.done })
    102     }
    103   }
    104   function lerp(n,a,b){ return (b-a)*n+a }
    105 
    106   // requestAnimationFrame(oktween.update)
    107 
    108   oktween.easing = {
    109     linear: function(t){
    110       return t
    111     },
    112     circ_out: function(t) {
    113       return Math.sqrt(1 - (t = t - 1) * t)
    114     },
    115     circ_in: function(t){
    116       return -(Math.sqrt(1 - (t * t)) - 1)
    117     },
    118     circ_in_out: function(t) {
    119       return ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1)
    120     },
    121     quad_in: function(n){
    122       return Math.pow(n, 2)
    123     },
    124     quad_out: function(n){
    125       return n * (n - 2) * -1
    126     },
    127     quad_in_out: function(n){
    128       n = n * 2
    129       if(n < 1){ return Math.pow(n, 2) / 2 }
    130       return -1 * ((--n) * (n - 2) - 1) / 2
    131     },
    132     cubic_bezier: function (mX1, mY1, mX2, mY2) {
    133       function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
    134       function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
    135       function C(aA1)      { return 3.0 * aA1; }
    136 
    137       // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
    138       function CalcBezier(aT, aA1, aA2) {
    139         return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;
    140       }
    141 
    142       // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
    143       function GetSlope(aT, aA1, aA2) {
    144         return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
    145       }
    146 
    147       function GetTForX(aX) {
    148         // Newton raphson iteration
    149         var aGuessT = aX;
    150         for (var i = 0; i < 10; ++i) {
    151           var currentSlope = GetSlope(aGuessT, mX1, mX2);
    152           if (currentSlope == 0.0) return aGuessT;
    153           var currentX = CalcBezier(aGuessT, mX1, mX2) - aX;
    154           aGuessT -= currentX / currentSlope;
    155         }
    156         return aGuessT;
    157       }
    158 
    159       return function(aX) {
    160         if (mX1 == mY1 && mX2 == mY2) return aX; // linear
    161         return CalcBezier(aX, mY1, mY2);
    162       }
    163     }
    164   }
    165   
    166   return oktween
    167 })()