使用 @keyframes 和 animation-play-state 创建多种加载指示器
使用 rotate 实现的经典加载器
使用 scale 实现的脉冲效果
使用 opacity 实现的渐变效果
组合 scale 和 translateY 的弹跳效果
依次显示1个、2个、3个点的循环效果
💡 提示:点击单个按钮控制对应动画,或使用"暂停所有"控制全部
创建不同类型的加载器容器:
<div class="spinner spinner-classic"></div>
<div class="spinner spinner-pulse"></div>
<div class="spinner spinner-dots">
<span></span>
<span></span>
<span></span>
</div>
<div class="spinner spinner-bounce">
<span></span>
<span></span>
<span></span>
</div>
<div class="spinner spinner-progressive">
<span></span>
<span></span>
<span></span>
</div>
为每种加载器创建关键帧动画:
/* 经典旋转动画 */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* 脉冲缩放动画 */
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.5);
opacity: 0.5;
}
}
/* 渐变动画 */
@keyframes fade {
0%, 100% {
opacity: 0.2;
}
50% {
opacity: 1;
}
}
/* 弹跳动画 */
@keyframes bounce {
0%, 100% {
transform: translateY(0) scale(1);
}
50% {
transform: translateY(-20px) scale(0.8);
}
}
/* 渐进点动画 - 第1个点 */
@keyframes progressiveDot1 {
0% {
opacity: 1;
transform: scale(1);
}
75% {
opacity: 1;
}
85% {
opacity: 0;
transform: scale(0);
}
}
/* 渐进点动画 - 第2个点 */
@keyframes progressiveDot2 {
0%, 25% {
opacity: 0;
transform: scale(0);
}
30% {
opacity: 1;
transform: scale(1);
}
75% {
opacity: 1;
}
85% {
opacity: 0;
}
}
/* 渐进点动画 - 第3个点 */
@keyframes progressiveDot3 {
0%, 50% {
opacity: 0;
transform: scale(0);
}
55% {
opacity: 1;
transform: scale(1);
}
75% {
opacity: 1;
}
85% {
opacity: 0;
}
}
使用 animation 属性应用动画:
/* 经典旋转 */
.spinner-classic {
width: 50px;
height: 50px;
border: 4px solid var(--gray-200);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* 脉冲缩放 */
.spinner-pulse {
width: 50px;
height: 50px;
background: var(--primary);
border-radius: 50%;
animation: pulse 1.5s ease-in-out infinite;
}
/* 渐变点 */
.spinner-dots span {
width: 12px;
height: 12px;
background: var(--primary);
border-radius: 50%;
animation: fade 1.4s ease-in-out infinite;
}
.spinner-dots span:nth-child(2) {
animation-delay: 0.2s;
}
.spinner-dots span:nth-child(3) {
animation-delay: 0.4s;
}
/* 渐进点 - 依次显示1个、2个、3个点 */
.spinner-progressive span {
width: 12px;
height: 12px;
background: var(--primary);
border-radius: 50%;
opacity: 0;
transform: scale(0);
}
.spinner-progressive span:nth-child(1) {
animation: progressiveDot1 2s ease-in-out infinite;
}
.spinner-progressive span:nth-child(2) {
animation: progressiveDot2 2s ease-in-out infinite;
}
.spinner-progressive span:nth-child(3) {
animation: progressiveDot3 2s ease-in-out infinite;
}
通过 JavaScript 切换 animation-play-state:
/* CSS 暂停状态 */
.spinner.paused {
animation-play-state: paused;
}
.spinner.paused * {
animation-play-state: paused;
}
// JavaScript 控制
const spinner = document.querySelector('.spinner-classic');
const button = document.querySelector('[data-toggle]');
button.addEventListener('click', () => {
spinner.classList.toggle('paused');
if (spinner.classList.contains('paused')) {
button.textContent = '▶️ 播放';
} else {
button.textContent = '⏸️ 暂停';
}
});