自己实现js运动框架的一些心得

以前学了js的动画效果,当时看了别人的实现思路,以为自己听懂了,然后没太管,感觉太简单,但是这次做的一个项目中要用到动画效果,想着如果自己都手写一下就太麻烦了,于是想着自己实现一下这个完美运动框架,但是实现的过程中发现,其实没有那么简单,要写一个完美运动框架,那么他就要适合改变各种属性,那么他的参数必须有两个,一个是要改变的元素,第二个是要改变的属性,为了实现多个属性同时运动,我们的第二个参数需要是JSON格式的数据,第三个参数可以是一个回调函数,就是当我们达到目标值后,要执行的函数,看就是下面这个样子

function startMove (obj, json, fn) {
}

代码中要获取一个元素的属性值,需要有这样的一个函数

function getStyle (obj, attr) {
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    } else {
        return getComputedStyle(obj, false)[attr];
    }
}

这里关于

obj.currentStyle和getComputedStyle可以参考下面这篇文章

张鑫旭写的获取元素CSS值之getComputedStyle方法熟悉这篇文章,
看了之后会有一个很好的理解,我理解大概就是这么个意思
getComputedStyle是可以把一个元素所有的样式获取出来;而元素的style只能获取到元素的style属性里面的值,如果元素的样式是外联的,就没办法获取了。

currentStyle是ie出的一个产物,作用和getComputedStyle一样


接着又回过头来讲我们运动框架,先上一般别人的代码

function startMove(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function (){
        var bStop = true;  

        //这一次运动就结束了——所有的值都到达了            
        for(var attr in json) {

            //1.取当前的值
            var iCur = 0;

            if(attr == 'opacity') {
               iCur = parseInt(parseFloat(getStyle(obj, attr))*100);
            } else {
               iCur = parseInt(getStyle(obj, attr));
            }

            //2.算速度
            var iSpeed = (json[attr]-iCur)/8;

            iSpeed = iSpeed > 0?Math.ceil(iSpeed):Math.floor(iSpeed);

           //3.检测停止
           if(iCur!=json[attr]) {
               bStop=false;
            }

           if(attr=='opacity') {
               obj.style.filter='alpha(opacity:'+(iCur+iSpeed)+')';
               obj.style.opacity=(iCur+iSpeed)/100;
           } else {
               obj.style[attr]=iCur+iSpeed+'px';
           }

        }

        if(bStop) {
           clearInterval(obj.timer);

           if(fn){
              fn();
           }
        }

    }, 30)
}

用起来,是没有问题,可是元素要改变的属性如果是opacity的话,他就必须要传入0-100之间的值,这与我们平时写的opacity的值不一样,所以我自己写了一个

function startMove (obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function  () {
        var bStop = true,
            cur,
            speed;

        for (var attr in json) {
        if (attr === "opacity") {
            cur = parseInt((getStyle(obj, attr))*100);
         //让json[attr]和cur有朝一日能相等
        speed =  (parseInt(json[attr]*100) - cur)/8;
    } else {
            cur = parseInt(getStyle(obj, attr));
            speed =  (json[attr] - cur)/8;
    }

    speed = speed > 0?Math.ceil(speed):Math.floor(speed);

        if (cur != json[attr]) {
            bStop = false;
        }   

        if (attr === "opacity") {
            obj.style.opacity = (cur + speed)/100;
        } else {
            obj.style[attr] = cur + speed + "px";
        }                   
    }

    if(bStop) {
        clearInterval(obj.timer);
        if (fn) {
            fn();
        }
    }
  }, 1000);
}

我自己写的这个如果属性是opacity就可以写成0到1之间的值了,这里我总结了一条很重要的一点就是动画的当前值加上速度值,一定要在某个阶段等于目标值,我在代码中还专门为那一行做了注释,为了实现这一目标,我们在速度值的时候因为是有小数的存在,一定要在把他变为整数,这样才会到最后为1的时候精确控制目标元素的值,目标元素的值必须为整数,如果不是整数就必须做上述代码中的opacity的值*100然后在取整的操作,就是还原到整数那个阶段,但是这样其实也不太完美,如果opacity的值的小数位大于两位的话,他就有可能不会完美的到达目标值。

希望看到的人赐教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值