Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<meta name="theme-color" content="#000000" /> | |
<meta name="description" content="Web site created using create-react-app" /> | |
<link rel="preconnect" href="https://fonts.googleapis.com" /> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap" | |
rel="stylesheet" /> | |
<link | |
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200&display=block" | |
rel="stylesheet" /> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/gh/molleindustria/p5.play/lib/p5.play.js"></script> | |
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |
<!-- | |
Notice the use of %PUBLIC_URL% in the tags above. | |
It will be replaced with the URL of the `public` folder during the build. | |
Only files inside the `public` folder can be referenced from the HTML. | |
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | |
work correctly both with client-side routing and a non-root public URL. | |
Learn how to configure a non-root public URL by running `npm run build`. | |
--> | |
<title>Multimodal Live - Console</title> | |
</head> | |
<body> | |
<noscript>You need to enable JavaScript to run this app.</noscript> | |
<div id="root"></div> | |
<script> | |
let mySketch; | |
let osc; // oscillator for the tone | |
let freq = 261; // base frequency of the tone | |
let selectedCircleIndex = -1; | |
window.get_circles = function () { | |
return {circles: window.circles}; | |
}; | |
window.change_circle = function (args) { | |
// Play the tone here | |
if (osc) { | |
osc.start(); | |
osc.freq(freq); // Adjust frequency as needed | |
osc.amp(0.3); // Set initial amplitude | |
osc.fade(0, 0.2); // Fade to 0 amplitude over 0.2 seconds | |
} | |
// go through the object and copy the properties into the new one | |
window.circlesCurrent = window.circles.map((c) => ({ ...c })) | |
const color = args.color; | |
const findIndex = window.circles.findIndex( | |
(c) => c.color.toLowerCase() === color.toLowerCase(), | |
); | |
console.log(window.circles.splice); | |
window.circles.splice(findIndex, 1, args); | |
}; | |
window.circles = [ | |
{color: "#FF0000", x: window.innerWidth/2 - 150, y: window.innerHeight/2, radius: 100}, | |
{color: "#00FF00", x: window.innerWidth/2, y: window.innerHeight/2, radius: 100}, | |
{color: "#0000FF", x: window.innerWidth/2 + 150, y: window.innerHeight/2, radius: 100}, | |
]; | |
// make a copy of it | |
window.circlesCurrent = window.circles.map((c) => ({ ...c })) | |
window.initSketch = function (container) { | |
console.log("initialize sketch in public/index.html"); | |
console.log(container); | |
if (mySketch) { | |
return; | |
} | |
mySketch = new p5((p) => { | |
p.setup = function () { | |
console.log(p); | |
p.createCanvas(window.innerWidth, window.innerHeight); | |
container.innerHTMl = ""; | |
container.appendChild(p._renderer.canvas); | |
// Create the oscillator here, after p5.sound has been initialized | |
osc = new p5.Oscillator('sine'); | |
osc.amp(0); // Start with zero amplitude | |
}; | |
function getSelectedCircleIndex() { | |
for (let i = 0; i < circles.length; i++) { | |
const circle = circles[i]; | |
if ( | |
p.mouseX > circle.x - circle.radius && | |
p.mouseX < circle.x + circle.radius && | |
p.mouseY > circle.y - circle.radius && | |
p.mouseY < circle.y + circle.radius | |
) { | |
console.log("clicked : " + i); | |
return i; | |
} | |
} | |
return -1; | |
} | |
p.mousePressed = function () { | |
selectedCircleIndex = getSelectedCircleIndex(); | |
}; | |
p.mouseDragged = function () { | |
if (selectedCircleIndex > -1) { | |
const circle = circles[selectedCircleIndex]; | |
circle.x = p.mouseX; | |
circle.y = p.mouseY; | |
} | |
}; | |
p.mouseReleased = function () { | |
selectedCircleIndex = -1; | |
}; | |
p.draw = function draw() { | |
p.background(0); | |
p.blendMode(p.BLEND); | |
for(let i = 0; i < window.circles.length; i++) { | |
const circle = window.circles[i]; | |
p.noStroke(); | |
p.blendMode(p.SCREEN); | |
p.fill(circle.color); | |
// ease towards the final position | |
const easing = 0.15; | |
circlesCurrent[i].x = circlesCurrent[i].x + (circle.x - circlesCurrent[i].x) * easing; | |
circlesCurrent[i].y = circlesCurrent[i].y + (circle.y - circlesCurrent[i].y) * easing; | |
circlesCurrent[i].radius = circlesCurrent[i].radius + (circle.radius - circlesCurrent[i].radius) * easing; | |
// draw them at that position | |
p.circle(circlesCurrent[i].x, circlesCurrent[i].y, circlesCurrent[i].radius * 2); | |
} | |
}; | |
}); | |
}; | |
</script> | |
</body> | |
</html> | |