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!
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:
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.
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.