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();
 ...