byte-vortex commited on
Commit
68a8db7
·
verified ·
1 Parent(s): 61cd9b6

Deploy Myco from CI

Browse files
Files changed (1) hide show
  1. ui/interface.py +183 -90
ui/interface.py CHANGED
@@ -1,103 +1,196 @@
1
  import gradio as gr
2
- from game.engine import get_myco_narrative
3
-
4
- # Exported CSS for use in your app.launch(css=MYCO_CSS)
5
- MYCO_CSS = """
6
- #garden-canvas {
7
- width: 100%;
8
- height: 400px;
9
- background: linear-gradient(180deg, #1a2b4c 0%, #2a4c5e 50%, #4a7c59 100%);
10
- border-radius: 12px;
11
- }
12
- #narrative-box {
13
- font-family: 'Courier New', monospace;
14
- font-size: 15px;
15
- color: #52ff6b;
16
- background: #090e0b;
17
- padding: 15px;
18
- border-radius: 8px;
19
- border: 1px solid rgba(82, 255, 107, 0.3);
20
- text-align: center;
21
- margin-top: 10px;
22
- }
23
- """
24
 
25
- def render_shroom_tab():
26
- with gr.Blocks() as demo:
27
- # 1. The Canvas
28
- gr.HTML("<canvas id='garden-canvas'></canvas>")
29
-
30
- # 2. The Narrative
31
- narrative = gr.Markdown(value="Waiting for the forest to wake...", elem_id="narrative-box")
32
-
33
- # 3. Timer (Updates every 20s via game engine)
34
- gr.Timer(20).tick(fn=get_myco_narrative, outputs=narrative)
35
-
36
- # 4. Injected Animation Logic
37
- gr.HTML("""
 
 
 
 
 
 
 
 
38
  <script>
39
- (function() {
40
- const canvas = document.getElementById('garden-canvas');
41
- const ctx = canvas.getContext('2d');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- function resize() {
44
- canvas.width = canvas.parentElement.clientWidth;
45
- canvas.height = 400;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- window.addEventListener('resize', resize);
48
- resize();
49
-
50
- const mushrooms = [];
51
- const fireflies = [];
52
-
53
- function drawMushroom(m, time) {
54
- ctx.save();
55
- ctx.translate(m.x, m.y);
56
- const sway = Math.sin(time * 0.002 + m.phase) * 0.1;
57
- const bounce = Math.sin(time * 0.005 + m.phase) * 0.05 + 1;
58
- ctx.rotate(sway);
59
- ctx.scale(m.currentSize, m.currentSize * bounce);
60
 
61
- ctx.fillStyle = '#fff4e6';
62
- ctx.beginPath(); ctx.roundRect(-12, 0, 24, 35, 10); ctx.fill();
 
 
63
 
64
- ctx.fillStyle = '#4a3b32';
65
- const isBlinking = (time % m.blinkInterval) < 150;
66
- if (isBlinking) {
67
- ctx.fillRect(-7, 12, 4, 2);
68
- ctx.fillRect(3, 12, 4, 2);
69
- } else {
70
- ctx.beginPath(); ctx.arc(-5, 12, 2.5, 0, Math.PI*2); ctx.fill();
71
- ctx.beginPath(); ctx.arc(5, 12, 2.5, 0, Math.PI*2); ctx.fill();
72
- }
73
- ctx.restore();
74
  }
 
75
 
76
- function animate(time) {
77
- ctx.clearRect(0, 0, canvas.width, canvas.height);
78
- if (Math.random() < 0.02 && mushrooms.length < 20) {
79
- mushrooms.push({
80
- x: Math.random() * canvas.width,
81
- y: (canvas.height * 0.5) + (Math.random() * canvas.height * 0.4),
82
- targetSize: Math.random() * 1.5 + 0.8,
83
- currentSize: 0,
84
- blinkInterval: Math.floor(Math.random() * 3000) + 2000,
85
- phase: Math.random() * Math.PI * 2,
86
- life: 500
87
- });
88
- }
89
- mushrooms.forEach((m, i) => {
90
- m.life--;
91
- m.currentSize += (m.targetSize - m.currentSize) * 0.05;
92
- drawMushroom(m, time);
93
- if (m.life < 0) m.targetSize = 0;
94
- if (m.life < 0 && m.currentSize < 0.05) mushrooms.splice(i, 1);
95
  });
96
- requestAnimationFrame(animate);
97
  }
98
- animate(0);
99
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  </script>
101
- """)
102
- return demo
 
 
 
 
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ def cute_mushroom_garden_html() -> str:
5
+ """
6
+ Pure iframe srcdoc implementation of a cute mushroom garden.
7
+ Generates happy, blinking mushrooms that grow, sway, and shrink.
8
+ """
9
+ iframe_content = """
10
+ <!DOCTYPE html>
11
+ <html>
12
+ <head>
13
+ <style>
14
+ body {
15
+ margin: 0;
16
+ overflow: hidden;
17
+ /* Soft magical forest background */
18
+ background: linear-gradient(180deg, #1a2b4c 0%, #2a4c5e 50%, #4a7c59 100%);
19
+ }
20
+ canvas { display: block; }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <canvas id="cute-canvas"></canvas>
25
  <script>
26
+ const canvas = document.getElementById('cute-canvas');
27
+ const ctx = canvas.getContext('2d');
28
+
29
+ function resize() {
30
+ canvas.width = window.innerWidth;
31
+ canvas.height = window.innerHeight;
32
+ }
33
+ window.addEventListener('resize', resize);
34
+ resize();
35
+
36
+ const mushrooms = [];
37
+ const fireflies = [];
38
+
39
+ // Helper to draw a single cute mushroom
40
+ function drawMushroom(m, time) {
41
+ ctx.save();
42
+ ctx.translate(m.x, m.y);
43
+
44
+ // Bouncing and swaying math
45
+ const sway = Math.sin(time * 0.002 + m.phase) * 0.1;
46
+ const bounce = Math.sin(time * 0.005 + m.phase) * 0.05 + 1;
47
+
48
+ ctx.rotate(sway);
49
+ ctx.scale(m.currentSize, m.currentSize * bounce);
50
+
51
+ // 1. Draw Stem
52
+ ctx.fillStyle = '#fff4e6';
53
+ ctx.beginPath();
54
+ ctx.roundRect(-12, 0, 24, 35, 10);
55
+ ctx.fill();
56
+
57
+ // 2. Draw Cute Face
58
+ ctx.fillStyle = '#4a3b32';
59
+ const isBlinking = (time % m.blinkInterval) < 150;
60
+
61
+ if (isBlinking) {
62
+ // Closed eyes (wincing/blinking)
63
+ ctx.fillRect(-7, 12, 4, 2);
64
+ ctx.fillRect(3, 12, 4, 2);
65
+ } else {
66
+ // Open eyes
67
+ ctx.beginPath(); ctx.arc(-5, 12, 2.5, 0, Math.PI*2); ctx.fill();
68
+ ctx.beginPath(); ctx.arc(5, 12, 2.5, 0, Math.PI*2); ctx.fill();
69
+ }
70
 
71
+ // Tiny smile
72
+ ctx.strokeStyle = '#4a3b32';
73
+ ctx.lineWidth = 1.5;
74
+ ctx.beginPath();
75
+ ctx.arc(0, 15, 3, 0, Math.PI, false);
76
+ ctx.stroke();
77
+
78
+ // Blush
79
+ ctx.fillStyle = 'rgba(255, 150, 150, 0.5)';
80
+ ctx.beginPath(); ctx.arc(-9, 16, 3, 0, Math.PI*2); ctx.fill();
81
+ ctx.beginPath(); ctx.arc(9, 16, 3, 0, Math.PI*2); ctx.fill();
82
+
83
+ // 3. Draw Cap
84
+ ctx.fillStyle = `hsl(${m.hue}, 80%, 75%)`; // Soft pastel colors
85
+ ctx.beginPath();
86
+ ctx.moveTo(-35, 5);
87
+ // Bezier curves make it look like a puffy umbrella
88
+ ctx.bezierCurveTo(-35, -30, 35, -30, 35, 5);
89
+ ctx.bezierCurveTo(35, 15, -35, 15, -35, 5);
90
+ ctx.fill();
91
+
92
+ // Cap Shadow/Detail
93
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
94
+ ctx.beginPath(); ctx.arc(-15, -12, 6, 0, Math.PI*2); ctx.fill();
95
+ ctx.beginPath(); ctx.arc(12, -8, 4, 0, Math.PI*2); ctx.fill();
96
+ ctx.beginPath(); ctx.arc(0, -18, 5, 0, Math.PI*2); ctx.fill();
97
+
98
+ ctx.restore();
99
+ }
100
+
101
+ function animate(time) {
102
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
103
+
104
+ // --- Fireflies Logic ---
105
+ if (Math.random() < 0.1 && fireflies.length < 50) {
106
+ fireflies.push({
107
+ x: Math.random() * canvas.width,
108
+ y: canvas.height + 10,
109
+ size: Math.random() * 2 + 1,
110
+ speed: Math.random() * 1 + 0.5,
111
+ wobble: Math.random() * Math.PI * 2
112
+ });
113
  }
114
+
115
+ ctx.fillStyle = '#fffae6';
116
+ for (let i = fireflies.length - 1; i >= 0; i--) {
117
+ let f = fireflies[i];
118
+ f.y -= f.speed;
119
+ f.x += Math.sin(time * 0.002 + f.wobble) * 0.5;
 
 
 
 
 
 
 
120
 
121
+ ctx.globalAlpha = Math.sin(time * 0.005 + f.wobble) * 0.5 + 0.5;
122
+ ctx.beginPath();
123
+ ctx.arc(f.x, f.y, f.size, 0, Math.PI * 2);
124
+ ctx.fill();
125
 
126
+ if (f.y < -10) fireflies.splice(i, 1);
 
 
 
 
 
 
 
 
 
127
  }
128
+ ctx.globalAlpha = 1.0;
129
 
130
+ // --- Mushroom Logic ---
131
+ // Randomly spawn new mushrooms
132
+ if (Math.random() < 0.02 && mushrooms.length < 35) {
133
+ mushrooms.push({
134
+ x: Math.random() * canvas.width,
135
+ y: (canvas.height * 0.4) + (Math.random() * canvas.height * 0.6), // Spawn in bottom 60%
136
+ targetSize: Math.random() * 1.5 + 0.8,
137
+ currentSize: 0,
138
+ hue: Math.random() * 360,
139
+ phase: Math.random() * Math.PI * 2,
140
+ blinkInterval: Math.floor(Math.random() * 3000) + 2000,
141
+ life: Math.random() * 500 + 300 // How long they stay before shrinking
 
 
 
 
 
 
 
142
  });
 
143
  }
144
+
145
+ // Sort mushrooms by Y coordinate so closer ones draw on top (Depth sorting)
146
+ mushrooms.sort((a, b) => a.y - b.y);
147
+
148
+ for (let i = mushrooms.length - 1; i >= 0; i--) {
149
+ let m = mushrooms[i];
150
+
151
+ m.life--;
152
+ if (m.life < 0) {
153
+ m.targetSize = 0; // Shrink away
154
+ }
155
+
156
+ // Smoothly grow or shrink
157
+ m.currentSize += (m.targetSize - m.currentSize) * 0.05;
158
+
159
+ drawMushroom(m, time);
160
+
161
+ // Remove if totally shrunk
162
+ if (m.life < 0 && m.currentSize < 0.05) {
163
+ mushrooms.splice(i, 1);
164
+ }
165
+ }
166
+
167
+ requestAnimationFrame(animate);
168
+ }
169
+
170
+ requestAnimationFrame(animate);
171
  </script>
172
+ </body>
173
+ </html>
174
+ """
175
+
176
+ # Safely escape the HTML
177
+ escaped_srcdoc = html.escape(iframe_content)
178
 
179
+ # Return a clean, borderless container
180
+ return f'''
181
+ <div style="width: 100%; height: 500px; border-radius: 16px; overflow: hidden; border: 4px solid #f8c8dc; box-shadow: 0 8px 32px rgba(0,0,0,0.15);">
182
+ <iframe
183
+ srcdoc="{escaped_srcdoc}"
184
+ style="width: 100%; height: 100%; border: none;"
185
+ scrolling="no">
186
+ </iframe>
187
+ </div>
188
+ '''
189
+
190
+ def render_shroom_tab():
191
+ with gr.Tabs():
192
+ with gr.Tab("✨ Magic Mushroom Garden"):
193
+ # Notice how we completely removed all the markdown/buttons!
194
+ # Just the beautiful animation now.
195
+ gr.HTML(value=cute_mushroom_garden_html())
196
+