JSFiddle - React, Tailwind, and code Playground
by alexvestin
HTML
<input id="file" type="file">Select song</input>
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
CSS
#canvas {
background-color: black;
width: 400;
height: 400;
}
#canvas2 {
background-color: black;
width: 400;
height: 400;
}
JavaScript
let fftMult = 8;
let height = 400, width = 400, fftSize = 2048 * fftMult, shortFftSize = 1024;
let canvas = document.getElementById("canvas");
let canvas2 = document.getElementById("canvas2");
let lastAvg = height / 2;
canvas.width = width;
canvas.height = height;
canvas2.height = height;
canvas2.width = width;
let ctx = canvas.getContext("2d");
let ctx2 = canvas2.getContext("2d");
let button = document.getElementById("file");
let audioCtx = new AudioContext();
let bufferSource, loaded = false;
let analyzer = audioCtx.createAnalyser();
let analyzer2 = audioCtx.createAnalyser();
ctx.strokeStyle = "green";
analyzer.fftSize = fftSize;
analyzer2.fftSize = shortFf;
button.onchange = (e) => {
let reader = new FileReader();
reader.readAsArrayBuffer(button.files[0]);
reader.onload = function(ev) {
audioCtx.decodeAudioData(ev.target.result, function(buffer) {
bufferSource = audioCtx.createBufferSource();
bufferSource.buffer = buffer;
bufferSource.connect(analyzer2);
analyzer2.connect(analyzer);
analyzer.connect(audioCtx.destination);
loaded = true;
bufferSource.loop = true;
bufferSource.start(0);
});
};
}
let shiftContext = (c) => {
let imageData = c.getImageData(1, 0, c.canvas.width-1, c.canvas.height);
c.putImageData(imageData, 0, 0);
c.clearRect(ctx2.canvas.width-1, 0, 1, c.canvas.height);
}
var id = ctx2.createImageData(1,height);
var d = id.data;
let animateFreqCanvas = (arr) => {
// shift one bit
shiftContext(ctx2);
for(var i = 0; i < d.length; i+=4) {
const val = arr[i / 4];
d[i] = val;
d[i+1] = val;
d[i+2] = val;
d[i+3] = val;
}
ctx2.putImageData(id, 300, 0);
}
let animateTimeCanvas = (arr, col) => {
shiftContext(ctx);
let avg = 0;
for(var i = 0; i < arr.length; i++) {
avg += arr[i];
}
avg = fftMult * avg / arr.length - (fftMult*80);
console.log(avg)
ctx.strokeStyel = col;
ctx.beginPath();
...