1

itemCurrently when I hover a HTML element, a song is played. Now, I would like to create a simple circle reacting with that sound (bouncing, or vibrating effect), I just don't know where to look to achieve that kind of stuff maybe plain Javascript or the Web Audio API ?

The code to play sound:

 $('.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");
    }
});

Any help would be very appreciated! Thanks!

user990463
  • 439
  • 1
  • 7
  • 27
  • Your question is definitely too broad for SO format, but have a look to canvas API or SVG, these are the API you want to work with for visual animations. – Kaiido May 02 '16 at 09:12
  • Check out this article about music visualisation https://www.bignerdranch.com/blog/music-visualization-with-d3-js/. – Nik Markin May 02 '16 at 09:50
  • Very helpful article, thanks NikMarkin ! – user990463 May 02 '16 at 12:31

1 Answers1

3

It's not too complicated. First you need to load the audio through Web Audio API - you can do this directly using a AJAX request, or use an Audio element which you tap into. Then:

  • Create a analyzer node for FFT data
  • Decide which frequency band(s) you want for the animation (average multiple if necessary and/or add a filter node)
  • Use that value to set f.ex radius of a circle

Note that the audio you're loading must be from same origin or provided by a server allowing cross-origin use.

Note also that Web Audio API is not supported in IE.

Example

Warning: check your audio volume before running code!

Adopt as needed -

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">

Music © K3N / freely distributable for test purposes.