Spaces:
Running
Running
import gradio as gr | |
def update_ui(code): | |
try: | |
return f""" | |
<div style="border: 1px solid #ccc; padding: 10px; height: 400px; overflow: auto;"> | |
{code} | |
</div> | |
""", None | |
except Exception as e: | |
return "", str(e) | |
def interface(): | |
with gr.Blocks() as demo: | |
gr.Markdown("# Learn Frontend UI") | |
with gr.Row(): | |
code_input = gr.Code(label="Write your HTML/CSS/JS here", language="html") | |
with gr.Column(): | |
ui_preview = gr.HTML(label="UI Preview") | |
error_output = gr.Textbox(label="Error", interactive=False) | |
# Correctly using _js in the latest Gradio version | |
code_input.change( | |
fn=update_ui, | |
inputs=code_input, | |
outputs=[ui_preview, error_output], | |
_js=lambda code: f""" | |
(function() {{ | |
const tempDiv = document.createElement('div'); | |
tempDiv.innerHTML = `{code}`; | |
const scripts = tempDiv.getElementsByTagName('script'); | |
Array.from(scripts).forEach(script => {{ | |
const newScript = document.createElement('script'); | |
newScript.textContent = script.textContent; | |
document.body.appendChild(newScript); | |
script.remove(); | |
}}); | |
return tempDiv.innerHTML; | |
}})(); | |
""" | |
) | |
# Add example section | |
with gr.Accordion("HTML/CSS/JS Code Examples", open=False): | |
with gr.Column(): | |
example_buttons = [] | |
example_codes = [ | |
# ... (your existing examples here) | |
(""" | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Snake Game</title> | |
<style> | |
body {{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
background-color: #000; | |
margin: 0; | |
}} | |
#gameCanvas {{ | |
border: 1px solid #fff; | |
}} | |
</style> | |
</head> | |
<body> | |
<canvas id="gameCanvas" width="400" height="400"></canvas> | |
<script> | |
const canvas = document.getElementById('gameCanvas'); | |
const ctx = canvas.getContext('2d'); | |
const grid = 20; | |
let count = 0; | |
let snake = {{ | |
x: grid * 5, | |
y: grid * 5, | |
dx: grid, | |
dy: 0, | |
cells: [], | |
maxCells: 4 | |
}}; | |
let apple = {{x: 0, y: 0}}; | |
let score = 0; | |
function gameLoop() {{ | |
requestAnimationFrame(gameLoop); | |
if (++count < 4) return; | |
count = 0; | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
snake.x += snake.dx; | |
snake.y += snake.dy; | |
if (snake.x < 0) snake.x = canvas.width - grid; | |
else if (snake.x >= canvas.width) snake.x = 0; | |
if (snake.y < 0) snake.y = canvas.height - grid; | |
else if (snake.y >= canvas.height) snake.y = 0; | |
snake.cells.unshift({{x: snake.x, y: snake.y}}); | |
if (snake.cells.length > snake.maxCells) snake.cells.pop(); | |
ctx.fillStyle = 'red'; | |
ctx.fillRect(apple.x, apple.y, grid - 1, grid - 1); | |
ctx.fillStyle = 'green'; | |
snake.cells.forEach(function(cell, index) {{ | |
ctx.fillRect(cell.x, cell.y, grid - 1, grid - 1); | |
if (index !== 0 && cell.x === snake.x && cell.y === snake.y) {{ | |
snake.maxCells = 4; | |
score = 0; | |
}} | |
}}); | |
if (snake.x === apple.x && snake.y === apple.y) {{ | |
snake.maxCells++; | |
score++; | |
apple.x = Math.floor(Math.random() * 20) * grid; | |
apple.y = Math.floor(Math.random() * 20) * grid; | |
}} | |
ctx.fillStyle = 'white'; | |
ctx.font = '20px Arial'; | |
ctx.fillText('Score: ' + score, 10, 20); | |
}} | |
document.addEventListener('keydown', function(e) {{ | |
if (e.which === 37 && snake.dx === 0) {{ snake.dx = -grid; snake.dy = 0; }} | |
else if (e.which === 38 && snake.dy === 0) {{ snake.dx = 0; snake.dy = -grid; }} | |
else if (e.which === 39 && snake.dx === 0) {{ snake.dx = grid; snake.dy = 0; }} | |
else if (e.which === 40 && snake.dy === 0) {{ snake.dx = 0; snake.dy = grid; }} | |
}}); | |
apple.x = Math.floor(Math.random() * 20) * grid; | |
apple.y = Math.floor(Math.random() * 20) * grid; | |
requestAnimationFrame(gameLoop); | |
</script> | |
</body> | |
</html> | |
""", "Snake Game"), | |
] | |
for code, label in example_codes: | |
button = gr.Button(label) | |
example_buttons.append(button) | |
button.click(fn=lambda x=code: x, outputs=code_input) | |
return demo | |
if __name__ == "__main__": | |
demo = interface() | |
demo.launch() |