Patrick Wied https://twitter.com/patrickwied 受到一个漂亮的 YouTube 音频可视化工具的启发, 心想,"嗨, 为什么我不开发一个自己的音乐可视化程序呢?"
(请使用谷歌浏览器观看演示)
观看演示
本文里将介绍 Patrick Wied 开发出这种效果使用的技术. 尽管 webGL 和 Canvas 2D 技术看起来都非常的有前途(而且很有趣, 本人更喜欢多学一点 WebGL 知识!), 但对于 Patrick Wied 想实现的这个功能, 使用纯 html, 利用 CSS3 来实现动画效果, 足够了(将来 Patrick Wied 有计划将它迁移到其它技术上).
这个试验特别的有趣, 对 Patrick Wied 来说这是他第一次运用学习的数学知识到编程中. 尽管涉及到的数学部分很浅显, Patrick Wied 还是对能掌握一些东西的工作原理感到非常的兴奋.
下面就来讲一讲 Patrick Wied 是如何实现它的.
获取音频数据
可视化的前提是需要获取音频数据. 幸运的是, 现代浏览器 (谷歌浏览器, 火狐浏览器等) 里的 Web Audio API 对 Web 音频提供了丰富的操作功能. 这里最重要是调用 AnalyserNode.AnalyserNode 将会给我们提供实时的音频数据, 用于可视化显示. 关于更详细的音频操作, 可以阅读 w3c Web Audio Specs.
下面里看看为获取音频数据做的准备.
首先我们需要在页面上添加一个 < audio > 标记, 并指定音频源为你想要可视化的音乐文件.
<audio id="myAudio" src="path-to-audio.mp3"></audio>
下面是如何使用 AnalyserNode 获取数据:
- Windows.AudioContext = Windows.AudioContext || Windows.webkitAudioContext || Windows.mozAudioContext;
- Windows.onload = function() {
- var ctx = new AudioContext();
- var audio = document.getElementById('myAudio');
- var audioSrc = ctx.createMediaElementSource(audio);
- var analyser = ctx.createAnalyser();
- // we have to connect the MediaElementSource with the analyser
- audioSrc.connect(analyser);
- // we could configure the analyser: e.g. analyser.fftSize (for further infos read the spec)
- // frequencyBinCount tells you how many values you'll receive from the analyser
- var frequencyData = new Uint8Array(analyser.frequencyBinCount);
- // we're ready to receive some data!
- // loop
- function renderFrame() {
- requestAnimationFrame(renderFrame);
- // update data in frequencyData
- analyser.getByteFrequencyData(frequencyData);
- // render frame based on values in frequencyData
- // console.log(frequencyData)
- }
- audio.start();
- renderFrame();
- };
分析音频数据
现在我们有了非常不错的音乐和数据. Patrick Wied 测试过不少首歌曲, 发现 frequencyData 在 [0, 255] 之间的数据才有意义. 而且有些地方 frequencyData 的数据始终是 0-- 删除它们能更好的表现视觉动画, 但很可能丢失了一下音频信息.
视觉化音频数据
这是最有趣的部分. Patrick Wied 先实现了一个柱状条样式的动画效果, 每个柱子都表示 frequencyData 里的一组数据. 每个柱子都是用纯 HTML 实现的, 它的高度是使用 CSS 根据音频数据分析结果即时改变. 为了让动画更加顺滑, Patrick Wied 将 CSS 动画的 transition 属性设置为 0.1 秒.
更有趣的效果 -- 辐射状动画
其实也是很简单, 但需要运用更多的技巧. 为了让物体按环状对齐, 需要使用几何函数(还记得 Cos & Sin 吧?)
- // a full circle
- var twoPi = 2*Math.PI;
- var objectsCount = 12;
- var radius = 100
- // you want to align objectsCount objects on the circular path
- // with constant distance between neighbors
- var change = twoPi/objectsCount;
- for (var i=0; i < twoPi; i+=change) {
- var x = radius*cos(i);
- var y = radius*sin(i);
- // rotation of object in radians
- var rotation = i;
- // set the CSS properties to calculated values
- }
想要实现更奇特的效果? 你实际上是可以在这个 2D 空间里使用任何的弧形, 比如, 心型, 泪滴型等等. 但我还是更喜欢传统的视觉效果.
观看演示
希望你喜欢这篇文章. 请在评论里让我知道你的想法.
来源: http://www.webhek.com/post/create-audio-visualizations-with-javascript-and-css.html