网络编程
位置:首页>> 网络编程>> JavaScript>> javascript 45种缓动效果(二)

javascript 45种缓动效果(二)

作者:司徒正美 来源:司徒正美blog 发布时间:2009-09-19 18:53:00 

标签:JavaScript,缓动,Tween,特效,函数

阅读上一篇:javascript 45种缓动效果(一)

这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化。成品的效果非常惊人逆天。走过路过不要错过。

好了,打诨到此为止。普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公式。我见过两套缓动公式,一套是早期Robert Penner大神的缓动公式,内置到tween类中,不过现在人们越来越推荐tweenlite这个新秀了。另一套是script.aculo.us与mootools里面的,由于mootools可称之为prototype的升级版,script.aculo.us则是基于prototype,我们就把它们并称为prototype流派。与flash流派最大的不同是,它们封装得更好,并只需传入一个参数(0~1的小数),并且拥有严密的队列机制来调用各种回调函数。如在回调函数设置元素的长宽,就弄成Scale特效,利用它我们进一步制作SlideUp,SlideDown,Squish等复合特效。

我们先来看flash流派的缓动公式,它们基本都有如下四个参数。

  • t:timestamp,指缓动效果开始执行到当前帧开始执行时经过的时间段,单位ms

  • b:beginning position,起始位置

  • c:change,要移动的距离,就是终点位置减去起始位置。

  • d: duration ,缓和效果持续的时间。

我们把这四个参数传入Robert Penner大神的缓动公式,它就会计算出当前帧物体移动的位置。我们对比原来的函数来改写。

var transition = function(el){    transition.linear = function(t,b,c,d){ return c*t/d + b; };//免费提供一个缓动公式(匀速运动公式)    el.style.position = "absolute";    var options = arguments[1] || {},    begin =  getCoords(el).left,//开始位置    change = parseFloat(getStyle(_("taxiway"),"width")) - parseFloat(getStyle(el,"width")),//要移动的距离    duration = options.duration || 500,//缓动效果持续时间    ease = options.ease || transition.linear,//要使用的缓动公式    end = begin + change,//结束位置    startTime = new Date().getTime();//开始执行的时间    (function(){      setTimeout(function(){        var newTime = new Date().getTime(),//当前帧开始的时间        timestamp = newTime - startTime;//逝去时间        el.style.left = ease(timestamp,begin,change,duration) + "px";//移动        if(duration <= timestamp){          el.style.left = end + "px";        }else{          setTimeout(arguments.callee,25);//每移动一次停留25毫秒        }      },25)    })()  }

接着是各种缓动公式大阅兵,共分为十一大类,除了linear。其他类又分为三种。

  • easeIn方法控制补间如何从开始到最高速度。

  • easeOut 方法控制补间减速并停在目标位置

  • easeInOut方法同时控制上述两者。

具体公式见下面(共31种)。

相关阅读:JavaScript Tween算法及缓动效果

//***********@author:Robert Penner and cloudgamer************* //http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html  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){        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;        if (!a || a < Math.abs(c)) { a=c; var s=p/4; }        else var 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){        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;        if (!a || a < Math.abs(c)) { a=c; var s=p/4; }        else var 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){        if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);        if (!a || a < Math.abs(c)) { a=c; var s=p/4; }        else var 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 (s == undefined) s = 1.70158;        return c*(t/=d)*t*((s+1)*t - s) + b;      },      easeOut: function(t,b,c,d,s){        if (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 (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;      }    }  }

<div id="taxiway">  <div id="move" onclick="transition(this,{ease:Tween.Bounce.easeOut})"></div> </div>

效果演示请看下一页

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com