You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过JavaScript实现CSS动画与音频雷声(峰值)同步

解决方案

步骤1:调整CSS动画触发逻辑

先把原有的自动播放动画改成通过类名触发,这样就能在检测到雷声时动态启动动画:

div {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
}

@keyframes mymove {
  from {top: 0px;}
  to {top: 200px;}
}

/* 通过类名触发动画 */
.trigger-animation {
  animation: mymove 5s 1 ease-in-out;
}

步骤2:用Web Audio API检测音频峰值

利用Web Audio API的AnalyserNode实时获取音频数据,计算音量峰值,当超过设定阈值时触发动画,同时加入冷却机制避免重复触发:

<div id="animated-box"></div>

<script>
let audioContext;
let analyser;
let dataArray;
let isCoolingDown = false; // 防止动画短时间重复触发
const volumeThreshold = 0.2; // 音量阈值,可根据实际音频微调

window.onload = async function() {
  try {
    // 初始化音频上下文
    audioContext = new (window.AudioContext || window.webkitAudioContext)();
    analyser = audioContext.createAnalyser();
    analyser.fftSize = 256;
    const bufferLength = analyser.frequencyBinCount;
    dataArray = new Uint8Array(bufferLength);

    // 加载并解码音频文件
    const audioRes = await fetch('./070115-glorious-early-morning-t-storm-19045.mp3');
    const audioBuffer = await audioRes.arrayBuffer();
    const decodedAudio = await audioContext.decodeAudioData(audioBuffer);

    // 创建音频源并连接分析器
    const audioSource = audioContext.createBufferSource();
    audioSource.buffer = decodedAudio;
    audioSource.connect(analyser);
    analyser.connect(audioContext.destination);
    
    // 播放音频
    audioSource.start();

    // 启动实时音量检测
    monitorVolume();
  } catch (err) {
    console.error('音频加载失败:', err);
  }
};

function monitorVolume() {
  // 获取音频频率数据
  analyser.getByteFrequencyData(dataArray);
  
  // 计算归一化后的平均音量(0-1范围)
  let total = 0;
  for (let val of dataArray) total += val;
  const avgVolume = total / (dataArray.length * 255);

  // 音量达标且不在冷却时触发动画
  if (avgVolume > volumeThreshold && !isCoolingDown) {
    const box = document.getElementById('animated-box');
    // 重置动画:先移除类再重新添加,强制浏览器重绘
    box.classList.remove('trigger-animation');
    void box.offsetWidth;
    box.classList.add('trigger-animation');

    // 设置冷却时长(和动画时长一致,避免重复触发)
    isCoolingDown = true;
    setTimeout(() => isCoolingDown = false, 5000);
  }

  // 循环检测
  requestAnimationFrame(monitorVolume);
}
</script>

注意事项

  • 阈值调整:volumeThreshold的值需要根据音频实际情况微调,雷声音量远大于雨声,可在0.1-0.3区间测试找到合适值。
  • 浏览器限制:现代浏览器要求音频播放必须由用户交互触发(比如点击按钮),如果window.onload触发失败,建议把播放逻辑绑定到按钮点击事件上。

内容的提问来源于stack exchange,提问作者user1286956

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:52:40