Waves/js/index.js
2024-05-29 15:19:07 +02:00

621 lines
14 KiB
JavaScript

const micro_height = 100;
const micro_width = 100;
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const SPEED = 50;
const AMPLITUDE = 50;
const SIZE = 1;
const NP = 10;
const rigi = 5;
const krigi = 0.9;
const CLAMPED = 1;
var DAMP = 0.05;
var firstMic = 1;
var myId = 0;
var nbMicro = 0;
var l = Math.floor(canvas.height / NP); //length of a row
var midl = Math.pow(l, 2) / 2 - l / 2;
var r = 1;
var redstyle = 0;
var bluestyle = 0;
const FRAME_RATE = 60;
const FRAME_INTERVAL = 1000 / FRAME_RATE;
var tempx,
tempy,
tempvx,
tempvy,
i,
b,
j,
k,
f,
v,
vunx,
vuny,
vdeuxx,
vdeuxy,
diffun,
diffdeux,
average,
self,
start,
mousedown,
press,
radioval,
firstmic = 0;
var tab = [];
var tabuffer = [];
var previoustab = [];
var tabtaken = [];
var tabsin = [];
frequency = document.querySelector("#freq");
amplitude = document.querySelector("#gain");
DB = document.querySelector("#db");
damping = document.querySelector("#damp");
//////////////INITIALISATION////////
function initialisation() {
console.log("initialisation");
for (i = 0; i < Math.floor(canvas.height / NP); i++) {
for (j = 0; j < Math.floor(canvas.width / NP); j++) {
addNewPart(i, j);
}
}
}
function addNewPart(x, y) {
tab.push({ x: x * NP, y: y * NP, z: SIZE, active: 1, v: 0 });
tabuffer.push({ x: x * NP, y: y * NP, z: SIZE });
previoustab.push({ x: x * NP, y: y * NP, z: SIZE });
}
///////////ENGINE////////////////////
function engine() {
setSin();
//setMics();
var m = 0;
for (m = 0; m < r; m++) {
nextStep();
}
render();
}
function setSin() {
for (i = 0; i < tabsin.length; i++) {
tab[tabsin[i].i].v = tabsin[i].valueUpdate();
tabsin[i].step++;
}
}
function setMic(i, a) {
tab[i].v += tab[i + l].v += (amplitude.value * (a - DB.value)) / 100;
//tab[i-l].v+= amplitude.value*(a-DB.value)/100;
}
function taken(i) {
var u = 0;
for (u = 0; u < tabtaken.length; u++) {
if (tabtaken[i] === i) {
return 1;
}
}
return 0;
}
function addSin(i) {
var u = 0;
if (taken(i)) {
return;
} else {
let sin = new Sin(210 - frequency.value, amplitude.value, i);
console.log("sin :", sin.valueUpdate());
tabtaken.push(i);
tabsin.push(sin);
}
}
function Sin(freq, amp, i) {
this.i = i;
this.step = 0;
this.amp = amp;
this.freq = freq;
this.valueUpdate = function () {
return Math.cos((this.step / this.freq) * 2 * Math.PI) * this.amp;
this.step++;
};
//console.log((Math.cos(((this.step/this.freq)*2*Math.PI))*this.amp));
}
function nextStep() {
var act,
temp,
spd,
d,
self = 0;
for (i = 0; i < tab.length; i++) {
self = tab[i].z;
if (i > l && i && i % l && (i % l) - l + 1 && i < l * (l - 1)) {
act =
tab[i + l].active +
tab[i - l].active +
tab[i - 1].active +
tab[i + 1].active;
if (!act) {
act = 1;
}
// temp=(up(i)+down(i)+left(i)+right(i))*(rigi-1)/(act*rigi)+(tab[i].z)*1/rigi
d = (self * 4 - (up(i) + down(i) + left(i) + right(i))) / 4;
spd = tab[i].v - krigi * d - tab[i].v * DAMP;
temp = spd + tab[i].z;
tabuffer[i].z = temp;
tab[i].v = spd;
} else {
disable(i);
temp = 0;
switch (i) {
case 0:
{
temp = down(i) + right(i);
if (!temp) {
temp = SIZE;
}
act = tab[i + l].active + tab[i + 1].active;
}
break;
case l - 1:
{
temp = up(i) + right(i);
if (!temp) {
temp = SIZE;
}
act = tab[i + l].active + tab[i - 1].active;
}
break;
case tab.length - l:
{
temp = down(i) + left(i);
if (!temp) {
temp = SIZE;
}
act = tab[i - l].active + tab[i + 1].active;
}
break;
case tab.length - 1: {
temp = up(i) + left(i);
if (!temp) {
temp = SIZE;
}
}
}
if (temp) {
if (CLAMPED) {
temp = SIZE;
} else {
temp = (temp * (rigi - 1)) / (act * rigi) + (tab[i].z * 1) / rigi;
}
} else {
if ((i % l) - l + 1 === 0 && i) {
temp = up(i) + right(i) + left(i);
act = tab[i + l].active + tab[i - l].active + tab[i - 1].active;
}
if (i % l === 0 && i !== l && i) {
temp = right(i) + down(i) + left(i);
act = tab[i + l].active + tab[i - l].active + tab[i + 1].active;
}
if (i < l * l - 1 && i > l * l - l - 1) {
temp = up(i) + down(i) + left(i);
act = tab[i - l].active + tab[i - 1].active + tab[i + 1].active;
}
if (i < l && i > 0) {
temp = up(i) + down(i) + right(i);
act = tab[i + l].active + tab[i - 1].active + tab[i + 1].active;
}
if (!act) {
act = 1;
}
temp = ((temp * (rigi - 1)) / (act * rigi) + (tab[i].z * 1) / rigi) / 2;
temp += (previoustab[i].z * 1) / 2;
previoustab[i].z = temp;
}
tabuffer[i].z = temp;
}
}
for (i = 0; i < tab.length; i++) {
tab[i].z = tabuffer[i].z;
}
}
function down(i) {
return tab[i + 1].z * tab[i + 1].active;
}
function up(i) {
return tab[i - 1].z * tab[i - 1].active;
}
function left(i) {
return tab[i - l].z * tab[i - l].active;
}
function right(i) {
return tab[i + l].z * tab[i + l].active;
}
function disable(a) {
tab[a].active = 0;
}
function unable(a) {
tab[a].active = 1;
}
function toggle(a) {
tab[a].active ? (tab[a].active = 0) : (tab[a].active = 1);
}
function makeWave(e) {
if (press) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
console.log("i move in make wave");
if (ielement(x, y) != b) {
wave(x, y);
}
b = ielement(x, y);
}
}
function wave(x, y) {
tab[ielement(x, y)].v += -SPEED;
}
function clear() {
removeMicro();
tabsin = [];
}
////////////CLICK////////////////////
var elemLeft = canvas.offsetLeft,
elemTop = canvas.offsetTop,
context = canvas.getContext("2d"),
elements = [];
onmousemove = function (e) {
switch (radioval) {
case "Mic":
{
}
break;
case "Wall":
{
wallMaker(e);
}
break;
case "Wave":
{
makeWave(e);
console.log(radioval);
}
break;
// case "Nothing":{};break;
}
};
//onmousemove = wallMaker(e);
damping.oninput = function () {
DAMP = this.value;
};
canvas.addEventListener(
"mouseup",
function (event) {
press = 0;
firstmic = 0;
},
false
);
canvas.addEventListener(
"mousedown",
function (event) {
console.log("click");
press = 1;
var temp = 0;
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
//switch ()
for (i = 0; i < radio.length; i++) {
if (radio[i].checked) {
temp = radio[i].value;
}
radioval = temp;
switch (temp) {
case "Mic":
{
addMicro(x, y);
}
break;
case "Wall":
{
}
break;
case "Wave":
{
makeWave(event);
}
break;
case "Sin": {
addSin(ielement(x, y));
}
// case "Nothing":{};break;
}
}
},
false
);
var btn = document.getElementById("startbtn");
var radio = document.getElementById("radio");
var clr = document.getElementById("clear");
btn.addEventListener("click", getSound);
clr.addEventListener("click", clear);
function startMachine() {
start ? (start = 0) : (start = 1);
if (start) {
getSound;
}
}
function toggleSend() {
send ? (send = 0) : (send = 1);
}
////////////////WALLS////////////////////////
function wallMaker(event) {
if (press) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
if (ielement(x, y) != b) {
makeWall(x, y);
}
b = ielement(x, y);
}
}
function makeWall(x, y) {
toggle(ielement(x, y));
window.requestAnimationFrame(render);
console.log("i made a wall", ielement(x, y));
}
function ielement(x, y) {
var temp = Math.round(x / NP) * l + Math.round(y / NP);
if (temp < tab.length && temp > 0) {
return temp;
} else {
return midl;
}
}
////////////RENDER///////////////////
function render() {
var xsize,
ysize,
xpos,
ypos = 10;
var up,
right,
diag = 0;
var r,
g,
b,
avr = 0;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 0; i < tab.length; i++) {
if (i) {
ctx.beginPath();
up = tab[i - 1];
right = tab[i + l];
diag = tab[i - 1 + l];
}
if (tab[i].active) {
if (tab[i].z <= 0) {
//downhill value
b = 126;
r = 0;
g = (-256 * tab[i].z) / 200;
if (g < 0) {
g *= -1;
}
ctx.fillStyle = "rgb(" + r + ", " + g + "," + b + "," + 0.95 + ")";
xsize = SIZE;
ysize = SIZE;
ctx.moveTo(tab[i].x, tab[i].y - tab[i].z / 2);
ctx.lineTo(up.x, up.y - up.z / 2);
ctx.lineTo(diag.x, diag.y - diag.z / 2);
ctx.lineTo(right.x, right.y - right.z / 2);
ctx.closePath();
ctx.fill();
} else {
//uphill value
avr = tab[i].z + up.z + diag.z + right.z;
avr *= 1 / 4;
b = 125;
r = (256 * avr) / 100;
g = 0;
if (g < 0) {
g *= -1;
}
ctx.fillStyle = "rgb(" + r + ", " + g + "," + b + "," + 1 + ")";
xsize = SIZE;
ysize = SIZE;
ctx.moveTo(tab[i].x - xsize / 4, tab[i].y - tab[i].z / 2);
ctx.lineTo(up.x, up.y - up.z / 2);
ctx.lineTo(diag.x, diag.y - diag.z / 2);
ctx.lineTo(right.x, right.y - right.z / 2);
ctx.closePath();
ctx.fill();
}
} else {
ctx.fillStyle = "rgb(" + 250 + ", " + 240 + "," + 256 + "," + 0 + ")";
ctx.fillRect(
tab[i].x - 2 * SIZE,
tab[i].y - 2 * SIZE,
4 * SIZE,
4 * SIZE
); //walls
}
}
ctx.stroke();
//ctx.fill();
}
////////////MAIN/////////////////////
function main() {
f = 1;
v = 1;
send = 0;
console.log("main");
initialisation();
}
console.clear();
main();
/////////////AUDIO/////////////
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
function getSound() {
if (navigator.getUserMedia) {
navigator.mediaDevices
.getUserMedia({ audio: true })
.then(function (flux) {
audioContext = new AudioContext();
analyseur = audioContext.createAnalyser();
microphone = audioContext.createMediaStreamSource(flux);
javascriptNode = audioContext.createScriptProcessor(2048, 1, 1);
analyseur.fftSize = 1024;
microphone.connect(analyseur);
analyseur.connect(javascriptNode);
javascriptNode.connect(audioContext.destination);
javascriptNode.onaudioprocess = function () {
var tab = new Uint8Array(analyseur.frequencyBinCount);
analyseur.getByteFrequencyData(tab);
var values = 0;
for (var i = 0; i < tab.length; i++) {
values += tab[i];
}
average = values / tab.length;
setAverage(average);
if (firstMic) {
engine();
}
/*
for(var i = 0; i < nbMicro; ++i){
//setAverage(i);
}
*/ // engine();
/*
if (send){
state.set(values / tab.length);
}*/
};
})
.catch(function (err) {
console.log("The following error occured: " + err.name);
});
}
}
/////////////FIREBASE////////////
var tabPersonne = firebase.database().ref("tabPersonne");
function addPersonneOnline(personne) {
myId = tabPersonne.push(personne);
}
function addMicroOnline(micro) {
var tabMicro = firebase.database().ref(myId);
micro.id = tabMicro.push(micro);
}
function removeMicroOnline() {
var p = firebase.database().ref(myId);
p.remove();
}
function setAverage(data) {
var fb = firebase.database().ref(myId);
fb.once("value", function (snapshot) {
snapshot.forEach(function (child) {
//child.forEach(function(sousChild){
child.ref.update({
average: data,
});
// });
});
});
}
function clearAll() {}
//Quitte la page
/*
var depart = firebase.database().ref(myId);
depart.onDisconnect().remove();
*/
var change = firebase.database().ref("tabPersonne");
change.on("value", newData);
function newData(data) {
var fb = firebase.database().ref("tabPersonne");
fb.once("value", function (snapshot) {
snapshot.forEach(function (child) {
child.forEach(function (sousChild) {
var content = sousChild.val();
setMic(content.i, content.average);
});
// });
});
});
//engine();
}
///////////FONCTION ADD MAP
function addMicro(x, y) {
var monMicro = new Object();
monMicro.x = x;
monMicro.y = y;
monMicro.i = ielement(x, y);
monMicro.average = 0;
if (firstMic === 0) {
addMicroLocal(monMicro);
} else {
addPersonne(monMicro);
}
}
function removeMicro() {
for (var i = 0; i < nbMicro; ++i) {
maPersonne[i] = null;
nbMicro = 0;
firstMic = 1;
removeMicroOnline();
}
}
var maPersonne = new Array();
function addPersonne(micro) {
maPersonne.push(micro);
++nbMicro;
firstMic = 0;
addPersonneOnline(maPersonne);
}
function addMicroLocal(micro) {
maPersonne[nbMicro] = micro;
++nbMicro;
addMicroOnline(micro);
}
function removeAllLocal() {
for (var i = 0; i < nbMicro; ++i) {
maPersonne[i] = null;
nbMicro = 0;
firstMic = 1;
}
var p = firebase.database().ref("tabPersonne");
p.remove();
}
/*
function startAnimationLoop() {
function loop(currentTime) {
if (currentTime - lastFrameTime >= FRAME_INTERVAL) {
engine();
lastFrameTime = currentTime;
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
*/