利用tween.js算法生成缓动效果

  在讲tween类之前,不得不提的是贝塞尔曲线了。首先,贝塞尔曲线是指依据四个位置任意的点坐标绘制出的一条光滑曲线。它在作图工具或动画中中运用得比较多,例如PS中的钢笔工具,firework中的画笔等等。无论运用在哪里,它们的原理都是一样的。同样,在用js实现运动效果时,我们也可以利用贝塞尔曲线来实现不同的特效,而tween.js就是一个封装好的计算辅助算法。你可以通过连续输入多个值,然后利用贝塞尔曲线公式输出不同的值,最终形成了一条光滑的曲线。因为一条曲线上的值的不一样的,所以我们可以利用曲线的特性创造出不同的效果。

  tween.js封装了多种效果的计算方法,我们可以利用里面的公式或者自己重写方法。以下是源代码,可根据自己的需要增删使用。 

  1 // Tween类
  2 var Tween = {
  3     Linear: function(t,b,c,d){ return c*t/d + b; },
  4     Quad: {
  5         easeIn: function(t,b,c,d){
  6             return c*(t/=d)*t + b;
  7         },
  8         easeOut: function(t,b,c,d){
  9             return -c *(t/=d)*(t-2) + b;
 10         },
 11         easeInOut: function(t,b,c,d){
 12             if ((t/=d/2) < 1) return c/2*t*t + b;
 13             return -c/2 * ((--t)*(t-2) - 1) + b;
 14         }
 15     },
 16     Cubic: {
 17         easeIn: function(t,b,c,d){
 18             return c*(t/=d)*t*t + b;
 19         },
 20         easeOut: function(t,b,c,d){
 21             return c*((t=t/d-1)*t*t + 1) + b;
 22         },
 23         easeInOut: function(t,b,c,d){
 24             if ((t/=d/2) < 1) return c/2*t*t*t + b;
 25             return c/2*((t-=2)*t*t + 2) + b;
 26         }
 27     },
 28     Quart: {
 29         easeIn: function(t,b,c,d){
 30             return c*(t/=d)*t*t*t + b;
 31         },
 32         easeOut: function(t,b,c,d){
 33             return -c * ((t=t/d-1)*t*t*t - 1) + b;
 34         },
 35         easeInOut: function(t,b,c,d){
 36             if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
 37             return -c/2 * ((t-=2)*t*t*t - 2) + b;
 38         }
 39     },
 40     Quint: {
 41         easeIn: function(t,b,c,d){
 42             return c*(t/=d)*t*t*t*t + b;
 43         },
 44         easeOut: function(t,b,c,d){
 45             return c*((t=t/d-1)*t*t*t*t + 1) + b;
 46         },
 47         easeInOut: function(t,b,c,d){
 48             if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
 49             return c/2*((t-=2)*t*t*t*t + 2) + b;
 50         }
 51     },
 52     Sine: {
 53         easeIn: function(t,b,c,d){
 54             return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
 55         },
 56         easeOut: function(t,b,c,d){
 57             return c * Math.sin(t/d * (Math.PI/2)) + b;
 58         },
 59         easeInOut: function(t,b,c,d){
 60             return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
 61         }
 62     },
 63     Expo: {
 64         easeIn: function(t,b,c,d){
 65             return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
 66         },
 67         easeOut: function(t,b,c,d){
 68             return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
 69         },
 70         easeInOut: function(t,b,c,d){
 71             if (t==0) return b;
 72             if (t==d) return b+c;
 73             if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
 74             return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
 75         }
 76     },
 77     Circ: {
 78         easeIn: function(t,b,c,d){
 79             return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
 80         },
 81         easeOut: function(t,b,c,d){
 82             return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
 83         },
 84         easeInOut: function(t,b,c,d){
 85             if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
 86             return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
 87         }
 88     },
 89     Elastic: {
 90         easeIn: function(t,b,c,d,a,p){
 91             if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
 92             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
 93             else var s = p/(2*Math.PI) * Math.asin (c/a);
 94             return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
 95         },
 96         easeOut: function(t,b,c,d,a,p){
 97             if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
 98             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
 99             else var s = p/(2*Math.PI) * Math.asin (c/a);
100             return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
101         },
102         easeInOut: function(t,b,c,d,a,p){
103             if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
104             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
105             else var s = p/(2*Math.PI) * Math.asin (c/a);
106             if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
107             return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
108         }
109     },
110     Back: {
111         easeIn: function(t,b,c,d,s){
112             if (s == undefined) s = 1.70158;
113             return c*(t/=d)*t*((s+1)*t - s) + b;
114         },
115         easeOut: function(t,b,c,d,s){
116             if (s == undefined) s = 1.70158;
117             return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
118         },
119         easeInOut: function(t,b,c,d,s){
120             if (s == undefined) s = 1.70158; 
121             if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
122             return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
123         }
124     },
125     Bounce: {
126         easeIn: function(t,b,c,d){
127             return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
128         },
129         easeOut: function(t,b,c,d){
130             if ((t/=d) < (1/2.75)) {
131                 return c*(7.5625*t*t) + b;
132             } else if (t < (2/2.75)) {
133                 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
134             } else if (t < (2.5/2.75)) {
135                 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
136             } else {
137                 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
138             }
139         },
140         easeInOut: function(t,b,c,d){
141             if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
142             else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
143         }
144     }
145 };
点击展开源代码

  下载地址:http://pan.baidu.com/s/1sjQdWQx

  这个算法可以用在很多地方,如果滚动条的移动,物块的移动或各种渐变等等。今天我就用物块移动demo的例子来讲讲这个辅助计算类怎么用吧,首先我们得创建一个定时器或者函数,一下是我常用的方法。

 1             //利用tween.js返回特殊值,生成不同效果
 2             function tweenFn(obj,attr,value,endFn){
 3                 var timer = null;
 4                 var start = 0;        //开始位置
 5 //                var value = value        //改变值大小
 6                 var t = 0;                //从0步开始
 7                 var endT = 30;            //结束步数
 8                 clearInterval(timer);
 9                 timer = setInterval(function(){
10                             t++;
11                             if(t>endT){
12                                 clearInterval(timer);
13                                 endFn && endFn();//回调函数存在则返回
14                                 return;
15                             };
16                         obj.style[attr] = Tween.Cubic.easeInOut(t,start,value,endT)+"px";
17                 },30);
18             }

  函数说明:obj,绑定执行的对象;

       attr,改变的属性值;

       value,改变值的大小;

       endFn,执行完毕的回调函数,没有可不写;

       start,属性初始值;

       t,endT,执行的步数,可理解为分多少次执行完。

      函数第十六行中Tween.Cubic.easeInOut(...)为调用tween.js中的方法,可根据实际需求修改Cubic或easeInOut的值。我把里面所有的方法列表如下:

Linear

线性匀速变化

Quad

easeIn

easeOut

easeInOut  
二次方缓动 Expo

easeIn

easeOut

easeInOut
指数曲线缓动
Cubic

easeIn

easeOut

easeInOut  
三次方缓动 Circ  easeIn

easeOut

easeInOut  
圆周曲线缓动
Quart  easeIn

easeOut

easeInOut  
四次方缓动 Elastic  easeIn

easeOut

easeInOut  
弹性伸缩缓动
Quint

easeIn

easeOut

easeInOut   
五次方缓动 Back  easeIn

easeOut

easeInOut  
返回缓动
Sine  easeIn

easeOut

easeInOut  
正弦曲线缓动 Bounce  easeIn

easeOut

easeInOut  
跳动缓动

  请查看本人写的Demo,里面包含了所有效果:www.chengguanhui.com/demos/tween/index.html

 

posted @ 2015-07-21 17:17  小辉_Ray  阅读(4444)  评论(0编辑  收藏  举报