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,GRAD@20..48,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> | |