js实现元素的动画

以下都是总结的慕课网课程https://www.imooc.com/video/3179

eg1:元素属性值都带px

        // 想想是否可以用三目运算符直接一句话
        function getStyle(obj, attr) {
            // IE
            if (obj.currentStyle) {
                return obj.currentStyle[attr];
            } else {
                return getComputedStyle(obj, false)[attr];
            }
        }

        // obj:要实现动画的对象;attr:要实现动画的属性;target:属性动画的最终值
        function animate(obj, attr, target) {
            // 防止连续移入元素会生成多个计时器,所以进入之前先清除
            clearInterval(timer);
            obj.timer = setInterval(function() {
                // 属性当前值
                var icur = parseInt(getStyle(obj, attr));
                // 动画的速度
                var speed = (target - icur) / 8;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                if (icur == target) {
                    clearInterval(obj.timer);
                } else {
                    obj.style[attr] = icur + speed + 'px';
                }
            }, 30);
        }

eg2:除了eg1还包括对opacity的动画,这样基本可以满足大多数情况的动画了,其他比如z-index可以自己去补充

        // 想想是否可以用三目运算符直接一句话
        function getStyle(obj, attr) {
            // IE
            if (obj.currentStyle) {
                return obj.currentStyle[attr];
            } else {
                return getComputedStyle(obj, false)[attr];
            }
        }

        // obj:要实现动画的对象;attr:要实现动画的属性;target:属性动画的最终值
        function animate(obj, attr, target) {
            // 防止连续移入元素会生成多个计时器,所以进入之前先清除
            clearInterval(timer);
            obj.timer = setInterval(function() {
                // 属性当前值
                var icur = 0;
                if (attr == 'opacity') {
                    // 这里用Math.round()处理是防止出现数据在目标值附近抖动的情况,因为计算机对浮点数的计算存在误差
                    icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
                } else {
                    icur = parseInt(getStyle(obj, attr));
                }
                // 动画的速度
                var speed = (target - icur) / 8;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                // 检测停止
                if (icur == target) {
                    clearInterval(obj.timer);
                } else {
                    if (attr == 'opacity') {
                        // IE
                        obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
                        // 非IE
                        obj.style.opacity = (icur + speed) / 100;
                    } else {
                        obj.style[attr] = icur + speed + 'px';
                    }
                }
            }, 30);
        }

如果想要实现链式运动(这里不是指链式调用),即一个属性动画完成后开始下一个属性的动画,只需要在上面代码加个参数——回调函数

js实现元素的动画_第1张图片

调用方法如下

js实现元素的动画_第2张图片


以上方法不能实现让一个元素同时做多种动画,即jquery的animate效果,下面我们来实现一下

        // 想想是否可以用三目运算符直接一句话
        function getStyle(obj, attr) {
            // IE
            if (obj.currentStyle) {
                return obj.currentStyle[attr];
            } else {
                return getComputedStyle(obj, false)[attr];
            }
        }

        // obj:要实现动画的对象;json:要实现动画的属性及属性最终值;fn:回调函数
        function animate(obj, json, fn) {
            // 防止连续移入元素会生成多个计时器,所以进入之前先清除
            clearInterval(timer);
            // 标识是不是所有属性的动画都已完成,true表示都完成
            var flag = true;
            obj.timer = setInterval(function() {
                flag = true;
                for (var attr in json) {
                    // 属性当前值
                    var icur = 0;
                    if (attr == 'opacity') {
                        // 这里用Math.round()处理是防止出现数据在目标值附近抖动的情况,因为计算机对浮点数的计算存在误差
                        icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
                    } else {
                        icur = parseInt(getStyle(obj, attr));
                    }
                    // 动画的速度
                    var speed = (json[attr] - icur) / 8;
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                    // 检测只要有属性没有完成动画就将flag设置成false
                    if (icur != json[attr]) {
                        flag = false;
                    }

                    // 这里提取出来了,因为当icur == json[attr]时,speed=0,因此后面的值也不会有影响,按照逻辑应该是写在上面的if语句里
                    if (attr == 'opacity') {
                        // IE
                        obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
                        // 非IE
                        obj.style.opacity = (icur + speed) / 100;
                    } else {
                        obj.style[attr] = icur + speed + 'px';
                    }

                }
                if (flag) {
                    clearInterval(obj.timer);
                    if (fn) {
                        fn();
                    }
                }
            }, 30);
        }

 

你可能感兴趣的:(JS)