持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
css实现无缝轮播
写在前面: 之前在大学自学前端的时候,用transform和animation实现过一个轮播图,最近看见coco大佬利用步骤缓动函数和补间动画实现了无缝轮播图的效果,遂记录在册.
无缝轮播图效果
大学版本的轮播图实现逻辑
当时代码能力很初级,其实代码和逻辑都比较简单,就是给定了一个父元素框设置固定高度然后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-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>
// CSS
: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代码通过根元素选择器设置了三个css变量,在下面的move动画中调用了这三个css变量
calc(var(--speed) * var(--s)):单次动画的耗时 * 轮播的个数,也就是总动画时长steps(var(--s))就是逐帧动画的帧数,这里也就是steps(6),很好理解calc(var(--s) * var(--h) * -1px))单个 li 容器的高度 * 轮播的个数,其实就是 ul 的总体高度,用于设置逐帧动画的终点值
增加动画效果(补间动画)
ul li{
height: 36px;
animation: liMove calc(var(--speed)) infinite;
}
@keyframes liMove {
0% {
transform: translate(0, 0);
}
80%,
100% {
transform: translate(0, -36px);
}
}
以上代码增加一个liMove动画,增加动画效果在上面move动画执行的时候同时执行,速度通过
--speed统一控制.
最后效果优化
给外层容器添加
overflow:hidden, 会发现最后存在空白元素,在HTML末尾复制第一条元素用以实现无缝轮播,
实现逻辑总结
- 利用逐帧动画,实现整体的轮播的循环效果
- 利用补间动画,实现个体的动画效果
- 容器添加overflow:hidden遮挡其他元素
- HTML尾部增加第一条数据实现无缝轮播
End