动画-列表入场
2024/9/26大约 6 分钟
由右向左
效果展示
由右向左
<template>
<div class="animation-list">
<div class="list-right-to-left">
<div
class="list-item"
v-for="(item, index) in listTotal"
:key="index"
:style="{ 'animation-delay': index * 0.1 + 's' }"
></div>
</div>
</div>
</template>
<script>
const { ref, onBeforeUnmount } = Vue;
export default {
setup() {
const listTotal = ref(0);
function startAnimation() {
listTotal.value = 0;
setTimeout(() => {
listTotal.value = 6;
}, 300);
}
setInterval(() => {
startAnimation();
}, 5000);
startAnimation();
onBeforeUnmount(() => {
clearInterval(interval);
});
return {
listTotal,
};
},
};
</script>
<style scoped>
@keyframes right-to-left {
from {
margin-left: 100%;
width: 0;
opacity: 0;
}
to {
margin-left: 0%;
width: 100%;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
.animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-right-to-left {
width: 200px;
height: 240px;
overflow: hidden;
.list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation: right-to-left 0.6s ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
}
}
</style>
实现思路
- 列表动画开始之前,先将列表元素隐藏
opacity: 0
; - 动画开始时,将列表元素移到可视区域外
margin-left: 100%
,并且将宽度设置为 0width: 0
; - 动画进行时,将列表元素移到可视区域
margin-left: 0%
,将透明度还原opacity: 1
,将宽度还原width: 100%
; - 动画结束时,保持最后一帧的状态
animation-fill-mode: forwards
; - 使用原生 JavaScript 实现动画控制,通过动态创建元素并设置不同的动画延迟来实现交错效果。
实现代码
HTML
<div class="animation-list">
<div id="list-right-to-left" class="list-right-to-left">
<!-- 列表项将通过JavaScript动态生成 -->
</div>
</div>
CSS
@keyframes right-to-left {
from {
margin-left: 100%;
width: 0;
opacity: 0;
}
to {
margin-left: 0%;
width: 100%;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
}
.animation-list .animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-right-to-left {
width: 200px;
height: 240px;
overflow: hidden;
}
.list-right-to-left .list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation: right-to-left 0.6s ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
JS
function startRightToLeftAnimation() {
const container = document.getElementById("list-right-to-left");
container.innerHTML = ""; // 清空容器
setTimeout(() => {
// 创建6个列表项
for (let i = 0; i < 6; i++) {
const item = document.createElement("div");
item.className = "list-item";
item.style.animationDelay = `${i * 0.1}s`;
container.appendChild(item);
}
}, 300);
}
// 初始动画
startRightToLeftAnimation();
// 每3秒重复一次动画
setInterval(startRightToLeftAnimation, 5000);
由下向上
效果展示
由下向上
<template>
<div class="animation-list">
<div class="list-bottom-to-top">
<div
class="list-item"
v-for="(item, index) in listTotal"
:key="index"
:style="{ 'animation-delay': index * 0.1 + 's' }"
></div>
</div>
</div>
</template>
<script>
const { ref, onBeforeUnmount } = Vue;
export default {
setup() {
const listTotal = ref(0);
function startAnimation() {
listTotal.value = 0;
setTimeout(() => {
listTotal.value = 6;
}, 300);
}
const interval = setInterval(() => {
startAnimation();
}, 5000);
startAnimation();
onBeforeUnmount(() => {
clearInterval(interval);
});
return {
listTotal,
};
},
};
</script>
<style scoped>
@keyframes bottom-to-top {
from {
margin-top: 100%;
height: 0;
opacity: 0;
}
to {
margin-top: 0%;
height: 30px;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
.animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-bottom-to-top {
width: 200px;
height: 240px;
overflow: hidden;
.list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation: bottom-to-top 0.6s ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
}
}
</style>
HTML
<div class="animation-list">
<div id="list-bottom-to-top" class="list-bottom-to-top">
<!-- 列表项将通过JavaScript动态生成 -->
</div>
</div>
CSS
@keyframes bottom-to-top {
from {
margin-top: 100%;
height: 0;
opacity: 0;
}
to {
margin-top: 0%;
height: 30px;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
}
.animation-list .animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-bottom-to-top {
width: 200px;
height: 240px;
overflow: hidden;
}
.list-bottom-to-top .list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation: bottom-to-top 0.6s ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
JS
function startBottomToTopAnimation() {
const container = document.getElementById("list-bottom-to-top");
container.innerHTML = ""; // 清空容器
setTimeout(() => {
// 创建6个列表项
for (let i = 0; i < 6; i++) {
const item = document.createElement("div");
item.className = "list-item";
item.style.animationDelay = `${i * 0.1}s`;
container.appendChild(item);
}
}, 300);
}
// 初始动画
startBottomToTopAnimation();
// 每3秒重复一次动画
setInterval(startBottomToTopAnimation, 5000);
实现思路
- 列表动画开始之前,先将列表元素隐藏
opacity: 0
; - 动画开始时,将列表元素移到可视区域外
margin-top: 100%
,并且将高度设置为 0height: 0
; - 动画进行时,将列表元素移到可视区域
margin-top: 0%
,将透明度还原opacity: 1
,将高度还原height: 30px
; - 动画结束时,保持最后一帧的状态
animation-fill-mode: forwards
; - 使用原生 JavaScript 实现动画控制,通过动态创建元素并设置不同的动画延迟来实现交错效果。
交错
效果展示
交错
<template>
<div class="animation-list">
<div class="list-crossed">
<div
class="list-item"
v-for="(item, index) in listTotal"
:key="index"
:style="{
'animation-delay': index * 0.1 + 's',
'animation-name': index % 2 === 0 ? 'crossed-rb' : 'crossed-lb',
}"
></div>
</div>
</div>
</template>
<script>
const { ref, onBeforeUnmount } = Vue;
export default {
setup() {
const listTotal = ref(0);
function startAnimation() {
listTotal.value = 0;
setTimeout(() => {
listTotal.value = 6;
}, 300);
}
const interval = setInterval(() => {
startAnimation();
}, 5000);
startAnimation();
onBeforeUnmount(() => {
clearInterval(interval);
});
return {
listTotal,
};
},
};
</script>
<style scoped>
@keyframes crossed-rb {
from {
margin-left: 100%;
margin-top: 100%;
width: 0;
height: 0;
opacity: 0;
}
to {
margin-left: 0%;
margin-top: 0%;
width: 100%;
height: 30px;
opacity: 1;
}
}
@keyframes crossed-lb {
from {
margin-right: 100%;
margin-top: 100%;
width: 0;
height: 0;
opacity: 0;
}
to {
margin-right: 0%;
margin-top: 0%;
width: 100%;
height: 30px;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
.animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-crossed {
width: 200px;
height: 240px;
overflow: hidden;
.list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation-duration: 0.6s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
}
}
</style>
HTML
<div class="animation-list">
<div id="list-crossed" class="list-crossed">
<!-- 列表项将通过JavaScript动态生成 -->
</div>
</div>
CSS
@keyframes crossed-rb {
from {
margin-left: 100%;
margin-top: 100%;
width: 0;
height: 0;
opacity: 0;
}
to {
margin-left: 0%;
margin-top: 0%;
width: 100%;
height: 30px;
opacity: 1;
}
}
@keyframes crossed-lb {
from {
margin-right: 100%;
margin-top: 100%;
width: 0;
height: 0;
opacity: 0;
}
to {
margin-right: 0%;
margin-top: 0%;
width: 100%;
height: 30px;
opacity: 1;
}
}
.animation-list {
display: flex;
justify-content: center;
position: relative;
}
.animation-list .animation-btn {
width: 4em;
height: 28px;
position: absolute;
top: 10px;
left: 10px;
}
.list-crossed {
width: 200px;
height: 240px;
overflow: hidden;
}
.list-crossed .list-item {
height: 30px;
margin-bottom: 12px;
width: 200px;
background: LightSlateGray;
border-radius: 5px;
animation-duration: 0.6s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
opacity: 0;
}
JS
function startCrossedAnimation() {
const container = document.getElementById("list-crossed");
container.innerHTML = ""; // 清空容器
setTimeout(() => {
// 创建6个列表项
for (let i = 0; i < 6; i++) {
const item = document.createElement("div");
item.className = "list-item";
item.style.animationDelay = `${i * 0.1}s`;
item.style.animationName = i % 2 === 0 ? "crossed-rb" : "crossed-lb";
container.appendChild(item);
}
}, 300);
}
// 初始动画
startCrossedAnimation();
// 每3秒重复一次动画
setInterval(startCrossedAnimation, 5000);
实现思路
- 列表动画开始之前,先将列表元素隐藏
opacity: 0
; - 动画开始时,将列表元素移到可视区域外(偶数项从右下,奇数项从左下),并且将高度和宽度设置为 0
height: 0; width: 0
; - 动画进行时,将列表元素移到可视区域,将透明度还原
opacity: 1
,将高度和宽度还原height: 30px; width: 100%
; - 动画结束时,保持最后一帧的状态
animation-fill-mode: forwards
; - 使用原生 JavaScript 实现动画控制,通过动态创建元素并为奇偶项设置不同的动画名称和延迟来实现交错效果。
浏览器兼容性
相关信息
- 表格中的数字表示该浏览器开始支持的最低版本
- "No" 表示该浏览器不支持此功能
注意事项
- IE 浏览器兼容性:IE 11 及以下版本对部分 CSS 特性支持不完全
- 性能考虑:在移动设备上,大量的 CSS 动画可能会影响性能,建议适当优化动画复杂度
更新日志
2025/9/28 09:03
查看所有更新日志
38e56
-于8b50d
-于