File size: 4,500 Bytes
9fd0d3c
 
3e2c114
 
a2201d6
3e2c114
0dea17b
a2201d6
33b52f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0dea17b
3e2c114
 
 
 
 
 
 
 
 
 
9a770de
3e2c114
 
a2201d6
3e2c114
 
 
09b1f7a
3e2c114
33b52f1
a2201d6
3e2c114
 
 
 
a2201d6
 
 
3e2c114
a2201d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3e2c114
 
c94f5bc
3e2c114
 
 
 
3ab14b8
3e2c114
3ab14b8
3e2c114
 
 
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
import gradio as gr

def update_ui(code):
    try:
        # Directly return the code wrapped in a div for styling
        return f"""
        <div style="border: 1px solid #ccc; padding: 10px; height: 400px; overflow: auto;">
            {code}
            <script>
                // Ensure the game reinitializes when the code is updated
                if (typeof gameLoop !== 'undefined') {{
                    clearInterval(gameLoop);
                }}
                let canvas = document.getElementById('gameCanvas');
                let ctx = canvas.getContext('2d');
                let snake = [{x: 10, y: 10}];
                let food = {{x: 15, y: 15}};
                let gameLoop;

                function init() {{
                    gameLoop = setInterval(game, 100);
                }}

                function game() {{
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    snake.unshift({{x: snake[0].x, y: snake[0].y}});
                    snake[0].x += 1; // Simple movement for demonstration
                    if(snake[0].x > 39) snake[0].x = 0; // Wrap around
                    ctx.fillStyle = "green";
                    snake.forEach(part => {{
                        ctx.fillRect(part.x * 10, part.y * 10, 10, 10);
                    }});
                    ctx.fillStyle = "red";
                    ctx.fillRect(food.x * 10, food.y * 10, 10, 10);
                    if(snake[0].x == food.x && snake[0].y == food.y) {{
                        food.x = Math.floor(Math.random() * 40);
                        food.y = Math.floor(Math.random() * 40);
                    }} else {{
                        snake.pop();
                    }}
                }}

                // Start the game
                init();
            </script>
        </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)
        
        # Instead of using _js, we'll directly handle the JavaScript with Python
        code_input.change(
            fn=update_ui, 
            inputs=code_input, 
            outputs=[ui_preview, error_output]
        )
        
        # 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"),
                    ("""
                    <style>
                        body { margin: 0; padding: 0; }
                        #gameCanvas { border: 1px solid black; }
                    </style>
                    <canvas id="gameCanvas" width="400" height="400"></canvas>
                    """, "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()