I am trying to make a music visualizer in Javascript in the shape of circle, my problem is that even though I call clearRect
, the canvas isnt clearing after a completion of a cycle.
$(document).ready(function() {
var canvas = document.getElementsByTagName("canvas")[0];
var context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
context.translate(window.innerWidth / 2, window.innerHeight / 2);
var audioContext = new AudioContext();
var audio = document.getElementsByTagName('audio')[0];
var source = audioContext.createMediaElementSource(audio);
var analyser = audioContext.createAnalyser();
source.connect(analyser);
analyser.connect(audioContext.destination);
var BLenght = analyser.frequencyBinCount;
var data = new Uint8Array(BLenght);
function Visualizer() {
context.clearRect(0, 0, canvas.width, canvas.height);
analyser.getByteFrequencyData(data);
var fwidth = (canvas.width / BLenght);
var fheight = 0;
var maxCircle = 80;
var radius = 200;
for (var i = 0; i <= maxCircle; i++) {
fheight = (data[i] * (canvas.height * 0.003)) / 2;
context.fillStyle = "#000000";
context.rect(0, radius, fwidth, fheight);
context.rotate(2 * Math.PI / maxCircle);
context.fill();
}
call = requestAnimationFrame(Visualizer);
}
var button = document.getElementById("button");
var isPlaying = false;
button.addEventListener('click', function() {
if (isPlaying == false) {
audio.play();
Visualizer();
isPlaying = true;
button.style.boxShadow = "0px 0px 0px 0px #065e41";
var delay = 400;
setTimeout(function() {
button.style.boxShadow = "0px 5px 0px 0px #065e41";
}, delay);
} else {
audio.pause();
isPlaying = false;
cancelAnimationFrame(call);
button.style.boxShadow = "0px 0px 0px 0px #065e41";
var delay = 400;
setTimeout(function() {
button.style.boxShadow = "0px 5px 0px 0px #065e41";
}, delay);
}
});
});
* {
box-sizing: border-box;
}
canvas {
position: absolute;
top: 10%;
}
#button {
width: 150px;
height: 50px;
background: #0deaa1;
text-align: center;
border-radius: 5px;
box-shadow: 0px 5px 0px 0px #065e41;
cursor: pointer;
user-select: none;
transition: .5s;
}
#button h1 {
padding-top: 7px;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<audio src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1715/the_xx_-_intro.mp3" preload="auto"></audio>
<canvas></canvas>
<div id="button">
<h1>PLAY</h1>
</div>
<p id="width">width</p>
<p id="buffer">buffer</p>
<p id="data">data</p>
It can be fixed by using fillRect, or by using context.beginPath. (currently you are adding every rect to the same path)
context.fillStyle = "#000000";
context.fillRect(0,radius,fwidth,fheight); // rect changed to fillrect
context.rotate(2*Math.PI/maxCircle);
To prevent the lines from spinning: reset the context transformation matrix:
context.setTransform(1, 0, 0, 1, 0, 0);
context.translate(window.innerWidth/2,window.innerHeight/2);
context.clearRect(-canvas.width/2,-canvas.height/2,canvas.width,canvas.height);
The Codepen example you provided was also updated: http://codepen.io/anon/pen/xbMxzY