zoukankan      html  css  js  c++  java
  • JS —— 轮播图中的缓动函数的封装

      轮播图的根本其实就是缓动函数的封装,如果说轮播图是一辆跑动的汽车,那么缓动函数就是它的发动机,今天本文章就带大家由简入繁,封装属于自己的缓动函数~~

      我们从需求的角度开始,首先给出一个简单需求:

      1、我想让页面中的一个盒子从开始的位置匀速向右运动到200px的地方,该怎么实现?

         分析:1)我们需要知道盒子在哪个地方,这个可以通过offsetLeft属性去获取;

            2)要让盒子匀速运动,对于js肯定需要setInterval了;

            3)要让盒子向右边跑起来?那就是需要不停改变盒子与左边起始点的距离,有margin-left,还有定位的left,这里我选择了改变绝对定位的left;

            4)跑到离开始点200px的距离我们要停下来,使用clearInterval就可以了。

       接下来直接上代码了

      

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">
          * {
            margin: 0;
            padding: 0;
          }
          div {
            position: absolute;
            top: 50px;
            width: 100px;
            height: 100px;
            background-color: red;
          }
          input {
            width: 100px;
            height: 30px;
            color: #fff;
            background-color: yellowgreen;
          }
    
        </style>
      </head>
    
      <body>
        <div></div>
        <input type="button" value="移动到200" />
    
    
        <script type="text/javascript">
          // 获取到元素(这里有个小细节,如果给元素设置了id名,即便不使用获取元素的方法,也能通过这个id名获取到元素哦~~大家可以自己尝试一下)
          var btn = document.querySelector('input'),
              dv = document.querySelector('div');
          // 添加点击事件
          btn.addEventListener('click',function() {
            var timer = null,// 保存定时器
                currentDistance = dv.offsetLeft, // 当前离父盒子的距离
                step = 8,// 每次改变的距离
                target = 200;// 目标距离
            timer = setInterval(function() {
              currentDistance += step;// 当前距离 = 上一个当前距离 + 改变的距离
              if((target - currentDistance) < step) { 
                currentDistance = target; // 如果目标距离与当前距离的差小于了要改变的距离,这时候我们就直接让当前距离等于目标距离,防止盒子停下来的时候有误差
                clearInterval(timer); // 清楚定时器
                timer = null; // 将timer解绑,释放内存
              }
              dv.style.left = currentDistance + 'px'; // 最核心的一步,改变盒子的left为当前距离
            },17)
          })
        </script>
      </body>
    </html>

      2、一个初步运动的效果实现了,那么接下来我们改进了需求:

        盒子运动到200px的位置后,我们要让盒子继续运动到400px的位置?

        分析: 1)、这时候要有两个按钮点击,一个运动到200px,一个运动到400px

            2)、虽然有两个运动,但是其使用的功能都是一样,都是从一个点移动到另一个点,所以我们考虑将1中的运动封装一个函数,以供复用。

        上代码~

       

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <title>Document</title>
      <style type="text/css">
        * {
          margin: 0;
          padding: 0;
        }
        div {
          position: absolute;
          top: 50px;
          width: 100px;
          height: 100px;
          background-color: red;
        }
        input {
          width: 100px;
          height: 30px;
          color: #fff;
          background-color: yellowgreen;
        }
    
      </style>
    </head>
    
    <body>
      <div></div>
      <input type="button" value="移动到200" />
      <input type="button" value="移动到400" />
      <script type="text/javascript">
        // 封装函数,盒子和目标距离都是不确定的,我们可以将他们作为参数传递。
        function animation(tag,target) {
          var timer = null,
              currentDistance = tag.offsetLeft,
              step = 5;
          step = currentDistance < target? step: -step;// 判断step的正负,200到400时是递增,400到200时是递减
          timer = setInterval(function() {
            if(Math.abs(currentDistance - target) > Math.abs(step)) { // 这里判断条件也要略作改动,使用绝对值进行比较
              currentDistance += step; /
              tag.style.left = currentDistance + 'px';
            }else {
              tag.style.left = target + 'px' // 当当前距离与目标距离之间的差值小于step改变的距离时,我们直接让盒子移动到目标距离。
              clearInterval(timer);
              timer = null;
            }
          },17)
        }
        var btns = document.querySelectorAll('input'),
            dv = document.querySelector('div');
        btns[0].addEventListener('click',function() {
          animation(dv,200);
        })
        btns[1].addEventListener('click',function() {
          animation(dv,400);
        })
      </script>
    </body>
    </html>

      3、盒子来回运动的函数我们封装好了,但是我们再想一下轮播图的滚动效果,它并不是匀速移动,而是最开始很块,在接近滚动完成时,速度又逐渐减低。

         需求: 让盒子缓动(也就是变速运动) 

         上代码~

        

    function animation(tag,target) {
          var timer = null;
          timer = setInterval(function() {
            var currentDistance = tag.offsetLeft,
                step = (target - currentDistance) / 5;// 通过目标距离与当前距离的差除以5便达到了我们需要的变速运动,因为step每次定制器执行都要改变,所以放入定时器内
            step = step > 0 ? Math.ceil(step):Math.floor(step);// 这里如果将currentDistance定时器外面声明可以不用写,如果放在定时器内声明,因为offsetLeft取整的特性,要对step进行取整
            if(Math.abs(currentDistance - target) > Math.abs(step)) {
              currentDistance += step;
              tag.style.left = currentDistance + 'px';
            }else {
              tag.style.left = target + 'px'
              clearInterval(timer);
              timer = null;
            }
          },17)

      好了,一个轮播图需要的最基本的缓动函数完成了~

      这里补充一个比较完整的缓动函数:它的功能更全面一点,可以同时更改多样式。

      

    function perfectAnimate(tag, obj, fn) {// 传三个参数,运动的盒子,对象(可以传多个属性),回调函数(在执行完后可以再执行自定义的功能)
        clearInterval(tag.timer);// 这里将定时器作为tag标签的属性保存,可以多次调用函数清除上一个定时器。
        tag.timer = setInterval(function () {
            var flag = true;
            for (var k in obj) {
           // 因为并不是所有属性都带px单位,所以这里进行判断分别设置
    if (k == 'opacity') { var currentDistance = getStyle(tag, k) * 100, target = obj[k] * 100, step = (target - currentDistance) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); currentDistance += step; tag.style[k] = currentDistance / 100; } else if (k == 'zIndex') { tag.style[k] = obj[k]; else { var currentDistance = parseInt(getStyle(tag, k)) || 0, target = obj[k], step = (target - currentDistance) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); currentDistance += step; tag.style[k] = currentDistance + 'px'; } if (target != currentDistance) { flag = false // 只要还有属性没有运动完成,就不会清楚定时器 } } if (flag) { clearInterval(tag.timer) fn && fn();// 所有定时器走完,这里执行回调函数,短路操作避免不传回调函数也不会报错。 } }, 17) }

      

    // 获取样式的兼容函数,上面的缓动函数的依赖
    function
    getStyle(tag, attr) { if (tag.currentStyle) { return tag.currentStyle[attr]; } else { return getComputedStyle(tag, null)[attr]; } }

      就写到这里了~,睡个午觉QAQ

      

  • 相关阅读:
    Jenkins中构建Testcomplete项目的方法介绍
    抖音批量,批量运营抖音_不要迷恋我_【单月抖音变现7000万】教程
    java 读取 excel 表格内容
    .NET Core 2.1中的分层编译(预览)
    Windows10上使用Linux子系统(WSL)
    swagger上传文件并支持jwt认证
    .NET微服务 容器化.NET应用架构指南(支持.NET Core2)
    用C#编写Linux守护进程
    安装mysql后运行.net程序出错
    2018 你好
  • 原文地址:https://www.cnblogs.com/qishiyumowang/p/6285198.html
Copyright © 2011-2022 走看看