Spaces:
Running
Running
File size: 8,506 Bytes
9fd0d3c 17cccd0 9fd0d3c 17cccd0 9fd0d3c 095df03 9fd0d3c 17cccd0 9fd0d3c 17cccd0 e6d5c9e 17cccd0 038159a 17cccd0 e6d5c9e 17cccd0 095df03 17cccd0 e6d5c9e 17cccd0 e6d5c9e 17cccd0 9fd0d3c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
import gradio as gr
def update_ui(code):
try:
# For the preview, we'll return the code as-is to be rendered in an iframe-like manner
# Gradio's HTML component can render HTML/CSS directly, but JS needs special handling
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)
# JavaScript execution needs to be handled client-side, so we use _js to inject it
code_input.change(
fn=update_ui,
inputs=code_input,
outputs=[ui_preview, error_output],
js="""
function(code) {
// Create a temporary div to parse the HTML/CSS/JS
const tempDiv = document.createElement('div');
tempDiv.innerHTML = code;
// Handle JavaScript by creating new script elements
const scripts = tempDiv.querySelectorAll('script');
scripts.forEach(script => {
const newScript = document.createElement('script');
newScript.textContent = script.textContent;
document.body.appendChild(newScript);
script.remove(); // Remove original script to avoid double execution
});
// Wrap the content in a styled div for better presentation
return `
<div style="border: 1px solid #ccc; padding: 10px; height: 400px; overflow: auto;">
${tempDiv.innerHTML}
</div>
`;
}
"""
)
# Add example section
with gr.Accordion("HTML/CSS/JS Code Examples", open=False):
with gr.Column():
example_buttons = []
example_codes = [
('<h1>Hello World</h1>', "Basic Heading"),
('<p style="color: red;">This is a paragraph.</p>', "Styled Paragraph"),
('<button onclick="alert(\'Button clicked!\')">Click me</button>', "Interactive Button"),
("""
<style>
.box {
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<div class="box"></div>
""", "CSS Box"),
("""
<style>
.container {
display: flex;
justify-content: space-between;
}
</style>
<div class="container">
<div style="background-color: red; width: 50px; height: 50px;"></div>
<div style="background-color: green; width: 50px; height: 50px;"></div>
</div>
""", "Flexbox Layout"),
("""
<!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() |