浅析如何利用逐帧动画配合补间动画实现一个无限循环的文字及图片轮播效果

  今天,分享一个实际业务中能够用得上的动画技巧。巧用逐帧动画,配合补间动画实现一个无限循环的轮播效果.

  有同学不禁会发问,这不是个非常简单的位移动画么?我们来简单分析分析,从表面上看,确实好像只有元素的 transfrom: translate() 在位移,但是注意,这里有2个需要注意的点:

(1)这是个无限轮播的效果,我们的动画需要支持任意多个元素的无限轮播切换

(2)因为是轮播,所以,运行到最后一个的时候,需要动画切到第一个元素(注意我们追求的是无缝切换,看到过很多网站这种切换是很突兀的切换)

  所以到这里,你可以暂停思考一下,如果有 20 个元素,需要进行类似的无限轮播播报,使用 CSS 实现,你会怎么去做呢?

一、逐帧动画控制整体切换

  首先,我需要利用到逐帧动画效果,也被称为步骤缓动函数,利用的是 animation-timing-function 中,的 steps,语法如下:

复制代码
{
    /* Keyword values */
    animation-timing-function: step-start;
    animation-timing-function: step-end;
    /* Function values */
    animation-timing-function: steps(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>// 在这里,要实现轮播效果,并且是任意个数,我们可以借助 animation-timing-function: steps():
:root {
  // 轮播的个数
  --s: 6;
  // 单个 li 容器的高度
  --h: 36;
  // 单次动画的时长
  --speed: 1.5s;
}
.g-container {
  width: 300px;
  height: calc(var(--h) * 1px);
}
ul {
  display: flex;
  flex-direction: column;
  animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
  width: 100%;
}
@keyframes move {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, calc(var(--s) * var(--h) * -1px));
  }
}
复制代码

  别看到上述有几个 CSS 变量就慌了,其实很好理解:

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

  上述的效果,实际如下:

  如果给容器添加上 overflow: hidden,就是这样的效果:

  这样,我们就得到了整体的结构,至少,整个效果是循环的。

  但是由于只是逐帧动画,所以只能看到切换,但是每一帧之间,没有过渡动画效果。所以,接下来,我们还得引入补间动画。

二、利用补间动画实现两组数据间的切换

  我们需要利用补间动画,实现动态的切换效果。这一步,其实也非常简单,我们要做的,就是将一组数据,利用 transform,从状态 A 位移到 状态 B。

复制代码
:root {
  --h: 36;
  --speed: 1.2s;
}
ul li {
  height: 36px;
  animation: liMove calc(var(--speed)) infinite;
}
@keyframes liMove {
  0% {
    transform: translate(0, 0);
  }
  80%,
  100%  {
    transform: translate(0, -36px);
  }
}
复制代码

  基于上述效果,我们如果把一开始提到的 逐帧动画 和这里这个 补间动画 结合一下,ul 的整体移动,和 li 的 单个移动叠在在一起,就能得到这样一个效果:

  基于 逐帧动画补间动画 的结合,我们几乎实现了一个轮播效果。当然,有一点瑕疵,可以看到,最后一组数据,是从第六组数据 transform 移动向了一组空数据:

  解决方案:末尾填充头部第一组数据。实际开发过轮播的同学肯定知道,这里,其实也很好处理,我们只需要在末尾,补一组头部的第一个数据即可

  那么要实现横向无限轮播及轮播图的话,都是一样的原理

  下面总结一下:

1、利用 逐帧动画,实现整体的轮播的循环效果

2、利用 补间动画,实现具体的 状态A 向 状态B 的动画效果

3、逐帧动画 配合 补间动画 构成整体轮播的效果

4、通过向 HTML 结构末尾补充一组头部数据,实现整体动画的衔接

5、通过 HTML 元素的 style 标签,利用 CSS 变量,填入实际的参与循环的 DOM 个数,可以实现 JavaScript 与 CSS 的打通

  详见这篇文章:https://mp.weixin.qq.com/s/pSoSpuLXfeghfMvEfl38WA

posted @   古兰精  阅读(274)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示