欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

webAPI案例之三分钟玩转动画封装

程序员文章站 2022-03-30 11:52:02
...

webAPI案例之三分钟玩转动画封装

动画原理:

  1. 获得盒子当前位置
  2. 让盒子在当前位置加上1个移动距离(注意此元素需要添加定位才能使用left)
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件

1. 从简单开始

效果图:

webAPI案例之三分钟玩转动画封装

思路相关

webAPI案例之三分钟玩转动画封装
相关代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: antiquewhite;
        }
    </style>
</head>

<body>
    <div>

    </div>
    <script>
        var div = document.querySelector("div");
        var timer = null;
        timer = setInterval(go, 20);

        function go() {
            div.style.left = div.offsetLeft + 3 + "px";
            if (div.offsetLeft > 500) {
                clearInterval(timer);
            }
        }
    </script>

</body>

</html>

2. 稍稍进行改装

效果:

webAPI案例之三分钟玩转动画封装

思路相关:

不要忘了给对象添加元素和方法的方式喔

相关代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: antiquewhite;
        }
        
        .div02 {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: red;
            top: 150px;
        }
    </style>
</head>

<body>
    <button>控制第一个盒子</button>
    <button>控制第二个盒子</button>
    <div></div>
    <div class="div02"></div>
    <script>
        var btn = document.querySelectorAll("button");
        var div = document.querySelectorAll("div");
        div[0].target = 300;
        div[1].target = 200;
        btn[0].addEventListener("click", function() {
            go(div[0], div[0].target)
        })
        btn[1].addEventListener("click", function() {
                go(div[1], div[1].target)
            })
            //这次我们不在声明定时器的名字了,而是利用给对象添加属性的方法
        function go(element, target) {
            element.timer = setInterval(function() {
                element.style.left = element.offsetLeft + 3 + "px";
                if (element.offsetLeft > target) {
                    clearInterval(element.timer);
                }
            }, 20);
        }
    </script>

</body>

</html>

3. 接下来就到了重点了——缓慢动画

它的特点是就是让元素运动的速度有所变化,这里以渐慢方式为主

思路:

  1. 让每次移动的距离逐渐减少
  2. 核心,它的每次移动是因为定时器循环执行运动函数,这里我们可以给定时器中的运动函数做点手脚。让它每次的移动距离递减。常用值(目标值-现在位置)/10 。即把目标值和现在的位置当成一个线段,且分成10份。随着现在位置的不断增大,这个分数不是越来越小吗
  3. 停止的条件是: 让当前盒子位置等于目标位置就停止定时器 (要注意的是步长要取整。0-100的时候向上取整,100-0 。向下取整 )
  4. 为何取整,不取整一般最后的步长都会成了小数那怎么可能会等于你设置的整数目标值呢。它到不了目标值就会在那左右抽搐。又问为什么有时向下有时向上呢。我以向上为例(向下同理),当分数越来越小越来越小它成了小数,小数向上取整成了1 。1再除以份数10又成了小数,再取整又成了1 。故它最后的步长是以1走的,1像素1像素的走还走不动整数的目标值吗

效果:

webAPI案例之三分钟玩转动画封装

需要注意:

多次点击可触发定时器的按钮,如上面的过去回来。会导致速度加快问题等其他一些你想象不到的乱七八糟的问题,所以一般元素对象在做一件事的时候我们只开一个定时器。即用到定时器的时候先用排他思想去掉在该事情上的其他定时器

相关代码(在上面2的代码对部分修改)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: antiquewhite;
        }
    </style>
</head>

<body>
    <button>过去</button>
    <button>回来</button>
    <div></div>

    <script>
        var btn = document.querySelectorAll("button");
        var div = document.querySelector("div");
        div.target = 500;

        btn[0].addEventListener("click", function() {
            go(div, div.target);
        })
        btn[1].addEventListener("click", function() {
                go(div, 0);
            })
            //这次我们不在声明定时器的名字了,而是利用给对象添加属性的方法
        function go(element, target) {

            //解决多次点击导致速度加快问题
            clearInterval(element.timer);
            element.timer = setInterval(function() {
                var step = (target - element.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                element.style.left = element.offsetLeft + step + "px";


                if (element.offsetLeft == target) {
                    clearInterval(element.timer);
                }


            }, 20);
        }
    </script>

</body>

</html>

4 完整版动画封装,即相对于3加了个回调函数

即设置元素在做完动画时又做了什么。如移动了500px之后自己的背景变了

效果:

webAPI案例之三分钟玩转动画封装
注意问题:

注意回调函数在封装函数中的调用位置喔

相关代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: antiquewhite;
        }
    </style>
</head>

<body>
    <button>过去</button>
    <button>回来</button>
    <div></div>

    <script>
        var btn = document.querySelectorAll("button");
        var div = document.querySelector("div");
        div.target = 500;

        btn[0].addEventListener("click", function() {
            go(div, div.target, function() {
                div.style.backgroundColor = "red";
            });
        })
        btn[1].addEventListener("click", function() {
                go(div, 0);
            })
            //这次我们不在声明定时器的名字了,而是利用给对象添加属性的方法
        function go(element, target, back) {

            //解决多次点击导致速度加快问题
            clearInterval(element.timer);
            element.timer = setInterval(function() {
                var step = (target - element.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                element.style.left = element.offsetLeft + step + "px";


                if (element.offsetLeft == target) {
                    clearInterval(element.timer);
                    //是否有back,有则调用我在js基础02上有借助电路解释过
                    back && back();
                }


            }, 20);

        }
    </script>

</body>

</html>