PC side seamless continuous scrolling special effects, marquee carousel special effects, breathing light carousel special effects

1. Seamless continuous scrolling effects

1. The principle of seamless continuous scrolling

For example, there are 6 pictures, the order is 0~5

Then stitch the same 0~5 pictures in the back for scrolling

When the 0th picture of the second group of pictures is moved to the left side of the scrolling area (that is, the first group of pictures has been moved), the picture can be moved from the beginning immediately.

2. Seamless continuous scrolling code implementation

<!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>
      * {
          margin: 0;
          padding: 0;
      }

      .box {
          width: 1000px;
          height: 130px;
          border: 1px solid #000;
          margin: 50px auto;
          overflow: hidden;
      }

      .box ul {
          list-style: none;
          /* 设置大一点,这样li才能浮动 */
          width: 5000px;
          position: relative;
      }

      .box ul li {
          float: left;
          margin-right: 10px;
      }
  </style>
</head>

<body>
  <div id="box" class="box">
      <ul id="list">
          <li><img src="images/number/0.png" alt=""></li>
          <li><img src="images/number/1.png" alt=""></li>
          <li><img src="images/number/2.png" alt=""></li>
          <li><img src="images/number/3.png" alt=""></li>
          <li><img src="images/number/4.png" alt=""></li>
          <li><img src="images/number/5.png" alt=""></li>
      </ul>
  </div>
  <script>
      var box = document.getElementById('box');
      var list = document.getElementById('list');

      // 复制多一遍所有的li
      list.innerHTML += list.innerHTML;
      // 全局变量,表示当前list的left值
      var left = 0;
      // 定时器,全局变量
      var timer;
      move();
      // 动画封装成函数
      function move() {
          // 设表先关,防止动画积累
          clearInterval(timer);
          timer = setInterval(function () {
              left -= 4;
              // 每张图宽200px,加上缝隙为1260px
              if (left <= - 1260) {
                  left = 0;
              }
              list.style.left = left + 'px';
          }, 20);
      }

      // 鼠标进入停止定时器
      box.onmouseenter = function () {
          clearInterval(timer);
      };
      // 鼠标离开继续定时器
      box.onmouseleave = function () {
          move();
      };
  </script>
</body>
</html>
复制代码

2. The special effect of the marquee carousel

2-1. Implementation principle and precautions

Assuming that 5 pictures are to be rotated, click the right button to play the next picture, and click the left button to play the previous picture.

2-1-1. Layout carousel, realize clicking the right button to switch to the next picture

<!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>
      * {
        margin: 0;
        padding: 0;
      }
      
      .carousel {
        width: 650px;
        height: 360px;
        border: 1px solid #000;
        margin: 50px auto;
        position: relative;
        overflow: hidden;
      }
      
      .carousel ul {
        list-style: none;
        width: 6000px;
        position: relative;
        left: 0px;
        transition: left .5s ease 0s;
      }
      
      .carousel ul li {
        float: left;
      }
      
      .carousel .leftbtn {
        position: absolute;
        left: 20px;
        top: 50%;
        margin-top: -25px;
        width: 50px;
        height: 50px;
        background-color: rgb(226, 68, 28);
        border-radius: 50%;
      }
      
      .carousel .rightbtn {
        position: absolute;
        right: 20px;
        top: 50%;
        margin-top: -25px;
        width: 50px;
        height: 50px;
        background-color: rgb(226, 68, 28);
        border-radius: 50%;
      }
    </style>
  </head>
  
  <body>
    <div class="carousel">
      <ul id="list">
        <li><img src="images/beijing/0.jpg" alt=""></li>
        <li><img src="images/beijing/1.jpg" alt=""></li>
        <li><img src="images/beijing/2.jpg" alt=""></li>
        <li><img src="images/beijing/3.jpg" alt=""></li>
        <li><img src="images/beijing/4.jpg" alt=""></li>
      </ul>
      <!-- href写成空的javascript以防止页面刷新 -->
      <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
      <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>
    <script>
      // 得到按钮和ul,ul整体进行运动
      var leftbtn = document.getElementById('leftbtn');
      var rightbtn = document.getElementById('rightbtn');
      var list = document.getElementById('list');
      
      var idx = 0; // 表示此时处于第几张图
      
      rightbtn.onclick = function () {
        idx++; // 点击一次图片序号+1
        list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
      }
    </script>
  </body>
  
