JSFiddle - React, Tailwind, and code Playground

by fxi

HTML

<canvas id='c'></canvas>

CSS

html,
body {
  height: 100%;
  width: 100%;
  overflow:hidden;

}

body {
  display: flex;
  align-items: center;
  justify-content: centeR;
  flex-direction:column;

}
#c {
  width:100%;
  height:100%;
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  
}

JavaScript

const Actx = window.AudioContext || window.webkitAudioContext;
const audioCtx = new Actx();
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);


 class Os {
   constructor(opt) {
     this._opt = Object.assign({}, {
       type: 'sine',
       min: 0,
       max: 100,
       step : 10,
       color: '#000'
     }, opt);
     this._enabled = false;
     this._init = false;
     this.update = this.update.bind(this);
     /**
      * audio
      */
     this.audioCtx = this.o.audioCtx;
     const oscillator = this.audioCtx.createOscillator();
     oscillator.type = this.o.type;
     oscillator.connect(analyser);
     analyser.connect(this.audioCtx.destination);
     this.oscillator = oscillator;
     /**
      * ui
      */
     const elInput = document.createElement('input');
     elInput.setAttribute('type', 'range');
     elInput.setAttribute('min', this.o.min - 1);
     elInput.setAttribute('max', this.o.max);
     elInput.setAttribute('value', this.o.min - 1);
     elInput.setAttribute('step', this.o.step);
     elInput.addEventListener('input', this.update);
     elInput.style.accentColor = this.o.color;
     document.body.appendChild(elInput);
   }
   get o() {
     return this._opt;
   }
   update(e) {
     const hz = (e.target.value * 1);
     if (hz >= this.o.min) {
       this.start();
     } else {
       this.stop();
       return;
     }
     this.hz(hz);

   }
   hz(v) {
     this.oscillator.frequency.setValueAtTime(v, this.audioCtx.currentTime);
   }
   start() {
     if (this.enabled) {
       return;
     }
     if (!this._init) {
       this.oscillator.start();
       this._init = true;
     }
     this.enabled = true;
   }

   stop() {
     if (!this.enabled) {
       return;
     }
     this.hz(0);
     this.enabled = false;
   }
 }

 for (let i = 1; i < 3; i++) {
   new Os({
     audioCtx:...