first test
parent
3d08feaefb
commit
e5e908e65a
@ -1 +1,3 @@
|
||||
node_modules/
|
||||
node_modules/
|
||||
.env
|
||||
package-lock.json
|
||||
|
@ -0,0 +1,131 @@
|
||||
const audioContext = new AudioContext();
|
||||
|
||||
const tap = document.querySelector('.container')
|
||||
const address = document.querySelector('#address').innerHTML
|
||||
|
||||
const socket = new ReconnectingWebSocket(
|
||||
location.origin.replace(/^http/, "ws") + address
|
||||
|
||||
);
|
||||
|
||||
socket.onopen = (event) => {
|
||||
socket.send(JSON.stringify({ type: "hello" }));
|
||||
console.log("Connected as destination!");
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
let noiseDuration = 0.05
|
||||
const playNoise = (bandHz = 1000, time = 0) => {
|
||||
|
||||
const bufferSize = audioContext.sampleRate * noiseDuration
|
||||
|
||||
// Create an empty buffer
|
||||
const noiseBuffer = new AudioBuffer({
|
||||
length: bufferSize,
|
||||
sampleRate: audioContext.sampleRate,
|
||||
})
|
||||
|
||||
// Fill the buffer with noise
|
||||
const data = noiseBuffer.getChannelData(0);
|
||||
for (let i = 0; i < bufferSize; i++) {
|
||||
data[i] = Math.random() * 2 - 1;
|
||||
}
|
||||
|
||||
// Create a buffer source from data
|
||||
const noise = new AudioBufferSourceNode(audioContext, {
|
||||
buffer: noiseBuffer,
|
||||
})
|
||||
|
||||
// Filter the output
|
||||
const bandpass = new BiquadFilterNode(audioContext, {
|
||||
type: "bandpass",
|
||||
frequency: bandHz
|
||||
})
|
||||
|
||||
noise.connect(bandpass).connect(audioContext.destination);
|
||||
noise.start(time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const playPulse = (freq=440, lfoFreq=30, duration=1, time=0) => {
|
||||
|
||||
const osc = new OscillatorNode(audioContext, {
|
||||
type: "square",
|
||||
frequency: freq
|
||||
})
|
||||
|
||||
const amp = new GainNode(audioContext, {
|
||||
value: 0
|
||||
})
|
||||
|
||||
const lfo = new OscillatorNode(audioContext, {
|
||||
type: "sine",
|
||||
frequency: lfoFreq
|
||||
})
|
||||
|
||||
lfo.connect(amp.gain)
|
||||
osc.connect(amp).connect(audioContext.destination)
|
||||
lfo.start()
|
||||
osc.start(time)
|
||||
// osc.stop(time + duration)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const spawnGradient = (x, y) => {
|
||||
const gradient = document.createElement('div')
|
||||
gradient.classList.add('gradient')
|
||||
gradient.style.translate = `${x}px ${y}px`
|
||||
gradient.style.scale = 0
|
||||
|
||||
let red = x / tap.clientWidth * 255
|
||||
let green = y / tap.clientHeight * 255
|
||||
let blue = 0
|
||||
|
||||
gradient.style.background = `radial-gradient(circle, rgba(${red},${green},${blue},1) 0%, rgba(${red},${green},${blue},0) 25%)`
|
||||
|
||||
tap.appendChild(gradient)
|
||||
grow(gradient)
|
||||
|
||||
}
|
||||
|
||||
const grow = (el) => {
|
||||
let scale = Number(el.style.scale) || 0
|
||||
el.style.scale = scale + 0.1
|
||||
requestAnimationFrame(()=> grow(el))
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const emit = (x, y) => {
|
||||
playPulse(x, y * 0.01)
|
||||
spawnGradient(x, y)
|
||||
}
|
||||
|
||||
|
||||
const join = document.querySelector('#join')
|
||||
join.addEventListener('click', ()=>{
|
||||
playNoise()
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
let message;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {}
|
||||
|
||||
console.log("received a message! ", message)
|
||||
if (message?.type == 'pulse'){
|
||||
emit(message.x, message.y)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,33 +1,21 @@
|
||||
html,
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: dodgerblue;
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#svgElement {
|
||||
background-color: white;
|
||||
.container.destination {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.destination #svgElement {
|
||||
background: none;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
background-color: white;
|
||||
border: 2px solid currentColor;
|
||||
padding: 8px 24px;
|
||||
border-radius: 24px;
|
||||
font-size: 24px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#theme {
|
||||
font-weight: bold;
|
||||
-webkit-text-stroke: 1px black;
|
||||
-webkit-text-fill-color: white;
|
||||
.gradient {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: inline-block;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
@ -0,0 +1,100 @@
|
||||
const tap = document.querySelector('.container')
|
||||
const address = document.querySelector('#address').innerHTML
|
||||
const socket = new ReconnectingWebSocket(location.origin.replace(/^http/, "ws") + address);
|
||||
const audioContext = new AudioContext();
|
||||
|
||||
let noiseDuration = 0.05
|
||||
const playNoise = (bandHz = 1000, time = 0) => {
|
||||
|
||||
const bufferSize = audioContext.sampleRate * noiseDuration
|
||||
|
||||
// Create an empty buffer
|
||||
const noiseBuffer = new AudioBuffer({
|
||||
length: bufferSize,
|
||||
sampleRate: audioContext.sampleRate,
|
||||
})
|
||||
|
||||
// Fill the buffer with noise
|
||||
const data = noiseBuffer.getChannelData(0);
|
||||
for (let i = 0; i < bufferSize; i++) {
|
||||
data[i] = Math.random() * 2 - 1;
|
||||
}
|
||||
|
||||
// Create a buffer source from data
|
||||
const noise = new AudioBufferSourceNode(audioContext, {
|
||||
buffer: noiseBuffer,
|
||||
})
|
||||
|
||||
// Filter the output
|
||||
const bandpass = new BiquadFilterNode(audioContext, {
|
||||
type: "bandpass",
|
||||
frequency: bandHz
|
||||
})
|
||||
|
||||
noise.connect(bandpass).connect(audioContext.destination);
|
||||
noise.start(time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const playPulse = (freq=440, lfoFreq=30, duration=1, time=0) => {
|
||||
|
||||
const osc = new OscillatorNode(audioContext, {
|
||||
type: "square",
|
||||
frequency: freq
|
||||
})
|
||||
|
||||
const amp = new GainNode(audioContext, {
|
||||
value: 0
|
||||
})
|
||||
|
||||
const lfo = new OscillatorNode(audioContext, {
|
||||
type: "sine",
|
||||
frequency: lfoFreq
|
||||
})
|
||||
|
||||
lfo.connect(amp.gain)
|
||||
osc.connect(amp).connect(audioContext.destination)
|
||||
lfo.start()
|
||||
osc.start(time)
|
||||
// osc.stop(time + duration)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const spawnGradient = (x, y) => {
|
||||
const gradient = document.createElement('div')
|
||||
gradient.classList.add('gradient')
|
||||
gradient.style.translate = `${x}px ${y}px`
|
||||
gradient.style.scale = 0
|
||||
|
||||
let red = x / tap.clientWidth * 255
|
||||
let green = y / tap.clientHeight * 255
|
||||
let blue = 0
|
||||
|
||||
gradient.style.background = `radial-gradient(circle, rgba(${red},${green},${blue},1) 0%, rgba(${red},${green},${blue},0) 25%)`
|
||||
|
||||
tap.appendChild(gradient)
|
||||
grow(gradient)
|
||||
|
||||
}
|
||||
|
||||
const grow = (el) => {
|
||||
let scale = Number(el.style.scale) || 0
|
||||
el.style.scale = scale + 0.1
|
||||
requestAnimationFrame(()=> grow(el))
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tap.addEventListener("click", (e) => {
|
||||
playPulse(e.clientX, e.clientY * 0.01)
|
||||
spawnGradient(e.clientX, e.clientY)
|
||||
console.log('sending pulse')
|
||||
socket.send(JSON.stringify({type: 'pulse', x: e.clientX, y: e.clientY }))
|
||||
})
|
||||
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue