0
点赞
收藏
分享

微信扫一扫

JavaScript知识点整理(十六)- PC端网页特效 - 动画

谁知我新 2022-03-19 阅读 48

目录

一、动画函数封装

1.1 动画实现原理

1.2 动画函数简单封装

1.3 动画函数给不同元素记录不同定时器

1.4 缓动画原理

1.5 案例练习 - 让动画函数可以在两个位置之间来回移动

1.6 动画函数添加回调函数

1.7 案例练习 - 侧边栏划出动画效果


一、动画函数封装

1.1 动画实现原理

核心原理:通过定时器setInterval()不断移动盒子位置

实现步骤:

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

案例练习

        div{
            width: 100px;
            height: 100px;
            position: absolute;
            left: 0;
            background: skyblue;
            border: 1px solid #ccc;
        }
    <div></div>
    <script>
        var div = document.querySelector('div');
        var timer = setInterval(function(){
            if(div.offsetLeft >= 200){
                clearInterval(timer);
            } else {
                div.style.left = div.offsetLeft + 1 +'px';
            }
        },30);
    </script>

1.2 动画函数简单封装

注意:函数需要传递2个参数,动画对象移动到的距离

以1.1案例练习为例,封装动画函数

        function animate(obj,target){
            var timer = setInterval(function(){
                if(obj.offsetLeft >= target){
                    clearInterval(timer);
                } else {
                    obj.style.left = obj.offsetLeft + 1 +'px';
                }
            },30);
        }
        var div = document.querySelector('div');
        animate(div,200);

1.3 动画函数给不同元素记录不同定时器

如果多个函数使用这个动画函数,每次都需要var声明定时器,因此可以给不同的元素使用不同的定时器

核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性

        function animate(obj,target){
            clearInterval(obj.timer)
            // 给不同元素指定了不同定时器
            obj.timer = setInterval(function(){
                if(obj.offsetLeft >= target){
                    clearInterval(obj.timer);
                } else {
                    obj.style.left = obj.offsetLeft + 1 +'px';
                }
            },30);
        }

1.4 缓动画原理

缓动画就是让元素运动速度有所变化,最常见的就是让速度慢慢停下来

思路:

  1. 让盒子每次移动距离逐渐变小,达到速度变慢的效果
  2. 核心算法:(目标值-现在的位置)/ n 作为每次移动的距离
  3. 停止条件:让盒子位置等于目标位置就停止定时器

1.5 案例练习 - 让动画函数可以在两个位置之间来回移动

注意:

  1. 步长值需为整数
  2. 步长值如果为正整数,则遇到小数点时往大取整
  3. 步长值如果为负整数,则遇到小数点时往小取整
        div{
            width: 100px;
            height: 100px;
            position: absolute;
            left: 0;
            background: skyblue;
            border: 1px solid #ccc;
        }
 <button class="btn1">点击按钮到达500px</button>
    <button class="btn2">点击按钮到达800px</button>
    <div></div>
    <script>
        function animate(obj,target){
            clearInterval(obj.timer)
            // 给不同元素指定了不同定时器
            obj.timer = setInterval(function(){
                // 步长值写道定时器里
                // var step = Math.ceil((target - obj.offsetLeft) / 10);
                var step = (target - obj.offsetLeft) / 10;
                // 判断步长值的正负
                step = step > 0 ? Math.ceil(step) :Math.floor(step);
                if(obj.offsetLeft == target){
                    clearInterval(obj.timer);
                } else {
                    obj.style.left = obj.offsetLeft + step +'px';
                }
            },30);
        }
        var div = document.querySelector('div');
        var btn1 = document.querySelector('.btn1');
        var btn2 = document.querySelector('.btn2');

        btn1.addEventListener('click',function(){
            animate(div,500)
        });
        btn2.addEventListener('click',function(){
            animate(div,800)
        });

1.6 动画函数添加回调函数

回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调

回调函数写的位置:定时器结束的位置

以1.5案例为基础的案例练习

    <button class="btn1">点击按钮到达500px</button>
    <button class="btn2">点击按钮到达800px</button>
    <div></div>
    <script>
        function animate(obj, target, callback){
            clearInterval(obj.timer)
            // 给不同元素指定了不同定时器
            obj.timer = setInterval(function(){
                // 步长值写道定时器里
                // var step = Math.ceil((target - obj.offsetLeft) / 10);
                var step = (target - obj.offsetLeft) / 10;
                // 判断步长值的正负
                step = step > 0 ? Math.ceil(step) :Math.floor(step);
                if(obj.offsetLeft == target){
                    clearInterval(obj.timer);
                    // 回调函数写道定时器结束里面
                    if(callback){
                        callback();
                    }
                } else {
                    obj.style.left = obj.offsetLeft + step +'px';
                }
            },30);
        }
        var div = document.querySelector('div');
        var btn1 = document.querySelector('.btn1');
        var btn2 = document.querySelector('.btn2');

        btn1.addEventListener('click',function(){
            animate(div,500,function(){
                div.style.background = 'red';
            })
        });
        btn2.addEventListener('click',function(){
            animate(div,800)
        });

1.7 案例练习 - 侧边栏划出动画效果

     <style>  
        .sliderbar {
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: #fff;
        }
        
        .con {
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: skyblue;
            z-index: -1;
        }
    </style>
    <script src="animate.js"></script>
    <div class="sliderbar">
        <span>←</span>
        <div class="con">问题反馈</div>
    </div>
    <script>
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        sliderbar.addEventListener('mouseenter',function(){
            animate(con, -160,function(){
                sliderbar.children[0].innerHTML = '→';
            });
        }); 
        sliderbar.addEventListener('mouseleave',function(){
            animate(con, 0);
            sliderbar.children[0].innerHTML = '←';
        }); 
    </script>

animate.js

function animate(obj, target, callback) {
    clearInterval(obj.timer)
    // 给不同元素指定了不同定时器
    obj.timer = setInterval(function(){
        // 步长值写道定时器里
        // var step = Math.ceil((target - obj.offsetLeft) / 10);
        var step = (target - obj.offsetLeft) / 10;
        // 判断步长值的正负
        step = step > 0 ? Math.ceil(step) :Math.floor(step);
        if(obj.offsetLeft == target){
            clearInterval(obj.timer);
            // 回调函数写道定时器结束里面
            if(callback){
                callback();
            }
        } else {
            obj.style.left = obj.offsetLeft + step +'px';
        }
    },15);
}

 

举报

相关推荐

0 条评论