缓动动画典藏版 实现宽度、高度、层级、透明度、颜色变化

缓动动画典藏版

缓动动画思路

/* 
        1.缓动动画核心思路 : 由快到慢
            本次移动距离 = (目标位置 - 当前位置)/10

        2.缓动动画特点
            (1)需要取整 : 本次移动距离计算是一个除法的过程,会产生小数。而像素一般是整数
            (2)没有误差 :  核心公式到了后面,都是1px的移动。
                不需要边界检测 : 超过目标位置,清除定时器 并且 元素复位
                需要终点检测  : 到达终点, 清除定时器

        3.缓动动画封装思路
            (1)解决代码冗余       ->   函数
            (2)解决 移动距离     不限   ->    函数参数
            (3)解决 移动元素     不限   ->    函数参数
            (4)解决 移动方向     不限  
            (5)解决 移动属性     不限    -> 目前只能水平移动,  无法上下移动,无法改变宽高
            (6)解决 移动属性数量 不限     -> 目前一次只能改变一个属性
        最终动画 : 可以移动任意元素, 任意属性(不限数量) , 还可以移动多次
        */


        /*
            1.发现问题 : 层级与透明度没有动画
            2.分析问题
                层级 : 变化是一个瞬间的过程,没有动画的
                透明度 :范围是  0-1的小数
                    (1)需要使用parseFloat取小数
                    (2)透明度属性值是  number,没有px
                    (3)浮点型存在精度丢失 : 需要放大100倍计算 (透明度最大保留小数点两位)
            3.解决问题
                层级 : 直接赋值,不做动画
        */

HTML 块

<input type="button" value="左右移动到800" id="btn1" />
    <input type="button" value="上下移动到400" id="btn2" />

    <div id="box"></div>

    <div id="box1"></div>

js实现缓动动画代码

var box = document.querySelector('#box');//红色

        //1. 红色缓动到400
        document.querySelector('#btn1').onclick = function () {
            animationSlow(box, {
                left: 300,
                top: 300,
                width: 300,
                height: 300,
                zIndex: 1,
                opacity: 0.5,
                backgroundColor:'yellow'
            });
        };

        //2. 红色缓动到800
        document.querySelector('#btn2').onclick = function () {
            animationSlow(box, {
                left: 100,
                top: 200,
                width: 300,
                height: 400,

            });
        };

        /**
        * @description: 缓动动画
        * @param {type} ele :  要移动的元素
        * @param {type} attrs : 要移动的属性对象
        * @param {type} fn : 回调函数,可选。 (如果用户传了,则动画结束后执行fn中的代码)
        * @return: 
        */
        function animationSlow(ele, attrs, fn) {
            //1.清除以前的定时器,以本次为准
            clearInterval(ele.timeID);
            //2.开始本次移动
            ele.timeID = setInterval(function () {
                /*定时器每一次移动,结果只有两种情况。 要么全部到达终点,要么没有 
                    开关思想三步法
                        a. 提出假设  var isAllOk = true
                        b. 验证假设
                        c. 根据开关结果实现需求
                */
                //第一步 : 提出假设
                var isAllOk = true;
                //第二步 : 验证假设 (遍历对象属性,每一个属性进行移动)
                for (var key in attrs) {
                    var attr = key;
                    var target = attrs[key];

                    if (key == 'zIndex' || key == 'backgroundColor') {
                        //层级没有动画,直接赋值
                        ele.style[attr] = target;
                    } else if (key == 'opacity') {//透明度单独处理
                        //2.1 获取元素当前位置
                        /*(1)透明度是0-1小数,需要parseFloat */
                        var current = parseFloat(getComputedStyle(ele)[attr]);
                        /* (2)透明度存在浮点型精度丢失:放大100倍计算 */
                        current *= 100;
                        target *= 100;
                        //2.2 计算本次移动距离 = (目标位置 - 当前位置)/10
                        var step = (target - current) / 10;
                        //取整 : 从左往右 : step正数 向上取整    从右往左:step负数 向下取整
                        step = step > 0 ? Math.ceil(step) : Math.floor(step);
                        //2.3 开始移动
                        current += step;
                        /* (3)透明度是0-1小数,没有px */
                        ele.style[attr] = current/100;
                        //2.4 终点检测: 到达终点,清除定时器结束运动
                        //假设不成立 : 只要有属性没有到达终点
                        if (current != target) {
                            isAllOk = false;
                        };
                    }
                    else {
                        //2.1 获取元素当前位置
                        /* 注意点: getComputedStyle获取的是字符串类型,需要转成数字 */
                        var current = parseInt(getComputedStyle(ele)[attr]);
                        //2.2 计算本次移动距离 = (目标位置 - 当前位置)/10
                        var step = (target - current) / 10;
                        //取整 : 从左往右 : step正数 向上取整    从右往左:step负数 向下取整
                        step = step > 0 ? Math.ceil(step) : Math.floor(step);
                        //2.3 开始移动
                        current += step;
                        ele.style[attr] = current + 'px';
                        //2.4 终点检测: 到达终点,清除定时器结束运动
                        //假设不成立 : 只要有属性没有到达终点
                        if (current != target) {
                            isAllOk = false;
                        };
                    }
                };
                //第三步:根据开关结果实现需求
                if (isAllOk) {
                    //清除定时器
                    clearInterval(ele.timeID);
                    //动画结束,开始执行回调函数 (用户传递了fn,且为函数才执行)
                    if (typeof fn == 'function') {
                        fn();
                    };
                };
            }, 20);
        };

``
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值