javascript的缓动效果(第2部分)

原文地址:http://www.cnblogs.com/rubylouvre/archive/2009/09/17/1567607.html

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

好了,打诨到此为止。普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公式。我见过两套缓动公式,一套是早期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种)。

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

但我不喜欢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)
     })()
   }
参数 类型 说明
el element 必需,为页面元素
begin number 必需,开始的位置
change number 必需,要移动的距离
duration number 可选,缓动效果持续时间,默认是500ms。建议取300~1000ms。
field string 必需,要发生变化的样式属性。请在top,left,bottom,right,width与height中选择。
ftp number 可选,每秒进行多少帧动画,默认50帧,保证流畅播放。一些参考资料,日本动画1秒36帧,中国卡通24帧,赛车游戏60帧。
ease function 必需,缓动公式,参数为0~1之间的数。可参考我下面给出的45条公式。
onStart function 可选,在开始时执行。
onEnd function 可选,在结束时执行。

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

除了这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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值