</html>
复制代码
  • It should be noted that each picture is arranged in a floating manner, and the ul width must be large enough to arrange the li
  • We can add a transition effect to the left property of ul to make it smoother when moving

At this point, we will find that when we continue to click, click the right button again after rotating to the fifth picture, and the picture becomes blank, then how can we implement the rotation to the last picture and then start from the first picture What about carousel?

2-1-2. Realize the carousel effect of connecting the last picture and the first picture

Implementation principle:

  • Append a clone of the first picture to the back of the last picture, so that after rotating to the last picture, click again to see the first picture
  • In order to become the second image when the button is clicked again, then we can quickly set the left of the ul element to 0 after moving to the cloned image
  • Here we add a transition animation to the ul, and the animation duration is 0.5s, so we have to wait for the animation duration to quickly set the left of the ul to 0
  • When the left of ul is quickly set to 0, it does not need to be noticed by the naked eye, so the transition effect should be removed here.
  // 得到按钮和ul,ul整体进行运动
  var leftbtn = document.getElementById('leftbtn');
  var rightbtn = document.getElementById('rightbtn');
  var list = document.getElementById('list');
  // 克隆第一张图片,追加到后面
  var cloneli = list.firstElementChild.cloneNode(true);
  list.appendChild(cloneli);

  var idx = 0; // 表示此时处于第几张图

  rightbtn.onclick = function () {
    // 为了防止重置ul时将transition置为了'none',这里还原一下
    list.style.transition = 'left .5s ease 0s';
    idx++; // 点击一次图片序号+1
    if (idx > 4) {
      // 在动画时长过后将ul快速重置回去
      setTimeout(function () {
        list.style.transition = 'none';
        list.style.left = 0;
        idx = 0;
      }, 500);
    }
    list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
  }
复制代码

2-1-3. Optimization: add a throttle lock to prevent the abnormal playback of the carousel image when quickly clicked

Since the transition animation played by the carousel here is 500 milliseconds, we can set a throttle lock

  var idx = 0; // 表示此时处于第几张图
  var lock = true;
  rightbtn.onclick = function () {
    if (!lock) { return }
    lock = false; // 锁住
    // 为了防止重置ul时将transition置为了'none',这里还原一下
    list.style.transition = 'left .5s ease 0s';
    idx++; // 点击一次图片序号+1
    if (idx > 4) {
      // 在动画时长过后将ul快速重置回去
      setTimeout(function () {
        list.style.transition = 'none';
        list.style.left = 0;
        idx = 0;
      }, 500);
    }
    list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
    setTimeout(function () {
      lock = true;
    }, 500);
  }
复制代码

2-1-4. Click the left button to switch to the previous carousel

  • If it is already the first carousel image, click the left button to switch to the last image, then you need to instantly move to the cloned image spliced ​​to the back (remove the transition effect); then add the upper transition effect to The carousel moves to the real last image
  • If it is not the first carousel image, then idx -- move normally
      leftbtn.onclick = function () {
          if (!lock) return;

          lock = false;
          // 判断是不是第0张,如果是,就要瞬间用假的替换真的
          if (idx == 0) {
              // 取消掉过渡,因为要的是瞬间移动,不是“咕噜”过去
              list.style.transition = 'none';
              // 直接瞬间移动到最后的假图片上
              list.style.left = -5 * 650 + 'px';
              // 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
              setTimeout(function () {
                  // 加过渡
                  list.style.transition = 'left .5s ease 0s';
                  // idx改为真正的最后一张
                  idx = 4;
                  list.style.left = -idx * 650 + 'px';
              }, 0);
          } else {
              idx--;
              list.style.left = -idx * 650 + 'px';
          }
          // 函数节流
          setTimeout(function () {
              lock = true;
          }, 500);
      }
