深浅模式
CSS 实现无限滚动效果
更新: 2024/6/1 字数: 0 字 时长: 0 分钟
🔈 前言:无限滚动是一种常见的 UI 效果,常用于展示标签、图片轮播等场景。本文将介绍如何使用 CSS 和少量 JavaScript 实现平滑的无限滚动效果。
基本原理
无限滚动的核心原理是通过 CSS 动画移动元素,并通过复制内容来实现视觉上的无缝衔接。当内容滚动到一定位置时,通过位移动画让内容看起来是无限循环 的。
实现代码
首先,我们需要创建 HTML 结构(这里使用了 vue3 + ts + setup 和 tailwind css, 请根据实际情况进行修改):
html
<div class="swiper py-4 overflow-hidden">
<div
ref="swiperWrapper"
@mouseenter="iaPlay = false"
@mouseleave="iaPlay = true"
class="swiper-wrapper w-max flex gap-2"
:style="{ animationPlayState: iaPlay ? 'running' : 'paused' }"
:data-animated="true"
>
<div class="swiper-container flex-1 flex gap-2" v-for="i in 2" :key="i">
<!-- 这里复制了一份内容,方便做无缝衔接 -->
<div class="swiper-item rounded-3xl px-5 py-2" v-for="(tag, index) in allTags" :key="index">
<!-- 这里就是需要滚动的元素 -->
<a class="tag-item whitespace-nowrap text-base cursor-pointer"> # {{ tag }} </a>
</div>
</div>
</div>
</div>然后,添加 CSS 样式实现动画效果:
css
.swiper-wrapper[data-animated="true"] {
animation: scroll 10s linear infinite;
}
@keyframes scroll {
to {
transform: translateX(-50%);
}
}最后,添加 JavaScript 控制动画的播放和暂停:
javascript
const swiperWrapper = ref<HTMLElement>(); // 获取swiperWrapper元素(获取dom)
const iaPlay = ref<boolean>(true); // swiper是否播放实现要点解析
内容复制:通过
v-for="i in 2"复制一份完全相同的内容,确保滚动时有足够的内容可以衔接。动画控制:
- 使用 CSS 动画
animation: scroll 10s linear infinite实现无限循环 - 动画时间可以根据内容长度调整,这里使用 10 秒
linear确保匀速滚动,提供更平滑的视觉体验
- 使用 CSS 动画
用户交互:
- 当鼠标悬停时(
@mouseenter="iaPlay = false"),暂停滚动 - 当鼠标离开时(
@mouseleave="iaPlay = true"),恢复滚动 - 通过
:data-animated="true"作为一个标记,用于控制动画状态
- 当鼠标悬停时(
关键动画技巧:
transform: translateX(-50%)使内容移动自身宽度的一半- 由于我们复制了一份内容,当第一份内容完全滚出时,第二份内容正好完全滚入,视觉上形成无缝衔接
适用场景
这种无限滚动效果适用于:
- 标签云展示
- 图片轮播
- 新闻滚动条
- 产品展示轮播
性能优化
为了提高性能,可以考虑以下几点:
- 使用
transform而非left/top属性进行动画,利用 GPU 加速 - 为动画元素添加
will-change: transform提示浏览器做优化准备 - 根据实际需求调整动画速度和内容数量
兼容性处理
对于不支持 CSS 动画的旧浏览器,可以使用 JavaScript 实现类似效果:
javascript
// 兼容性处理示例
if (!CSS.supports("animation", "scroll 10s linear infinite")) {
// 使用JavaScript实现滚动效果
const scrollElement = () => {
const wrapper = document.querySelector(".swiper-wrapper");
let position = 0;
setInterval(() => {
position -= 1;
if (position <= -50) {
position = 0;
}
wrapper.style.transform = `translateX(${position}%)`;
}, 100);
};
scrollElement();
}总结
无限滚动是一种优雅的内容展示方式,通过 CSS 动画和简单的 JavaScript 交互,我们可以轻松实现这一效果。关键在于理解动画原理和内容复制的技巧,以 及如何通过用户交互来控制动画状态。