javascript的缓动效果.docx
《javascript的缓动效果.docx》由会员分享,可在线阅读,更多相关《javascript的缓动效果.docx(38页珍藏版)》请在冰点文库上搜索。
javascript的缓动效果
这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化。
成品的效果非常惊人逆天。
走过路过不要错过。
好了,打诨到此为止。
普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公式。
我见过两套缓动公式,一套是早期RobertPenner大神的缓动公式,内置到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:
beginningposition,起始位置
∙c:
change,要移动的距离,就是终点位置减去起始位置。
∙d:
duration,缓和效果持续的时间。
我们把这四个参数传入RobertPenner大神的缓动公式,它就会计算出当前帧物体移动的位置。
我们对比原来的函数来改写。
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种)。
showsource
Tween.Bounce.easeOut})">
但我不喜欢flash流派的缓动公式,为了使用prototype流派的缓动公式,我进一步改进与抽象化我的缓动函数
//******************@author:
司徒正美************
begin= options.begin,//开始位置
change=options.change,//变化量
field=options.field,//必须指定,基本上对top,left,width,height这个属性进行设置
ftp=options.ftp||50,
onStart=options.onStart||function(){},
onEnd=options.onEnd||function(){},
ease=options.ease,//要使用的缓动公式
onStart();
timestamp=newTime-startTime,//逝去时间
delta=ease(timestamp/duration);
el.style[field]=Math.ceil(begin+delta*change)+"px"
el.style[field]=end+"px";
onEnd();
setTimeout(arguments.callee,1000/ftp);
},1000/ftp)
参数
类型
说明
el
element
必需,为页面元素
begin
number
必需,开始的位置
change
必需,要移动的距离
duration
可选,缓动效果持续时间,默认是500ms。
建议取300~1000ms。
field
string
必需,要发生变化的样式属性。
请在top,left,bottom,right,width与height中选择。
ftp
可选,每秒进行多少帧动画,默认50帧,保证流畅播放。
一些参考资料,日本动画1秒36帧,中国卡通24帧,赛车游戏60帧。
ease
function
必需,缓动公式,参数为0~1之间的数。
可参考我下面给出的45条公式。
onStart
可选,在开始时执行。
onEnd
可选,在结束时执行。
prototype流派的缓动公式,只需一个参数(增至45种)
var tween={
easeInQuad:
function(pos){
return Math.pow(pos,2);
},
easeOutQuad:
return -(Math.pow((pos-1),2)-1);
easeInOutQuad:
if ((pos/=0.5)<1)return 0.5*Math.pow(pos,2);
return -0.5*((pos-=2)*pos-2);
easeInCubic:
return Math.pow(pos,3);
easeOutCubic:
return (Math.pow((pos-1),3)+1);
easeInOutCubic:
if ((pos/=0.5)<1)return 0.5*Math.pow(pos,3);
return 0.5*(Math.pow((pos-2),3)+2);
easeInQuart:
return Math.pow(pos,4);
easeOutQuart:
return -(Math.pow((pos-1),4)-1)
easeInOutQuart:
if ((pos/=0.5)<1)return 0.5*Math.pow(pos,4);
return -0.5*((pos-=2)*Math.pow(pos,3)-2);
easeInQuint:
return Math.pow(pos,5);
easeOutQuint:
return (Math.pow((pos-1),5)+1);
easeInOutQuint:
if ((pos/=0.5)<1)return 0.5*Math.pow(pos,5);
return 0.5*(Math.pow((pos-2),5)+2);
easeInSine:
return -Math.cos(pos*(Math.PI/2))+1;
easeOutSine:
return Math.sin(pos*(Math.PI/2));
easeInOutSine:
return (-.5*(Math.cos(Math.PI*pos)-1));
easeInExpo:
return (pos==0)?
0:
Math.pow(2,10*(pos-1));
easeOutExpo:
return (pos==1)?
1:
-Math.pow(2,-10*pos)+1;
easeInOutExpo:
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:
return -(Math.sqrt(1-(pos*pos))-1);
easeOutCirc:
return Math.sqrt(1-Math.pow((pos-1),2))
easeInOutCirc:
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:
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:
var s=1.70158;
return (pos)*pos*((s+1)*pos-s);
easeOutBack:
return (pos=pos-1)*pos*((s+1)*pos+s)+1;
easeInOutBack:
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:
return -1*Math.pow(4,-8*pos)*Math.sin((pos*6-1)*(2*Math.PI)/2)+1;
swingFromTo:
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:
return pos*pos*((s+1)*pos-s);
swingTo:
return (pos-=1)*pos*((s+1)*pos+s)+1;
bounce:
if (pos<(1/2.75)){
bouncePast:
return 2-(7.5625*(pos-=(1.5/2.75))*pos+.75);
return 2-(7.5625*(pos-=(2.25/2.75))*pos+.9375);
return 2-(7.5625*(pos-=(2.625/2.75))*pos+.984375);
easeFromTo:
easeFrom:
easeTo:
return Math.pow(pos,0.25);
linear:
return pos
sinusoidal:
return (-Math.cos(pos*Math.PI)/2)+0.5;
reverse:
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:
var pos=pos+(Math.random()-0.5)/5;
return tween.sinusoidal(pos<0?
pos>1?
pos);
wobble:
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:
return 1-(Math.cos(pos*4.5*Math.PI)*Math.exp(-pos*6));
none:
return 0
full:
return 1
doctypehtml>
.taxiway{
width:
800px;
height:
100px;
background:
#E8E8FF;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2