1

项目当前,当我将鼠标悬停在 HTML 元素上时,会播放一首歌曲。现在,我想创建一个与该声音(弹跳或振动效果)做出反应的简单圆圈,我只是不知道在哪里可以实现那种东西,可能是普通的 Javascript 或 Web Audio API?

播放声音的代码:

 $('.item').on('mouseenter', function(){
    itemId = $(this).attr('data-id');

    if (document.getElementById(coverId).tagName == 'AUDIO' ) {
        $('#' + itemId).trigger("play");
    }
});
$('.item').on('mouseleave', function(){
    itemId = $(this).attr('data-id');

    if (document.getElementById(itemId).tagName == 'AUDIO' ) {
        // For audio replay
        var audio = document.getElementById(itemId);
        audio.pause();
        audio.currentTime = 0;
        audio.load();
    } else {
        $('#' + itemId).trigger("pause");
    }
});

任何帮助将不胜感激!谢谢!

4

1 回答 1

3

这不是太复杂。首先,您需要通过 Web Audio API 加载音频 - 您可以使用 AJAX 请求直接执行此操作,或使用您点击的音频元素。然后:

  • 为 FFT 数据创建分析器节点
  • 确定动画所需的频带(必要时平均多个和/或添加过滤器节点)
  • 使用该值设置圆的 f.ex 半径

请注意,您正在加载的音频必须来自同一来源或由允许跨域使用的服务器提供。

另请注意,IE 不支持Web Audio API 。

例子

警告:在运行代码之前检查你的音量!

根据需要采用 -

window.AudioContext = window.AudioContext || window.webkitAudioContext;

var ctx = c.getContext("2d"),                  // canvas context
    actx = new AudioContext(),                 // audio context
    cx = c.width * 0.5, cy = c.height * 0.5,   // center of canvas
    radiusMax = Math.min(cx, cy) - 20,         // circle min/max radii
    radiusMin = radiusMax * 0.1,
    analyzer, srcNode, bquad, fftLen, fft;     // audio nodes and FFT data

ctx.fillStyle = "#fff";
ctx.fillText("Loading audio...", 10, 10);

a.oncanplay = function() {

  if (srcNode) return;
  
  // link audio element and Web Audio API
  srcNode = actx.createMediaElementSource(this);
  
  // create filter node
  bquad = actx.createBiquadFilter();
  bquad.type = "lowpass";
  bquad.frequency.value = 250;
  
  // create FFT analyzer node
  analyser = actx.createAnalyser();
  analyser.fftSize = 256;

  // connect nodes: srcNode (input) -> analyzer -> destination (output)
  srcNode.connect(bquad);
  bquad.connect(analyser);
  
  // connnect source directly to output
  srcNode.connect(actx.destination);

  // create FFT data buffer
  fftLen = analyser.frequencyBinCount;
  fft = new Uint8Array(fftLen);
 
  // set up arc look
  ctx.lineWidth = 12;
  ctx.strokeStyle = "#09f";
  
  ctx.fillStyle = "rgba(0,0,0,0.16)";
  
  // start visual galore
  render()
};

function render() {

  // clear semi-transparent
  ctx.fillRect(0, 0, c.width, c.height);
  
  // fill FFT buffer
  analyser.getByteFrequencyData(fft);
  
  // average data from some bands
  v = (fft[1] + fft[2]) / 512;
  
  // draw arc using interpolated range with exp. of v
  ctx.beginPath();
  ctx.arc(cx, cy, radiusMin + (radiusMax - radiusMin) * v*v*v*v, 0, 6.28);
  ctx.closePath();
  ctx.stroke();
  
  // feedback effect
  ctx.drawImage(c, -8, -8, c.width + 16, c.height + 16);
  
  requestAnimationFrame(render)
}
body, #c {background:#000}
#c {border:1px solid #222}
<canvas id=c height=300></canvas><br>
<audio id=a crossOrigin="anonymous" autoplay loop 
       src="https://cdn.rawgit.com/epistemex/SO-Demo-3-in-1-video/gh-pages/k3n_thebattle_segbass.mp3">

音乐 © K3N / 可免费分发用于测试目的。

于 2016-05-04T07:32:35.727 回答