先上效果图:

HTML文件:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>音频波形加载动画</title>
<!-- CSS File -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<main class="loader-container" role="main" aria-label="音频加载动画">
<!-- JavaScript将在这里动态生成loader -->
</main>
<script>
// 动态生成loader结构
function createLoaders(count = 3, barsPerLoader = 5) {
const container = document.querySelector('.loader-container');
for (let i = 0; i < count; i++) {
const loader = document.createElement('div');
loader.className = 'loader';
loader.setAttribute('aria-label', `音频波形 ${i + 1}`);
for (let j = 0; j < barsPerLoader; j++) {
const span = document.createElement('span');
span.setAttribute('aria-hidden', 'true');
loader.appendChild(span);
}
container.appendChild(loader);
}
}
// 页面加载完成后生成结构
document.addEventListener('DOMContentLoaded', () => {
createLoaders();
});
</script>
</body>
</html>
css文件:
css
/* 全局重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 页面布局 */
body {
height: 100vh;
display: grid;
place-items: center;
background: #100f13;
font-family: Arial, sans-serif;
}
/* Loader容器 - 支持多个loader并排显示 */
.loader-container {
display: flex;
align-items: center;
justify-content: center;
}
/* 单个Loader */
.loader {
height: 90px;
display: flex;
align-items: center;
transform: rotate(180deg);
}
/* Loader中的条形元素 */
.loader span {
width: 5px;
margin: 0 4px;
border-radius: 4px;
background: #ffffff;
will-change: height; /* 性能优化 */
}
/* 音频波形动画定义 - 使用CSS变量优化 */
@keyframes audioWave {
0%, 100% {
height: calc(var(--base-height) * 1px);
}
12% {
height: calc(var(--peak1) * 1px);
}
25% {
height: calc(var(--valley1) * 1px);
}
37% {
height: calc(var(--peak2) * 1px);
}
50% {
height: calc(var(--valley2) * 1px);
}
62% {
height: calc(var(--peak3) * 1px);
}
75% {
height: calc(var(--valley3) * 1px);
}
87% {
height: calc(var(--peak4) * 1px);
}
}
/* 每个span的音频波形动画 - 使用CSS变量复用 */
.loader span:nth-child(1) {
--base-height: 12;
--peak1: 68; --valley1: 25; --peak2: 82;
--valley2: 18; --peak3: 90; --valley3: 35; --peak4: 45;
animation: audioWave 1.8s infinite;
animation-delay: 0.1s;
}
.loader span:nth-child(2) {
--base-height: 20;
--peak1: 45; --valley1: 85; --peak2: 30;
--valley2: 95; --peak3: 15; --valley3: 75; --peak4: 60;
animation: audioWave 2.3s infinite;
animation-delay: 0.7s;
}
.loader span:nth-child(3) {
--base-height: 18;
--peak1: 78; --valley1: 40; --peak2: 88;
--valley2: 22; --peak3: 65; --valley3: 50; --peak4: 70;
animation: audioWave 1.9s infinite;
animation-delay: 0.3s;
}
.loader span:nth-child(4) {
--base-height: 15;
--peak1: 92; --valley1: 35; --peak2: 70;
--valley2: 25; --peak3: 85; --valley3: 50; --peak4: 65;
animation: audioWave 2.1s infinite;
animation-delay: 0.9s;
}
.loader span:nth-child(5) {
--base-height: 25;
--peak1: 55; --valley1: 90; --peak2: 20;
--valley2: 80; --peak3: 40; --valley3: 95; --peak4: 75;
animation: audioWave 2.4s infinite;
animation-delay: 0.5s;
}
/* 多个loader的动画延迟 */
.loader:nth-child(2) {
animation-delay: 0.3s;
}
.loader:nth-child(3) {
animation-delay: 0.6s;
}
喜欢的话比个心呦! :)