复制代码

需要注意的是,如果已经是第一张图,那么点击左按钮时要取消过渡然后瞬间移动到克隆图片上,然后再加上过渡移动到真正的最后一张图片上,这里恢复过渡时利用了setTimeout是为了让取消过渡的瞬移起效果,不然瞬间移动还是会有过渡效果。

2-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>
  * {
    margin: 0;
    padding: 0;
  }

  .carousel {
    width: 650px;
    height: 360px;
    border: 1px solid #000;
    margin: 50px auto;
    position: relative;
    overflow: hidden;
  }

  .carousel ul {
    list-style: none;
    width: 6000px;
    position: relative;
    left: 0px;
    transition: left .5s ease 0s;
  }

  .carousel ul li {
    float: left;
  }

  .carousel .leftbtn {
    position: absolute;
    left: 20px;
    top: 50%;
    margin-top: -25px;
    width: 50px;
    height: 50px;
    background-color: rgb(226, 68, 28);
    border-radius: 50%;
  }

  .carousel .rightbtn {
    position: absolute;
    right: 20px;
    top: 50%;
    margin-top: -25px;
    width: 50px;
    height: 50px;
    background-color: rgb(226, 68, 28);
    border-radius: 50%;
  }
</style>
</head>

<body>
<div class="carousel">
  <ul id="list">
    <li><img src="images/beijing/0.jpg" alt=""></li>
    <li><img src="images/beijing/1.jpg" alt=""></li>
    <li><img src="images/beijing/2.jpg" alt=""></li>
    <li><img src="images/beijing/3.jpg" alt=""></li>
    <li><img src="images/beijing/4.jpg" alt=""></li>
  </ul>
  <!-- href写成空的javascript以防止页面刷新 -->
  <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
  <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
  // 得到按钮和ul,ul整体进行运动
  var leftbtn = document.getElementById('leftbtn');
  var rightbtn = document.getElementById('rightbtn');
  var list = document.getElementById('list');

  // 克隆第一张图片追加到list中
  var cloneLi = list.firstElementChild.cloneNode(true);
  list.appendChild(cloneLi);

  // 表示滚动到了第几个图片
  var idx = 0;
  // 设置一个节流锁,防止快速点击
  var lock = true;
  rightbtn.onclick = function () {
    if (!lock) { return }
    lock = false;
    // 为了防止滚动到最后最后一张图后快速移动图片置第一张后去除掉了动画,要在点击时添加一遍
    list.style.transition = 'left .5s ease 0s';
    idx++;
    if (idx > 4) {
      // 在动画0.5s执行完毕后瞬间将list的left值置为0
      setTimeout(() => {
        list.style.transition = 'none';
        list.style.left = 0;
        idx = 0;
      }, 500)
    }
    // 这里每张图片宽度是650px
    list.style.left = -idx * 650 + 'px';
    setTimeout(() => {
      lock = true
    }, 500);
  }

  leftbtn.onclick = function () {
    if (!lock) { return }
    lock = false;
    if (idx == 0) {
      list.style.transition = 'none';
      // 直接瞬间移动到最后的假图片上
      list.style.left = -5 * 650 + 'px';
      // 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
      setTimeout(function () {
        // 加过渡
        list.style.transition = 'left .5s ease 0s';
        // idx改为真正的最后一张
        idx = 4;
        list.style.left = -idx * 650 + 'px';
      }, 0);
    } else {
      idx--;
      list.style.left = -idx * 650 + 'px';
    }
    setTimeout(() => {
      lock = true
    }, 500)
  }
</script>
</body>
</html>
复制代码

总结:跑马灯轮播图的要点是,所有的图片以浮动的方式排成一排,父元素改变left值进行移动;此外为了能够起到轮播的效果,要克隆第一张图片拼接到最后:

  • 在移动到最后一张图片再次向后移动时,先移动到克隆图片上,然后再瞬间让left变为0再进行移动(如果有过渡动画需要注意需要设置延时器,在动画效果结束后再重置回去)
  • 在移动到第一张图片再次先前移动时,需要先瞬移到克隆图片上,然后再移动到真正的最后一张图片上

