事关我再次接触到css实现无缝轮播

1,180 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

css实现无缝轮播

写在前面: 之前在大学自学前端的时候,用transform和animation实现过一个轮播图,最近看见coco大佬利用步骤缓动函数和补间动画实现了无缝轮播图的效果,遂记录在册.

无缝轮播图效果

image.png

大学版本的轮播图实现逻辑

当时代码能力很初级,其实代码和逻辑都比较简单,就是给定了一个父元素框设置固定高度然后overflo:hidden,然后再用一个子元素包裹内容,设置一个动画函数无限播放,以及在元素末尾增加和第一个一样的元素,从而实现轮播效果.

步骤缓动函数和补间动画实现轮播

两个概念

animation-timing-function指定动画将如何完成一个周期。

css的animation中,有一种描述动画变化速率的东西,例如常见的linear,ease-in,ease-out等,这些都是连续的变化,还有一种叫做steps的,它用来描述一种不连续的动画,也就是逐帧动画。

{
    // 
    animation-timing-function: step-start;
    animation-timing-function: step-end;
    
    animation-timing-functionsteps(6, start)
    animation-timing-function: steps(4, end);
}

正文开始

// HTML
<div class="g-container">
  <ul>
    <li>Lorem ipsum 1111111</li>
    <li>Lorem ipsum 2222222</li>
    <li>Lorem ipsum 3333333</li>
    <li>Lorem ipsum 4444444</li>
    <li>Lorem ipsum 5555555</li>
    <li>Lorem ipsum 6666666</li>
  </ul>
</div>


// CSS
:root {
  // 轮播的个数
  --s6;
  // 单个 li 容器的高度
  --h36;
  // 单次动画的时长
  --speed1.5s;
}
.g-container {
  width300px;
  heightcalc(var(--h) * 1px);
}
ul {
  display: flex;
  flex-direction: column;
  animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
  width100%;
}

@keyframes move {
  0% {
    transformtranslate(00);
  }
  100% {
    transformtranslate(0calc(var(--s) * var(--h) * -1px));
  }
}


以上代码css代码通过根元素选择器设置了三个css变量,在下面的move动画中调用了这三个css变量

  • calc(var(--speed) * var(--s)):单次动画的耗时 * 轮播的个数,也就是总动画时长
  • steps(var(--s)) 就是逐帧动画的帧数,这里也就是 steps(6),很好理解
  • calc(var(--s) * var(--h) * -1px)) 单个 li 容器的高度 * 轮播的个数,其实就是 ul 的总体高度,用于设置逐帧动画的终点值

增加动画效果(补间动画)

ul li{
  height36px;
  animation: liMove calc(var(--speed)) infinite;
}

@keyframes liMove {
  0% {
    transformtranslate(00);
  }
  80%,
  100%  {
    transformtranslate(0, -36px);
  }
}

以上代码增加一个liMove动画,增加动画效果在上面move动画执行的时候同时执行,速度通过 --speed 统一控制.

最后效果优化

给外层容器添加overflow:hidden, 会发现最后存在空白元素,在HTML末尾复制第一条元素用以实现无缝轮播,

实现逻辑总结

  1. 利用逐帧动画,实现整体的轮播的循环效果
  2. 利用补间动画,实现个体的动画效果
  3. 容器添加overflow:hidden遮挡其他元素
  4. HTML尾部增加第一条数据实现无缝轮播

End