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

javascript 45种缓动效果(二)(2)

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

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

但我不喜欢flash流派的缓动公式,为了使用prototype流派的缓动公式,我进一步改进与抽象化我的缓动函数

//******************@author : 司徒正美************  var transition = function(el){    el.style.position = "absolute";    var options = arguments[1] || {},    begin =  options.begin,//开始位置    change = options.change,//变化量    duration = options.duration || 500,//缓动效果持续时间    field = options.field,//必须指定,基本上对top,left,width,height这个属性进行设置    ftp = options.ftp || 50,    onStart = options.onStart || function(){},    onEnd = options.onEnd || function(){},    ease = options.ease,//要使用的缓动公式    end = begin + change,//结束位置    startTime = new Date().getTime();//开始执行的时间    onStart();    (function(){      setTimeout(function(){        var newTime = new Date().getTime(),//当前帧开始的时间        timestamp = newTime - startTime,//逝去时间        delta = ease(timestamp / duration);        el.style[field] = Math.ceil(begin + delta * change) + "px"        if(duration <= timestamp){          el.style[field] = end + "px";          onEnd();        }else{          setTimeout(arguments.callee,1000/ftp);        }      },1000/ftp)    })()  }

参数类型说明
elelement必需,为页面元素
beginnumber必需,开始的位置
changenumber必需,要移动的距离
durationnumber可选,缓动效果持续时间,默认是500ms。建议取300~1000ms。
fieldstring必需,要发生变化的样式属性。请在top,left,bottom,right,width与height中选择。
ftpnumber可选,每秒进行多少帧动画,默认50帧,保证流畅播放。一些参考资料,日本动画1秒36帧,中国卡通24帧,赛车游戏60帧。
easefunction必需,缓动公式,参数为0~1之间的数。可参考我下面给出的45条公式。
onStartfunction可选,在开始时执行。
onEndfunction可选,在结束时执行。

prototype流派的缓动公式,只需一个参数(增至45种)