三、呼吸灯轮播图特效

3-1、实现原理

与跑马灯轮播图特效不同的是,呼吸灯特效需要各个轮播图堆叠在一起,以上一张“淡出”下一张“淡入”的方式来实现效果,也不需要克隆第一张图拼接到最后。

  • 首先使用定位的方式,让各个轮播图堆叠展示,将第一张轮播图的opacity置为1,其余轮播图置为0,为了实现淡出淡入效果,可为ul添加opacity的过渡动画
  • 当点击左/右按钮时,让当前轮播图的opacity变为0,上一张/下一张轮播图的opacity变为1即可
  • 同样需要节流锁的使用,比如过渡动画时间为1s则锁打开的时长也设置为1s

3-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>
      * {
        margin: 0;
        padding: 0;
      }
      
      .carousel {
        width: 650px;
        height: 360px;
        border: 1px solid #000;
        margin: 50px auto;
        position: relative;
        
      }
      
      .carousel ul {
        list-style: none;
      }
      
      .carousel ul li {
        position: absolute;
        top: 0;
        left: 0;
        /* 透明度都是0 */
        opacity: 0;
        transition: opacity 1s ease 0s;
      }
      
      /* 只有第一张透明度是1 */
      .carousel ul li:first-child {
        opacity: 1;
      }
      
      .carousel .leftbtn {
        position: absolute;
        left: 20px;
        top: 50%;
        margin-top: -25px;
        width: 50px;
        height: 50px;
        background-color: rgb(28, 180, 226);
        border-radius: 50%;
      }
      
      .carousel .rightbtn {
        position: absolute;
        right: 20px;
        top: 50%;
        margin-top: -25px;
        width: 50px;
        height: 50px;
        background-color: rgb(28, 180, 226);
        border-radius: 50%;
      }
    </style>
  </head>
  
  <body>
    <div class="carousel">
      <ul id="list">
        <li><img src="images/beijing/0.jpg" alt=""></li>
        <li><img src="images/beijing/1.jpg" alt=""></li>
        <li><img src="images/beijing/2.jpg" alt=""></li>
        <li><img src="images/beijing/3.jpg" alt=""></li>
        <li><img src="images/beijing/4.jpg" alt=""></li>
      </ul>
      <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
      <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>
    <script>
      // 得到按钮和ul,ul整体进行运动
      var leftbtn = document.getElementById('leftbtn');
      var rightbtn = document.getElementById('rightbtn');
      var list = document.getElementById('list');
      var lis = list.getElementsByTagName('li');
      
      // 当前是第几张图显示
      var idx = 0;
      
      // 节流
      var lock = true;
      
      // 右按钮
      rightbtn.onclick = function () {
        // 判断节流
        if (!lock) return;
        lock = false;
        // 还没有改idx,此时的idx这个图片就是老图,老图淡出
        lis[idx].style.opacity = 0;
        idx++;
        if (idx > 4) idx = 0;
        // 改了idx,此时的idx这个图片就是新图,新图淡入
        lis[idx].style.opacity = 1;
        
        // 动画结束之后,开锁
        setTimeout(function () {
          lock = true;
        }, 1000);
      }
      
      // 左按钮
      leftbtn.onclick = function () {
        // 判断节流
        if (!lock) return;
        lock = false;
        // 还没有改idx,此时的idx这个图片就是老图,老图淡出
        lis[idx].style.opacity = 0;
        idx--;
        if (idx < 0) idx = 4;
        // 改了idx,此时的idx这个图片就是新图,新图淡入
        lis[idx].style.opacity = 1;
        // 动画结束之后,开锁
        setTimeout(function () {
          lock = true;
        }, 1000);
      }
    </script>
  </body>
  
</html>
复制代码

Guess you like

Origin juejin.im/post/7078969683608616974