分享一个类似轮播图的账号切换效果

看成品

首先完成一个轮播图

 <style>
  * {
      box-sizing: border-box;
  }

  .box {
      display: flex;
      height: 400px;
      overflow: auto;
      scroll-snap-type: x mandatory;      /* 横向滚动到一定程度,自动吸附反向上的下一个元素 */
      align-items: center;
  }

  .it {
      height: 200px;
      width: 200px;
      flex-grow: 0;
      flex-shrink: 0;
      scroll-snap-align: center;        /* 被吸附的时候, 自动在视图居中*/
      display: flex;
      justify-content: center;
      align-items: center;
  }
  .it:last-of-type, .it:first-of-type{
      width: calc((100% - 200px) / 2);       /* 用于占位, 确保下一张图片可以居中显示, 一个轮播图是200px的宽度,相当于给第一张轮播图加了左边距*/
  }

  .inner {
      transition: transform 0.3s;
      border-radius: 50%;
      height: 100px;
      width: 100px;
      transform: translateY(60px);
  }

  .active .inner {
      transform: scale(2) translateY(0); /* 放大效果 */
  }
  .box::-webkit-scrollbar {
      display: none;
  }

</style>
<div class="box" id="carousel">
    <div class="it"></div>       /* 用于占位, 确保下一张图片可以居中显示 */
    <div class="it">
        <img class="inner" src="img/img.png">
    </div>
    <div class="it">
        <img class="inner" src="img/img_1.png">
    </div>
    <div class="it">
        <img class="inner" src="img/img_2.png">
    </div>
    <div class="it">
        <img class="inner" src="img/img_3.png">
    </div>
    <div class="it">
        <img class="inner" src="img/img_4.png">
    </div>
    <div class="it"></div>    /* 用于占位, 确保下一张图片可以居中显示 */
</div>

<div id="currentPage" style="text-align: center">Current Page: 1</div>

js 主要处理,给吸附上的元素增加 .action

  <script>
    const carousel = document.getElementById('carousel');
    const items = carousel.children;

    const currentPageDisplay = document.getElementById('currentPage');

    function getCurrentPage() {
        let closestIndex = 0;
        let closestDistance = Infinity;

        for (let i = 1; i < items.length-1; i++) {
            const rect = items[i].getBoundingClientRect();
            const carouselRect = carousel.getBoundingClientRect()
            const distance = Math.abs(rect.left + rect.width / 2 - carouselRect.left - carouselRect.width / 2);
            if (distance < closestDistance) {
                closestDistance = distance;
                closestIndex = i;
                for (let i = 0; i < items.length; i++) {
                    items[i].classList.remove('active')
                }
                items[i].classList.add('active')
            }
        }

        return closestIndex
    }

    carousel.addEventListener('scroll', () => {
        const currentPage = getCurrentPage();
        currentPageDisplay.innerText = `Current Page: ${currentPage}`;
    });

    //第一次还没有滚动,所以不会正常的添加 .action, 需要在运行的时候加载一次 
    window.addEventListener('load', () => {
        const currentPage = getCurrentPage();
        currentPageDisplay.innerText = `Current Page: ${currentPage}`;
    });
</script>
posted @ 2024-06-01 22:03  探索星空  阅读(8)  评论(0编辑  收藏  举报