JS运动集合,封装便捷的功能函数

动画的原理

匀速运动

        // 1. 匀速运动 s = vt  v不变
        let btn = document.querySelector("button");
        let div = document.querySelector(".box");
        btn.onclick = function () {
            starMove(div, 300)
        };
        // 运动的元素  运动到的位置 向后+  还是向前-
        function starMove(dom, target) {
            clearInterval(dom.timer);
            let speed = 7; // 匀速的关键  每次运动的距离一样
            dom.timer = setInterval(() => {
                 // 控制左右的方向 
                speed = (target - dom.offsetLeft) > 0 ? 7 : -7;
                // 判断停止的位置  
                // 目标位置 - 当前元素左侧的距离 <  指定速度 停止
                if (Math.abs(target - div.offsetLeft) < Math.abs(speed)) {
                    clearInterval(dom.timer);
                    dom.style.left = target + "px";
                } else {
                    dom.style.left = dom.offsetLeft + speed + "px";
                }
            }, 30);
        }

缓动运动

为了让每个元素拥有自己独立的定时器,把定时器名称挂在元素的属性上。
缓动运动:先加速后减速做变换。

        // 2. 缓冲运动 先加速 后减速  增加的步数越来越小
        let btn = document.querySelector("button");
        let div = document.querySelector(".box");

        btn.onclick = function () {
            startMove(div, 500)
        };
        
        function startMove(dom, target) {
            let speed = null;
            let step = 7;
            clearInterval(dom.timer);
            dom.timer = setInterval(() => {
                // 左右运动 控制数值大小 缓动趋势
                // 元素距离目标点 距离越小 运动速度(每次运动的距离)越小
                speed = (target - dom.offsetLeft) / step;  
                // 取个整数 负数时 向下取整  整数时 向上取整
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); 
				// 当元素左侧距离 达到目标点时 清除定时器
                if (dom.offsetLeft == target) {
                    clearInterval(dom.timer);
                } else {
                	// 具有左右两个方向的功能 speed为+ 加距离  为 - 减距离
                    dom.style.left = dom.offsetLeft + speed + "px";
                }
            }, 30);
        };

属性的缓动运行

不同元素不同属性变化。
透明度的缓动:

        
        // 获取对象特定属性值  返回类型是字符串
        function getStyle(dom, attr) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[attr];
            } else {
                return dom.currentStyle[attr];
            }
        }
        
        // 3.缓动透明度
        let btn = document.querySelector("button");
        let div = document.querySelector(".box");

        btn.onclick = function () {
            // 透明度扩大100倍
            startMove(div, "opacity", 20);
        };
        // 透明度缓冲
        function startMove(dom, target) {
            clearInterval(dom.timer);
            let speed = null,
                iCur = null;
            let step = 7;
            dom.timer = setInterval(function () {
                iCur = parseFloat(getStyle(dom, "opacity")) * 100;
                // speed为 缓动趋势 同时具有左右的功能。
                // 元素距离目标点 距离越小 运动速度(每次运动的距离)越小
                speed = (target - iCur) / step;
                // 取个整数 负数时 向下取整  整数时 向上取整
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); 
                // 透明度到了
                if (iCur == target) {
                    clearInterval(dom.timer);
                } else {
                    dom.style.opacity = (iCur + speed) / 100;
                }
            }, 30);
        };

封装适合所有属性的缓动:

        // 4. 封装一个不同属性缓动
        function startMove(dom, attr, target) {
            let speed = null,
                iCur = null;
            let step = 7;
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
            	// 	判断传入的属性是否 为 opacity 需要特殊处理
                if (attr == "opacity") {
                    iCur = parseFloat(getStyle(dom, attr)) * 100;
                } else {
                    iCur = parseFloat(getStyle(dom, attr));
                }
                // 确定属性类型  继续向下运行
                speed = (target - iCur) / step; // 元素距离目标点距离越小速度越小
                // 取个整数 负数时 向下取整  整数时 向上取整
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); 
                if (iCur == target) {
                    clearInterval(dom.timer);
                } else {
                    if (attr == "opacity") {
                        dom.style.opacity = (iCur + speed) / 100;
                    } else {
                    	// 具有左右两个方向的功能 speed为+ 加距离  为 - 减距离
                        dom.style[attr] = iCur + speed + "px";
                    }
                }
            }, 30);
        }

多个属性同时传入

不同元素多个属性发生改变。
回调机制:回调函数,动画完成后执行。

        // 5. 对象形式传入属性
        let btn = document.querySelector("button");
        let div = document.querySelector(".box");

        btn.onclick = function () {
            // 透明度扩大100倍
            startMove(div, {
                width: 400,
                height: 400,
                opacity: 50 // 串值时也需要扩大100
            });
        };

        // 属性对象:
        // 1.遍历此对象属性,
        // 2.判断属性中是否有透明度,有 值*100
        // 3.改变值时:判断属性是否含有opacity  有 /100
        // 4.设置标志 默认定时器可以清除  flag = true 循环外部设置
        // 5.判断是否有属性没有变换完毕   变换对象.属性值 是否等于 属性集合.属性值 不等于 flag = false
        // 6.属性遍历完毕,只要标志为真就说明所有属性完成变换 则清除定时器
        // 7.回调函数,动画做完调用,在清除定时器之后

        function startMove(dom, attrObj, callback) {
            clearInterval(dom.timer);
            let speed = null,
                iCur = null;
            const step = 7;
            dom.timer = setInterval(function () {
                let flag = true; // 标志
                // 遍历属性集合对象
                for (let attr in attrObj) {
                    // 判断属性 是否含有 opacity 取值
                    if (attr == "opacity") {
                        iCur = parseFloat(getStyle(dom, attr)) * 100;
                    } else {
                        iCur = parseFloat(getStyle(dom, attr));
                    }

                    // 缓动趋势
                    speed = (attrObj[attr] - iCur) / step;; // 元素距离目标点距离越小速度越小
                    // console.log(speed);

                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); // 取个整数
                    // 判断属性 是否含有 opacity 赋值
                    if (attr == "opacity") {
                        dom.style.opacity = (iCur + speed) / 100;
                    } else {
                        dom.style[attr] = iCur + speed + "px";
                    }
                    // 说明有属性没有变换完毕 标志取反
                    if (iCur != attrObj[attr]) {
                        flag = false;
                    }
                }
                // 属性对象遍历完毕  标志符为true则说明所有属性变换完毕 清除定时器
                if (flag) {
                    clearInterval(dom.timer);
                    // 逻辑短路应用:callback不存在返回false不影响,callback存在之间返回callback()
                    callback && callback();
                }
            }, 30);
        }

你可能感兴趣的:(Web—第二阶段,#,Javascript基础)