mirror of
https://github.com/G2-Games/website.git
synced 2025-04-19 09:52:53 -05:00
131 lines
2.9 KiB
JavaScript
131 lines
2.9 KiB
JavaScript
"use strict";
|
|
|
|
class VC
|
|
{
|
|
constructor( canvas, config )
|
|
{
|
|
const defConfig =
|
|
{
|
|
clearInterval: 50,
|
|
overScan: 0.82,
|
|
hOffset: 0.06525,
|
|
pulseLength: ( 0.2 / 1000 ),
|
|
lineWidth: 2.5,
|
|
brightness: 1,
|
|
saturation: 1,
|
|
blend: false,
|
|
hFreq: 225.0,
|
|
vFreq: 3
|
|
};
|
|
|
|
config = Object.assign( defConfig, config );
|
|
|
|
this.lines = [];
|
|
|
|
this.lastClear = 0;
|
|
this.clearInterval = config.clearInterval;
|
|
|
|
this.canvas = canvas;
|
|
|
|
this.width = this.canvas.width;
|
|
this.height = this.canvas.height;
|
|
|
|
this.lineWidth = config.lineWidth;
|
|
this.blend = config.blend;
|
|
|
|
this.config = config;
|
|
|
|
this.graphicsContext = null;
|
|
this.audioContext = null;
|
|
this.audioInput = null;
|
|
this.decoder = null;
|
|
}
|
|
|
|
async start()
|
|
{
|
|
this.graphicsContext = this.canvas.getContext( "2d" );
|
|
|
|
this.audioContext = new window.AudioContext();
|
|
|
|
let stream = await navigator.mediaDevices.getUserMedia(
|
|
{
|
|
audio: {
|
|
echoCancellation: false,
|
|
noiseSuppression: false,
|
|
autoGainControl: false,
|
|
channelCount: {
|
|
exact: 2
|
|
}
|
|
}
|
|
} );
|
|
|
|
this.audioInput = this.audioContext.createMediaStreamSource( stream );
|
|
|
|
await this.audioContext.audioWorklet.addModule( 'cv-decoder.js' )
|
|
|
|
this.decoder = new AudioWorkletNode( this.audioContext, 'cv-decoder',
|
|
{
|
|
numberOfInputs: 2,
|
|
numberOfOutputs: 0,
|
|
processorOptions: this.config
|
|
}
|
|
);
|
|
|
|
this.decoder.port.onmessage = event =>
|
|
{
|
|
if( this.lines.length < 1024 )
|
|
this.lines.push( event.data )
|
|
};
|
|
|
|
this.audioInput.connect( this.decoder );
|
|
|
|
requestAnimationFrame( () => this.draw() );
|
|
}
|
|
|
|
activate()
|
|
{
|
|
this.audioContext.resume();
|
|
}
|
|
|
|
draw()
|
|
{
|
|
if( Date.now() - this.lastClear > this.clearInterval )
|
|
{
|
|
this.graphicsContext.fillStyle = 'rgba(0,0,0,0.05)';
|
|
this.graphicsContext.globalCompositeOperation = 'source-over';
|
|
this.graphicsContext.fillRect( 0, 0, this.width, this.height );
|
|
this.lastClear = Date.now();
|
|
}
|
|
|
|
if( this.blend )
|
|
this.graphicsContext.globalCompositeOperation = 'screen';
|
|
else
|
|
this.graphicsContext.globalCompositeOperation = 'source-over';
|
|
|
|
this.graphicsContext.lineWidth = this.lineWidth;
|
|
|
|
const width = this.width;
|
|
const height = this.height;
|
|
|
|
for( let line of this.lines )
|
|
{
|
|
var gradient = this.graphicsContext.createLinearGradient( line.x1 * width, line.y * height, line.x2 * width, line.y * height );
|
|
|
|
for( let color of line.colors )
|
|
gradient.addColorStop( color.phase / line.maxPhase, 'rgb(' + color.r + ',' + color.g + ',' + color.b + ')' );
|
|
|
|
this.graphicsContext.beginPath();
|
|
|
|
this.graphicsContext.moveTo( line.x1 * width + Math.random() * 2.0 - 1.0, line.y * height + Math.random() * 2.0 - 1.0 );
|
|
this.graphicsContext.lineTo( line.x2 * width + Math.random() * 2.0 - 1.0, line.y * height + Math.random() * 2.0 - 1.0 );
|
|
|
|
this.graphicsContext.strokeStyle = gradient;
|
|
|
|
this.graphicsContext.stroke();
|
|
}
|
|
|
|
this.lines = [];
|
|
|
|
requestAnimationFrame( () => this.draw() );
|
|
}
|
|
}
|