Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os, base64, shutil, random | |
| from pathlib import Path | |
| def load_aframe_and_extras(): | |
| return """ | |
| <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> | |
| <script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script> | |
| <script> | |
| let score = 0; | |
| AFRAME.registerComponent('draggable', { | |
| init: function () { | |
| this.el.setAttribute('class', 'raycastable'); | |
| this.el.setAttribute('cursor-listener', ''); | |
| this.dragHandler = this.dragMove.bind(this); | |
| this.el.sceneEl.addEventListener('mousemove', this.dragHandler); | |
| this.el.addEventListener('mousedown', this.onDragStart.bind(this)); | |
| this.el.addEventListener('mouseup', this.onDragEnd.bind(this)); | |
| this.camera = document.querySelector('[camera]'); | |
| }, | |
| remove: function () { | |
| this.el.removeAttribute('cursor-listener'); | |
| this.el.sceneEl.removeEventListener('mousemove', this.dragHandler); | |
| }, | |
| onDragStart: function (evt) { | |
| this.isDragging = true; | |
| this.el.emit('dragstart'); | |
| }, | |
| onDragEnd: function (evt) { | |
| this.isDragging = false; | |
| this.el.emit('dragend'); | |
| }, | |
| dragMove: function (evt) { | |
| if (!this.isDragging) return; | |
| let mouseX = evt.clientX / window.innerWidth * 2 - 1; | |
| let mouseY = -(evt.clientY / window.innerHeight * 2) + 1; | |
| let position = new THREE.Vector3(mouseX, mouseY, -5); | |
| position.unproject(this.camera.components.camera.camera); | |
| let direction = position.sub(this.camera.object3D.position).normalize(); | |
| let distance = -this.camera.object3D.position.z / direction.z; | |
| let newPosition = this.camera.object3D.position.clone().add(direction.multiplyScalar(distance)); | |
| this.el.setAttribute('position', {x: newPosition.x, y: newPosition.y, z: this.el.getAttribute('position').z}); | |
| } | |
| }); | |
| AFRAME.registerComponent('cursor-listener', { | |
| init: function () { | |
| this.el.addEventListener('mouseenter', function (evt) { | |
| this.setAttribute('material', {color: 'red'}); | |
| }); | |
| this.el.addEventListener('mouseleave', function (evt) { | |
| this.setAttribute('material', {color: 'blue'}); | |
| }); | |
| this.el.addEventListener('click', function (evt) { | |
| score++; | |
| document.getElementById('score').setAttribute('value', 'Score: ' + score); | |
| }); | |
| } | |
| }); | |
| </script> | |
| """ | |
| def create_environment(scene): | |
| sky = scene.entity( | |
| geometry="primitive: sphere; radius: 5000", | |
| material="color: #ADD8E6; shader: flat; side: back" # Light blue sky | |
| ) | |
| ground = scene.entity( | |
| geometry="primitive: plane; width: 100; height: 100", | |
| material="color: #7CFC00; side: double", # Lawn green ground | |
| rotation="-90 0 0" | |
| ) | |
| return sky, ground | |
| def create_drag_target(scene, x, y, z, color='blue'): | |
| target = scene.entity( | |
| geometry=f"primitive: box; width: 1; height: 1; depth: 1", | |
| material=f"color: {color}", | |
| position=f"{x} {y} {z}", | |
| draggable="" | |
| ) | |
| return target | |
| def main(): | |
| st.title("Interactive A-Frame Scene") | |
| html_string = f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>A-Frame Example</title> | |
| {load_aframe_and_extras()} | |
| </head> | |
| <body> | |
| <a-scene cursor="rayOrigin: mouse" raycaster="objects: .raycastable"> | |
| <a-camera position="0 1.6 0"></a-camera> | |
| <a-entity id="environment"></a-entity> | |
| <a-text id="score" value="Score: 0" position="-2 2 -3" color="black"></a-text> | |
| <a-entity id="drag-targets"></a-entity> | |
| </a-scene> | |
| </body> | |
| </html> | |
| """ | |
| st.components.v1.html(html_string, height=600, scrolling=False) | |
| with st.sidebar: | |
| st.header("Scene Controls") | |
| num_targets = st.slider("Number of Drag Targets", min_value=1, max_value=10, value=3) | |
| scene = st.components.v1 # This won't work as expected for direct A-Frame manipulation | |
| environment = scene.get("environment") # This also won't work | |
| drag_targets = scene.get("drag-targets") # And this won't work | |
| if environment is not None: | |
| create_environment(environment) # This will likely cause errors | |
| if drag_targets is not None: | |
| for i in range(num_targets): | |
| x = random.uniform(-5, 5) | |
| y = 1 | |
| z = random.uniform(-5, -2) | |
| create_drag_target(drag_targets, x, y, z) # Potential error here too | |
| if __name__ == "__main__": | |
| main() |