欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

tweenjs缓动算法的使用实例分析

程序员文章站 2023-10-20 14:14:01
本文实例讲述了tweenjs缓动算法的使用。分享给大家供大家参考,具体如下: 这里的tweenjs不是依托于createjs的tewwnjs,而是一系列缓动算法集合。因为...

本文实例讲述了tweenjs缓动算法的使用。分享给大家供大家参考,具体如下:

这里的tweenjs不是依托于createjs的tewwnjs,而是一系列缓动算法集合。因为本身是算法,可以用在各个业务场景中,这也正是总结学习它的价值所在。tweenjs代码详情:

/*
 * tween.js
 * t: current time(当前时间);
 * b: beginning value(初始值);
 * c: change in value(变化量);
 * d: duration(持续时间)。
 * you can visit 'http://easings.net/zh-cn' to get effect
*/
var tween = {
  linear: function(t, b, c, d) {
    return c * t / d + b;
  },
  quad: {
    easein: function(t, b, c, d) {
      return c * (t /= d) * t + b;
    },
    easeout: function(t, b, c, d) {
      return -c *(t /= d)*(t-2) + b;
    },
    easeinout: function(t, b, c, d) {
      if ((t /= d / 2) < 1) return c / 2 * t * t + b;
      return -c / 2 * ((--t) * (t-2) - 1) + b;
    }
  },
  cubic: {
    easein: function(t, b, c, d) {
      return c * (t /= d) * t * t + b;
    },
    easeout: function(t, b, c, d) {
      return c * ((t = t/d - 1) * t * t + 1) + b;
    },
    easeinout: function(t, b, c, d) {
      if ((t /= d / 2) < 1) return c / 2 * t * t*t + b;
      return c / 2*((t -= 2) * t * t + 2) + b;
    }
  },
  quart: {
    easein: function(t, b, c, d) {
      return c * (t /= d) * t * t*t + b;
    },
    easeout: function(t, b, c, d) {
      return -c * ((t = t/d - 1) * t * t*t - 1) + b;
    },
    easeinout: function(t, b, c, d) {
      if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
      return -c / 2 * ((t -= 2) * t * t*t - 2) + b;
    }
  },
  quint: {
    easein: function(t, b, c, d) {
      return c * (t /= d) * t * t * t * t + b;
    },
    easeout: function(t, b, c, d) {
      return c * ((t = t/d - 1) * t * t * t * t + 1) + b;
    },
    easeinout: function(t, b, c, d) {
      if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
      return c / 2*((t -= 2) * t * t * t * t + 2) + b;
    }
  },
  sine: {
    easein: function(t, b, c, d) {
      return -c * math.cos(t/d * (math.pi/2)) + c + b;
    },
    easeout: function(t, b, c, d) {
      return c * math.sin(t/d * (math.pi/2)) + b;
    },
    easeinout: function(t, b, c, d) {
      return -c / 2 * (math.cos(math.pi * t/d) - 1) + b;
    }
  },
  expo: {
    easein: function(t, b, c, d) {
      return (t==0) ? b : c * math.pow(2, 10 * (t/d - 1)) + b;
    },
    easeout: function(t, b, c, d) {
      return (t==d) ? b + c : c * (-math.pow(2, -10 * t/d) + 1) + b;
    },
    easeinout: function(t, b, c, d) {
      if (t==0) return b;
      if (t==d) return b+c;
      if ((t /= d / 2) < 1) return c / 2 * math.pow(2, 10 * (t - 1)) + b;
      return c / 2 * (-math.pow(2, -10 * --t) + 2) + b;
    }
  },
  circ: {
    easein: function(t, b, c, d) {
      return -c * (math.sqrt(1 - (t /= d) * t) - 1) + b;
    },
    easeout: function(t, b, c, d) {
      return c * math.sqrt(1 - (t = t/d - 1) * t) + b;
    },
    easeinout: function(t, b, c, d) {
      if ((t /= d / 2) < 1) return -c / 2 * (math.sqrt(1 - t * t) - 1) + b;
      return c / 2 * (math.sqrt(1 - (t -= 2) * t) + 1) + b;
    }
  },
  elastic: {
    easein: function(t, b, c, d, a, p) {
      var s;
      if (t==0) return b;
      if ((t /= d) == 1) return b + c;
      if (typeof p == "undefined") p = d * .3;
      if (!a || a < math.abs(c)) {
        s = p / 4;
        a = c;
      } else {
        s = p / (2 * math.pi) * math.asin(c / a);
      }
      return -(a * math.pow(2, 10 * (t -= 1)) * math.sin((t * d - s) * (2 * math.pi) / p)) + b;
    },
    easeout: function(t, b, c, d, a, p) {
      var s;
      if (t==0) return b;
      if ((t /= d) == 1) return b + c;
      if (typeof p == "undefined") p = d * .3;
      if (!a || a < math.abs(c)) {
        a = c;
        s = p / 4;
      } else {
        s = p/(2*math.pi) * math.asin(c/a);
      }
      return (a * math.pow(2, -10 * t) * math.sin((t * d - s) * (2 * math.pi) / p) + c + b);
    },
    easeinout: function(t, b, c, d, a, p) {
      var s;
      if (t==0) return b;
      if ((t /= d / 2) == 2) return b+c;
      if (typeof p == "undefined") p = d * (.3 * 1.5);
      if (!a || a < math.abs(c)) {
        a = c;
        s = p / 4;
      } else {
        s = p / (2 *math.pi) * math.asin(c / a);
      }
      if (t < 1) return -.5 * (a * math.pow(2, 10* (t -=1 )) * math.sin((t * d - s) * (2 * math.pi) / p)) + b;
      return a * math.pow(2, -10 * (t -= 1)) * math.sin((t * d - s) * (2 * math.pi) / p ) * .5 + c + b;
    }
  },
  back: {
    easein: function(t, b, c, d, s) {
      if (typeof s == "undefined") s = 1.70158;
      return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    easeout: function(t, b, c, d, s) {
      if (typeof s == "undefined") s = 1.70158;
      return c * ((t = t/d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    easeinout: function(t, b, c, d, s) {
      if (typeof s == "undefined") s = 1.70158;
      if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
      return c / 2*((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    }
  },
  bounce: {
    easein: function(t, b, c, d) {
      return c - tween.bounce.easeout(d-t, 0, c, d) + b;
    },
    easeout: function(t, b, c, d) {
      if ((t /= d) < (1 / 2.75)) {
        return c * (7.5625 * t * t) + b;
      } else if (t < (2 / 2.75)) {
        return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
      } else if (t < (2.5 / 2.75)) {
        return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
      } else {
        return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
      }
    },
    easeinout: function(t, b, c, d) {
      if (t < d / 2) {
        return tween.bounce.easein(t * 2, 0, c, d) * .5 + b;
      } else {
        return tween.bounce.easeout(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
      }
    }
  }
}
math.tween = tween;

具体每种算法的操作实例,可以看大神张鑫旭的博客实例:http://www.zhangxinxu.com/study/201612/how-to-use-tween-js.html

当然,以上这些算法仅仅是一个状态,需要配合时间上的变化,才能实现缓动,这里使用的是requestanimationframe,具体代码好吧,也是拿来主义

(function() {
  var lasttime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for(var x = 0; x < vendors.length && !window.requestanimationframe; ++x) {
    window.requestanimationframe = window[vendors[x]+'requestanimationframe'];
    window.cancelanimationframe = window[vendors[x]+'cancelanimationframe']
                  || window[vendors[x]+'cancelrequestanimationframe'];
  }
  if (!window.requestanimationframe)
    window.requestanimationframe = function(callback, element) {
      var currtime = new date().gettime();
      var timetocall = math.max(0, 16 - (currtime - lasttime));
      var id = window.settimeout(function() { callback(currtime + timetocall); },
       timetocall);
      lasttime = currtime + timetocall;
      return id;
    };
  if (!window.cancelanimationframe)
    window.cancelanimationframe = function(id) {
      cleartimeout(id);
    };
}());

最后是简单的实例应用,很简单,

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>使用tweenjs</title>
  <style type="text/css">
  div {
    width: 100px;
    height: 100px;
    border: 1px solid red;
    text-align: center;
    line-height: 100px;
    position: absolute;
  }
  </style>
</head>
<body>
  <div id="test">
    这是测试
  </div>
  <script type="text/javascript" src="requestanimationframe.js"></script>
  <script type="text/javascript" src="tween.js"></script>
  <script type="text/javascript">
    var dom=document.getelementbyid("test");
  var t = 0,//开始时间
    b = 0,//开始位置
    c = 1000,//变化值
    d = 100;//持续时间
  var step = function() {
    var value = tween.bounce.easeout(t, b, c, d);
    dom.style.left = value + 'px';
    t++;
    if (t <= d) {
      // 继续运动
      requestanimationframe(step);
    } else {
      // 动画结束
    }
  };
  step();
  </script>
</body>
</html>

具体使用中,需要参数以及控制好结束条件即可。