//先封装获取非行间样式的函数
function getCssStyle(obj,styleName){
if(obj.currentStyle){
return obj.currnentStyle[styleName]
}else{
return computedStyle(obj,false)[styleName]
}
function startMove(obj,json,options){
var options=options || {}; //如果实参有传过来一个json则用它,若没有则定义一个空json;
var options.time=options.time || 1000; //如果传过来的options里面有给time值则使用参数,没有则默认值为1秒;
var options.easing=options.easing || 'linear'; //如果options里面有给easing值则用给的值,若无则默认值为'linear',就是匀速运动的意思,easing还有另外两个值为'ease-in'加速,'ease-out'减速;
clearInterval(obj.timer); //避免开启多个定时器,开启前先关闭定时器,用添加属性方法命名定时器,是为了避免多个对象共同使用一个定时器而互相影响;
var start={}; //起始值;
var distance={}; //需要运动的总距离;
for(name in json){
//json对象里面给的就是目的点,格式为 样式名:样式值;值不带单位;eg:{width:300,opacity:1,left:500};
start[name]=parseFloat(getCssStyle(obj,name)); //由于opacity值位小数则需要保留浮点数;
//由于有时候css样式里面了定位但是没有给left或right等样式值,所以在获取非行间样式的时候会获取不到,以下判断时如果没有设置这些样式的时候给一个默认值;
if(isNaN(start[name])){
switch(name){
case 'left':
start[name]=obj.offsetLeft;
break;
case 'top':
start[name]=obj.offsetTop;
break;
case 'right':
start[name]=obj.offsetRight;
break;
case 'bottom':
start[name]=obj.offsetBottom;
break;
}
}
distance[name]=json[name]-start[name];
};
var count=Math.floor(options.time/30); //此举求的是总次数,30为定时器设定的时间,相对比较稳定,建议不要改,用 总时间/走一次需要的时间 则得出总次数;
var n=0;
obj.timer=setInterval(function(){
n++;
for(name in json){
// 判断options里面的参数;
swith(options.easing){
case 'linear': //匀速;
var a=n/count; // 求的是目前走的次数占总次数的百分比;这个百分比也等于目前为止走的距离占总距离的百分比;
var cur=start+distance[name]*a; //求得是目前所在位置=起始值+总距离*(目前为止走的距离占总距离的百分比);
break;
case 'ease-in': //加速;
var a=n/count;
var cur=start+distance[name]*a*a*a; //加速就是刚开每次走的距离很短,每次走的距离逐渐增大,由于a<0;所以a*a*a比a小很多,所以刚开始很慢,但是a在增大,所以a*a*a也在增大,并且每次增大的值上一次增大的值大,当a*a*a增大的越来越快时每次走的距离也越来越大,随所以会加速;
break;
case 'ease-out': //减速;
var a=1-n/count; //由于n在递增,所以a在递减;
var cur=start+distance[name]*(1-a*a*a); //递减就是刚开始每次走的距大,每次走的距离逐渐减小,有与a在递减,则a*a*a也在递减,则1-a*a*a在递增,由于a*a*a递减的速度在增加,则1-a*a*a递增的速度在递减,所以每次走的距离在减小,这样为减速;
break;
}
if(name=='opacity'){ //由于透明度没有单位并且需要做兼容,所以需要另外判断;
obj.style.opacity=cur;
obj.style.filter=alpha(opacity=cur*100);
}else{
obj.style[name]=cur+'px';
}
if(n==count){
clearInterval(obj.timer); //当次数走完时关闭定时器;
options.complete&&options.complete(); //判断有无参数complete,complete值为函数,若有,则在运动函数完后执行此函数;
}
}
},30)
//调用方法;
eg:startMove(obj,{'width':200,'left':300,'opacity':0.8},{time:2000,complete:function(){
alert('运动完执行此函数');
});
//注意实参json对象里面的name和值;
用原生js封装运动框架
最新推荐文章于 2022-06-19 18:21:14 发布