代码之家  ›  专栏  ›  技术社区  ›  user990463

播放音频时创建弹跳圆

  •  1
  • user990463  · 技术社区  · 8 年前

    item当前,当我悬停在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");
        }
    });
    

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

    1 回复  |  直到 8 年前
        1
  •  3
  •   user1693593 user1693593    8 年前

    这并不太复杂。首先,您需要通过Web audio API加载音频-您可以使用AJAX请求直接加载,也可以使用您点击的audio元素。然后:

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

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

    还请注意,Web Audio API是 not supported in IE .

    实例

    警告:运行代码前请检查音频音量!

    根据需要采用-

    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/可自由分发,用于测试目的。