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" /> | |
| <title>Gemini Live API + p5.js</title> | |
| </head> | |
| <body> | |
| <noscript>You need to enable JavaScript to run this app.</noscript> | |
| <div id="root"></div> | |
| <script> | |
| let mySketch; | |
| // Function to remove existing sketch instance | |
| window.removeSketch = function() { | |
| if (mySketch) { | |
| if (mySketch._cleanup) { | |
| mySketch._cleanup(); | |
| } | |
| mySketch.remove(); | |
| mySketch = null; | |
| } | |
| }; | |
| // Function to update the sketch with new code | |
| window.updateSketch = function(sketchCode, container) { | |
| console.log("Updating sketch with new code"); | |
| try { | |
| // Remove existing sketch if any | |
| window.removeSketch(); | |
| // Create new sketch instance | |
| mySketch = new p5((p) => { | |
| // Store container reference in p5 instance | |
| p.containerWidth = container.clientWidth; | |
| p.containerHeight = container.clientHeight; | |
| p.container = container; // Store container reference | |
| // Add the sketch code to p5 instance scope | |
| const sketchFunction = new Function('p', ` | |
| with (p) { | |
| ${sketchCode} | |
| // If setup/draw weren't defined, provide defaults | |
| if (typeof setup !== 'function') { | |
| setup = function() { | |
| createCanvas(containerWidth, containerHeight); | |
| } | |
| } | |
| if (typeof draw !== 'function') { | |
| draw = function() { | |
| background(0); | |
| } | |
| } | |
| // Return all defined p5 functions | |
| return { | |
| setup, | |
| draw, | |
| // Mouse events | |
| mousePressed: typeof mousePressed === 'function' ? mousePressed : undefined, | |
| mouseReleased: typeof mouseReleased === 'function' ? mouseReleased : undefined, | |
| mouseMoved: typeof mouseMoved === 'function' ? mouseMoved : undefined, | |
| mouseDragged: typeof mouseDragged === 'function' ? mouseDragged : undefined, | |
| mouseClicked: typeof mouseClicked === 'function' ? mouseClicked : undefined, | |
| doubleClicked: typeof doubleClicked === 'function' ? doubleClicked : undefined, | |
| mouseWheel: typeof mouseWheel === 'function' ? mouseWheel : undefined, | |
| // Keyboard events | |
| keyPressed: typeof keyPressed === 'function' ? keyPressed : undefined, | |
| keyReleased: typeof keyReleased === 'function' ? keyReleased : undefined, | |
| keyTyped: typeof keyTyped === 'function' ? keyTyped : undefined | |
| }; | |
| } | |
| `); | |
| // Get the sketch functions | |
| const functions = sketchFunction(p); | |
| // Assign the functions to p5 instance | |
| p.setup = () => { | |
| functions.setup.call(p); | |
| // Ensure canvas is in container | |
| if (container) { | |
| container.innerHTML = ""; | |
| container.appendChild(p._renderer.canvas); | |
| // Fix accessibility tooltip issue | |
| if (p._renderer.canvas) { | |
| // Remove the default accessibility attributes that cause tooltips | |
| p._renderer.canvas.removeAttribute('aria-label'); | |
| p._renderer.canvas.removeAttribute('role'); | |
| // Add a custom class to help with styling | |
| p._renderer.canvas.classList.add('p5-managed-canvas'); | |
| } | |
| } | |
| }; | |
| p.draw = functions.draw.bind(p); | |
| // Bind all mouse and keyboard event handlers | |
| if (functions.mousePressed) p.mousePressed = functions.mousePressed.bind(p); | |
| if (functions.mouseReleased) p.mouseReleased = functions.mouseReleased.bind(p); | |
| if (functions.mouseMoved) p.mouseMoved = functions.mouseMoved.bind(p); | |
| if (functions.mouseDragged) p.mouseDragged = functions.mouseDragged.bind(p); | |
| if (functions.mouseClicked) p.mouseClicked = functions.mouseClicked.bind(p); | |
| if (functions.doubleClicked) p.doubleClicked = functions.doubleClicked.bind(p); | |
| if (functions.mouseWheel) p.mouseWheel = functions.mouseWheel.bind(p); | |
| if (functions.keyPressed) p.keyPressed = functions.keyPressed.bind(p); | |
| if (functions.keyReleased) p.keyReleased = functions.keyReleased.bind(p); | |
| if (functions.keyTyped) p.keyTyped = functions.keyTyped.bind(p); | |
| // Cleanup when sketch is removed | |
| p._cleanup = () => { | |
| // No cleanup needed anymore | |
| }; | |
| }, container); | |
| console.log("Successfully created new sketch"); | |
| return true; | |
| } catch (error) { | |
| console.error("Error creating sketch:", error); | |
| return false; | |
| } | |
| }; | |
| window.initSketch = function (container) { | |
| console.log("Initialize empty sketch"); | |
| if (mySketch) { | |
| return; | |
| } | |
| // Create initial empty sketch | |
| window.updateSketch(` | |
| function setup() { | |
| createCanvas(containerWidth, containerHeight); | |
| } | |
| function draw() { | |
| background(0); | |
| } | |
| `, container); | |
| }; | |
| </script> | |
| </body> | |
| </html> | |