用原生js封装运动框架

//先封装获取非行间样式的函数
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运动系列,原生js运动框架)