var tween = {    easeInQuad: function(pos){      return Math.pow(pos, 2);    },    easeOutQuad: function(pos){      return -(Math.pow((pos-1), 2) -1);    },    easeInOutQuad: function(pos){      if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,2);      return -0.5 * ((pos-=2)*pos - 2);    },    easeInCubic: function(pos){      return Math.pow(pos, 3);    },    easeOutCubic: function(pos){      return (Math.pow((pos-1), 3) +1);    },    easeInOutCubic: function(pos){      if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,3);      return 0.5 * (Math.pow((pos-2),3) + 2);    },    easeInQuart: function(pos){      return Math.pow(pos, 4);    },    easeOutQuart: function(pos){      return -(Math.pow((pos-1), 4) -1)    },    easeInOutQuart: function(pos){      if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,4);      return -0.5 * ((pos-=2)*Math.pow(pos,3) - 2);    },    easeInQuint: function(pos){      return Math.pow(pos, 5);    },    easeOutQuint: function(pos){      return (Math.pow((pos-1), 5) +1);    },    easeInOutQuint: function(pos){      if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,5);      return 0.5 * (Math.pow((pos-2),5) + 2);    },    easeInSine: function(pos){      return -Math.cos(pos * (Math.PI/2)) + 1;    },    easeOutSine: function(pos){      return Math.sin(pos * (Math.PI/2));    },    easeInOutSine: function(pos){      return (-.5 * (Math.cos(Math.PI*pos) -1));    },    easeInExpo: function(pos){      return (pos==0) ? 0 : Math.pow(2, 10 * (pos - 1));    },    easeOutExpo: function(pos){      return (pos==1) ? 1 : -Math.pow(2, -10 * pos) + 1;    },    easeInOutExpo: function(pos){      if(pos==0) return 0;      if(pos==1) return 1;      if((pos/=0.5) < 1) return 0.5 * Math.pow(2,10 * (pos-1));      return 0.5 * (-Math.pow(2, -10 * --pos) + 2);    },    easeInCirc: function(pos){      return -(Math.sqrt(1 - (pos*pos)) - 1);    },    easeOutCirc: function(pos){      return Math.sqrt(1 - Math.pow((pos-1), 2))    },    easeInOutCirc: function(pos){      if((pos/=0.5) < 1) return -0.5 * (Math.sqrt(1 - pos*pos) - 1);      return 0.5 * (Math.sqrt(1 - (pos-=2)*pos) + 1);    },    easeOutBounce: function(pos){      if ((pos) < (1/2.75)) {        return (7.5625*pos*pos);      } else if (pos < (2/2.75)) {        return (7.5625*(pos-=(1.5/2.75))*pos + .75);      } else if (pos < (2.5/2.75)) {        return (7.5625*(pos-=(2.25/2.75))*pos + .9375);      } else {        return (7.5625*(pos-=(2.625/2.75))*pos + .984375);      }    },    easeInBack: function(pos){      var s = 1.70158;      return (pos)*pos*((s+1)*pos - s);    },    easeOutBack: function(pos){      var s = 1.70158;      return (pos=pos-1)*pos*((s+1)*pos + s) + 1;    },    easeInOutBack: function(pos){      var s = 1.70158;      if((pos/=0.5) < 1) return 0.5*(pos*pos*(((s*=(1.525))+1)*pos -s));      return 0.5*((pos-=2)*pos*(((s*=(1.525))+1)*pos +s) +2);    },    elastic: function(pos) {      return -1 * Math.pow(4,-8*pos) * Math.sin((pos*6-1)*(2*Math.PI)/2) + 1;    },    swingFromTo: function(pos) {      var s = 1.70158;      return ((pos/=0.5) < 1) ? 0.5*(pos*pos*(((s*=(1.525))+1)*pos - s)) :        0.5*((pos-=2)*pos*(((s*=(1.525))+1)*pos + s) + 2);    },    swingFrom: function(pos) {      var s = 1.70158;      return pos*pos*((s+1)*pos - s);    },    swingTo: function(pos) {      var s = 1.70158;      return (pos-=1)*pos*((s+1)*pos + s) + 1;    },    bounce: function(pos) {      if (pos < (1/2.75)) {        return (7.5625*pos*pos);      } else if (pos < (2/2.75)) {        return (7.5625*(pos-=(1.5/2.75))*pos + .75);      } else if (pos < (2.5/2.75)) {        return (7.5625*(pos-=(2.25/2.75))*pos + .9375);      } else {        return (7.5625*(pos-=(2.625/2.75))*pos + .984375);      }    },    bouncePast: function(pos) {      if (pos < (1/2.75)) {        return (7.5625*pos*pos);      } else if (pos < (2/2.75)) {        return 2 - (7.5625*(pos-=(1.5/2.75))*pos + .75);      } else if (pos < (2.5/2.75)) {        return 2 - (7.5625*(pos-=(2.25/2.75))*pos + .9375);      } else {        return 2 - (7.5625*(pos-=(2.625/2.75))*pos + .984375);      }    },    easeFromTo: function(pos) {      if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,4);      return -0.5 * ((pos-=2)*Math.pow(pos,3) - 2);    },    easeFrom: function(pos) {      return Math.pow(pos,4);    },    easeTo: function(pos) {      return Math.pow(pos,0.25);    },    linear:  function(pos) {      return pos    },    sinusoidal: function(pos) {      return (-Math.cos(pos*Math.PI)/2) + 0.5;    },    reverse: function(pos) {      return 1 - pos;    },    mirror: function(pos, transition) {      transition = transition || tween.sinusoidal;      if(pos<0.5)        return transition(pos*2);      else        return transition(1-(pos-0.5)*2);    },    flicker: function(pos) {      var pos = pos + (Math.random()-0.5)/5;      return tween.sinusoidal(pos < 0 ? 0 : pos > 1 ? 1 : pos);    },    wobble: function(pos) {      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;    },    pulse: function(pos, pulses) {      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;    },    blink: function(pos, blinks) {      return Math.round(pos*(blinks||5)) % 2;    },    spring: function(pos) {      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));    },    none: function(pos){      return 0    },    full: function(pos){      return 1    }  }

效果演示:


除了这45条公式外,我们还可以制定自己的缓动公式。正如我在上面表格中提到, 它在运行过程是不执行回调函数时,但你们可以在运行框中看到,我可以实现一边移动一边记录点的坐标。这是怎样实现的呢? 我们只要把上面的缓动公式的任何一条塞进一个只有一个参数的函数就行了。当然此函数要有返回,供继续向下调用。以下就是一个模板:

var myTween = function(pos){ //缓动公式      var value = tween[ease](pos);      //***********这上面是固定的**************      indicator.style.display = "block";      marker.style.display = "block";      marker.style.left = Math.round((pos*200))+'px';      marker.style.bottom = Math.round(((value*200)-min)*factor)+'px';      label.innerHTML = Math.round((pos*200))+'px';      //************这下面是固定的*************      return value;    }

更多示例,不懂再留言给我。

<div class="taxiway">  <div class="move" onclick="transition(this,{field:'left',begin:parseFloat(getCoords(this).left),change:700,ease:tween.bouncePast})"></div> </div> <div class="taxiway">  <div class="move" onclick="transition(this,{field:'width',begin:parseFloat(getStyle(this,'width')),change:300,ease:tween.spring})"></div> </div>

0
投稿

猜你喜欢

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