Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import streamlit.components.v1 as components | |
| import time | |
| st.title("Shader + Mouse Demo") | |
| # Display mouse coordinates from Streamlit sliders | |
| st.sidebar.subheader("Mouse coordinates (simulate / control)") | |
| mouse_x = st.sidebar.slider("Mouse X (0–1)", 0.0, 1.0, 0.5) | |
| mouse_y = st.sidebar.slider("Mouse Y (0–1)", 0.0, 1.0, 0.5) | |
| # WebGL shader HTML | |
| html_code = f""" | |
| <canvas id="glcanvas" width="500" height="400"></canvas> | |
| <script type="text/javascript"> | |
| const canvas = document.getElementById('glcanvas'); | |
| const gl = canvas.getContext('webgl'); | |
| if (!gl) {{ | |
| alert('WebGL not supported'); | |
| }} | |
| // Vertex shader | |
| const vertCode = ` | |
| attribute vec4 position; | |
| void main() {{ | |
| gl_Position = position; | |
| }} | |
| `; | |
| // Fragment shader | |
| const fragCode = ` | |
| precision mediump float; | |
| uniform float iTime; | |
| uniform vec2 iMouse; | |
| uniform vec2 iResolution; | |
| void main() {{ | |
| vec2 uv = gl_FragCoord.xy / iResolution.xy; | |
| vec3 color = vec3(uv.x + iMouse.x*0.5 + sin(iTime)*0.2, | |
| uv.y + iMouse.y*0.5 + cos(iTime)*0.2, | |
| 0.5 + 0.5*sin(iTime)); | |
| gl_FragColor = vec4(color, 1.0); | |
| }} | |
| `; | |
| // Compile helper | |
| function compileShader(gl, source, type) {{ | |
| const shader = gl.createShader(type); | |
| gl.shaderSource(shader, source); | |
| gl.compileShader(shader); | |
| if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {{ | |
| console.error(gl.getShaderInfoLog(shader)); | |
| return null; | |
| }} | |
| return shader; | |
| }} | |
| // Compile shaders | |
| const vertShader = compileShader(gl, vertCode, gl.VERTEX_SHADER); | |
| const fragShader = compileShader(gl, fragCode, gl.FRAGMENT_SHADER); | |
| // Create program | |
| const program = gl.createProgram(); | |
| gl.attachShader(program, vertShader); | |
| gl.attachShader(program, fragShader); | |
| gl.linkProgram(program); | |
| gl.useProgram(program); | |
| // Fullscreen quad | |
| const vertices = new Float32Array([ | |
| -1,-1, 1,-1, -1,1, | |
| -1,1, 1,-1, 1,1 | |
| ]); | |
| const buffer = gl.createBuffer(); | |
| gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | |
| gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); | |
| const position = gl.getAttribLocation(program, "position"); | |
| gl.enableVertexAttribArray(position); | |
| gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0); | |
| // Uniform locations | |
| const iTime = gl.getUniformLocation(program, "iTime"); | |
| const iResolution = gl.getUniformLocation(program, "iResolution"); | |
| const iMouse = gl.getUniformLocation(program, "iMouse"); | |
| gl.uniform2f(iResolution, canvas.width, canvas.height); | |
| // Animation loop | |
| let startTime = Date.now(); | |
| function render() {{ | |
| let t = (Date.now() - startTime) / 1000.0; | |
| gl.uniform1f(iTime, t); | |
| gl.uniform2f(iMouse, {mouse_x}, {mouse_y}); // send Streamlit slider values | |
| gl.drawArrays(gl.TRIANGLES, 0, 6); | |
| requestAnimationFrame(render); | |
| }} | |
| render(); | |
| </script> | |
| """ | |
| components.html(html_code, height=420) | |
| st.write(f"Mouse in Streamlit sliders: X={mouse_x:.2f}, Y={mouse_y:.2f}") | |