carousel无缝轮播图

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    button {
      width: 160px;
      height: 160px;
      background-color: red;
      border: none;
    }

    .box {
      width: 500px;
      height: 300px;
      position: relative;
      overflow: hidden;
      border: 1px solid red;
      margin: 0 auto;
    }

    .item {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      right: 0;
      /* opacity: 0; */
      will-change: transform;
      text-align: center;
      line-height: 300px;
      font-size: 160px;
    }

    .item:not(.current) {
      visibility: hidden;
    }

    .item.current {
      /* opacity: 1; */
      visibility: visible;
      /* position: relative; */
      z-index: 1;
    }


    .in {
      animation: slide-x-in .5s cubic-bezier(0.34, 0.69, 0.1, 1);
    }

    .out {
      animation: slide-x-out .5s cubic-bezier(0.34, 0.69, 0.1, 1);
    }

    .in-reverse {
      animation: slide-x-in-reverse .5s cubic-bezier(0.34, 0.69, 0.1, 1);
    }

    .out-reverse {
      animation: slide-x-out-reverse .5s cubic-bezier(0.34, 0.69, 0.1, 1);
    }

    .a0 {
      background-color: pink;
    }

    .a1 {
      background-color: rgb(66, 59, 60);
    }

    @keyframes slide-x-in {
      from {
        transform: translateX(100%);
      }

      to {
        transform: translateX(0);
      }
    }

    @keyframes slide-x-out {
      from {
        transform: translateX(0);
      }

      to {
        transform: translateX(-100%);
      }
    }

    @keyframes slide-x-in-reverse {
      from {
        transform: translateX(-100%);
      }

      to {
        transform: translateX(0);
      }
    }

    @keyframes slide-x-out-reverse {
      from {
        transform: translateX(0);
      }

      to {
        transform: translateX(100%);
      }
    }
  </style>
</head>

<body>
  <div id="box" class="box">
    <div id="a0" class="item a0">00000</div>
    <div id="a1" class="item a1">11111</div>
    <div id="a2" class="item a2">22222</div>
    <div id="a3" class="item a3">33333</div>
  </div>
  <button id="left">左边按钮</button>
  -------------
  <button id="right">右边按钮</button>
  -------------
  <ul>
    <li id="btn0">哈哈哈0</li>
    <li id="btn1">哈哈哈1</li>
    <li id="btn2">哈哈哈2</li>
    <li id="btn3">哈哈哈3</li>
  </ul>
  <script>
    let childList = Array.from(box.getElementsByClassName('item'));
    const childrenLength = 4;
    //0 1 2 3
    //点击inctor的目标index
    let targetIndex = 0;
    //index 选中的那张
    let index = 0;
    //是否正在动画过程中,一次只能一个动画
    let isAnimating = false;

    //选中的Index 卡片
    let currentIndex = getValidIndex(index);
    right.onclick = function (e) {
      if (isAnimating === true) return;
      currentIndex = getValidIndex(currentIndex + 1);
      slideTo({
        targetIndex: currentIndex
      })
    }
    left.onclick = function (e) {
      if (isAnimating === true) return;
      currentIndex = getValidIndex(currentIndex - 1);
      slideTo({
        targetIndex: currentIndex,
        inNegative: true //负向
      })
    }

    function getValidIndex(i) {
      const indexNumber = +i;
      return typeof indexNumber === 'number' && !isNaN(indexNumber) ?
        (indexNumber + childrenLength) % childrenLength : i;
    }

    //改变index时,重新求出,对应的index
    function changeIndex(index) {
      let current = getValidIndex(index)
      let prevIndex = getValidIndex(index - 1);
      let nextIndex = getValidIndex(index + 1);
      // let targetIndex = index;
      return [current, prevIndex, nextIndex]
    }

    // 核心滚动FN逻辑
    function slideTo({
      targetIndex,
      inNegative = false, //移动方向,正向 or 负向
      isManual = false, //是否是手动 触发
      resetAutoPlayInterval = false, //autoplay时的,重置计时器
    }) {
      //
      isAnimating = true;
      //上 下
      let [current, prevIndex, nextIndex] = changeIndex(targetIndex);
      //过渡动画的类名
      if (inNegative) {
        //负方向动画类名
        childList[current].classList.add('in-reverse');
        childList[nextIndex].classList.add('out-reverse');
      } else {
        //正方向动画类名
        childList[current].classList.add('in');
        childList[prevIndex].classList.add('out');
      }

      //改变元素类名 prev,next,current
      init(current)
      setTimeout(() => {
        isAnimating = false;

        //删除旧的元素类名 prev,next,current
        removeName(current, inNegative)
        //delete过渡动画的类名
        if (inNegative) {
          childList[current].classList.remove('in-reverse');
          childList[nextIndex].classList.remove('out-reverse');
        } else {
          childList[current].classList.remove('in');
          childList[prevIndex].classList.remove('out');
        }
      }, 500)
    }

    function addName(index) {
      let [current, prevIndex, nextIndex] = changeIndex(index);
      childList[prevIndex].classList.add('prev');
      childList[nextIndex].classList.add('next');
      childList[current].classList.add('current');
    }

    function removeName(index, inNegative) {
      let _index = inNegative ? index + 1 : index - 1;
      console.log(_index, 'index');
      let [current, prevIndex, nextIndex] = changeIndex(_index);
      console.log(current, prevIndex, nextIndex, 'remove', _index)
      childList[prevIndex].classList.remove('prev');
      childList[nextIndex].classList.remove('next');
      childList[current].classList.remove('current');
    }

    function init(index) {
      addName(index);
    }
    init(0)

    // btn0.onclick = () => {
    //   // currentIndex current
    //   historyIndex = currentIndex;
    //   currentIndex = 0;
    //   slideTo({
    //     targetIndex: currentIndex,
    //     inNegative: historyIndex > currentIndex, //负向
    //     isManual: true,
    //   })
    // }


    //核心原理,current visibility: visible;
    //其他不带current的元素 visibility: hidden;
    //动画过程中,500ms,存在2个current,2个同时平移,
      
    //in    一个进入动画
    // from: transform: translateX(100%);
    // to : transform: translateX(0);

    // out 一个出的动画
    //   from {
    //     transform: translateX(0);
    //   }
    //   to {
    //     transform: translateX(-100%);}
  </script>
</body>
<script>




</script>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值