zoukankan      html  css  js  c++  java
  • 动画函数优化,为任意元素添加任意多个属性

    注释:

      本篇文章封装了两个函数,

      ① getStyle 方法:获取任意元素任意一个属性的值,兼容谷歌,火狐,IE浏览器

      ② variableSpeedAnimate 方法:为任意元素添加任意多个属性,引入了回调函数,可在动画结束后,执行新的操作。

      注意:

       parseInt("128px") = 128

       如果设置的属性是 “opacity”,为了取得整数值,避免计算机的精度问题,可以采用“放大缩小”策略,即当前值和目标值放大相同倍数,设置属性值时,缩小相同倍数

       如果设置的属性是“zIndex”,不用直接渐变,直接将zIndex值设置成目标值即可

       属性值是“zIndex”而不是“z-index”是因为浏览器计算后的样式是“zIndex”,驼峰式命名法

    一、代码

    /**
     * 封装缓动动画,变速,为任意元素添加任意多个属性
     * @param {*} element   元素
     * @param {*} json      css属性键值对,例如{"width":200,"height":100,"zIndex":100,"opacity":0.3}
     * @param {*} fn        回调函数,动画结束,调用回调函数
     */
    function variableSpeedAnimate(element, json, fn) {
        clearInterval(element.timeId);
        element.timeId = setInterval(function () {
            var reachTarget = true;
            for (const attr in json) {
                if (attr == "zIndex") {
                    element.style[attr] = json[attr];
                } else if (attr == "opacity") {
                    var current = getStyle(element, attr) * 100;
                    var target = json[attr] * 100;
                    var step = (target - current) / 10;
                    step = step > 0 ? Math.ceil(step) : Math.floor(step);
                    current += step;
                    element.style[attr] = current / 100;
                    if (current != target) {
                        reachTarget = false;
                    }
                } else {
                    var current = parseInt(getStyle(element, attr));
                    var target = json[attr];
                    var step = (target - current) / 10;
                    step = step > 0 ? Math.ceil(step) : Math.floor(step);
                    current += step;
                    element.style[attr] = current + "px";
                    if (current != target) {
                        reachTarget = false;
                    }
                }
    
            }
            if (reachTarget) {
                clearInterval(element.timeId);
                if (fn) {
                    fn();
                }
            }
        }, 20)
    }
    

    二、测试deno

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            div {
                 200px;
                height: 100px;
                position: absolute;
                left: 0px;
                top: 0;
                border: 1px solid yellow;
                background-color: pink;
                z-index: 0;
    
            }
    
            input {
                position: relative;
                z-index: 99;
            }
        </style>
    </head>
    
    <body>
    
        <input type="button" value="400px" id="btn" />
        <input type="button" value="800px" id="btn1" />
        <div id="dv"></div>
    
        <script src="./js/common.js"></script>
        <script>
            // 400按钮点击事件
            my$("btn").onclick = function () {
                var json = {"width":400,"left":200,"top":150,"opacity":0.6};
                animate(my$("dv"), json,function(){
                    var json1 = { "width":400,"left":500,"top":250,"opacity":0.3};
                    animate(my$("dv"), json1,function(){
                        var json2 = {"width":200,"left":0,"top":0,"opacity":1,"zIndex":100};
                        animate(my$("dv"), json2);
                    })
                });
            };
    
            // 800按钮点击事件
            my$("btn1").onclick = function () {
                animate(my$("dv"), {'left':800});
            };
    
    
            // 封装动画缓冲函数,变速
            function animate(element, json, fn) {
                clearInterval(element.timeId);
                element.timeId = setInterval(function () {
                    var reachTarget = true;
                    for (const attr in json) {
                        if (attr == "zIndex") {
                            element.style[attr] = json[attr];
                        } else if (attr == "opacity") {
                            var current = getStyle(element, attr) * 100;
                            var target = json[attr] * 100;
                            var step = (target - current) / 10;
                            step = step > 0 ? Math.ceil(step) : Math.floor(step);
                            current += step;
                            element.style[attr] = current / 100;
                            if (current != target) {
                                reachTarget = false;
                            }
                        } else {
                            var current = parseInt(getStyle(element, attr));
                            var target = json[attr];
                            var step = (target - current) / 10;
                            step = step > 0 ? Math.ceil(step) : Math.floor(step);
                            current += step;
                            element.style[attr] = current + "px";
                            if (current != target) {
                                reachTarget = false;
                            }
                        }
    
                    }
                    if (reachTarget) {
                        clearInterval(element.timeId);
                        if (fn) {
                            fn();
                        }
                    }
                }, 20)
            }
        </script>
    </body>
    
    </html>
    

    三、common.js

    /*根据id获取元素对象*/
    function my$(id) {
        return document.getElementById(id);
    }
    
    /**
     * 获取任意一个元素的任意一个属性值
     * @param {*} element   元素
     * @param {*} attr      属性值,字符串格式,例如'width'...
     */
    function getStyle(element, attr) {
        return window.getComputedStyle ? window.getComputedStyle(element, null)[attr] : element.currentStyle[attr];
    }

    四、效果图

      初始图:

        

      点击400px按钮:

        

        

      

      点击800px按钮:

      

      

  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/mycnblogs-guoguo/p/11250685.html
Copyright © 2011-2022 走看看