]> git.cworth.org Git - zombocom-ai/blob - index.html
Remove the cancel button from the profile dialog
[zombocom-ai] / index.html
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6   <title>ZOMBO</title>
7   <link href="/zombo.css" rel="stylesheet" type="text/css">
8   <meta name="viewport" content="width=device-width,initial-scale=1">
9   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
10   <meta name="HandheldFriendly" content="true">
11 </head>
12
13 <body>
14   <div id="content">
15
16     <div id="header" align="center">
17       <p>
18         <br>
19       </p>
20
21       <p>
22         <img src="/zombocom.png" alt="Zombocom" longdesc="http://zombo.com" width="1199" height="217">
23       </p>
24     </div>
25
26     <p>
27       Welcome to Zombocom. You can do anything at Zombocom, anything at
28       all. The only limit is yourself!
29     </p>
30
31     <dialog id="name-dialog">
32       <form method="dialog">
33         <p>
34           <label>Your name:
35             <input id="name" type="text" autocomplete="off">
36           </label>
37         </p>
38         <div>
39           <button value="default">OK</button>
40         </div>
41       </form>
42     </dialog>
43
44     <p>
45       <div id="spinner" align="center">
46         <div class="animate-flicker">
47           <p>
48             <img src="/pngwheel.png" class="rotate thefade">
49           </p>
50         </div>
51       </div>
52
53       <form action="" id="zombo-form">
54         <div class="form-row large">
55           <label for="prompt">
56             What can you imagine?
57           </label>
58           <button id="safety" type="button">Safety prompt</button>
59           <textarea id="prompt" rows="4" width="100%" autocomplete="off" required></textarea>
60         </div>
61
62         <div class="form-row small left">
63           <div class="labeled-row">
64             <label for="code">
65               Numeric code:
66             </label>
67             <input id="code" type="text" autocomplete="off" placeholder="(Leave blank for random)" />
68           </div>
69         </div>
70
71         <div class="form-row large">
72           <button id="generate" type="submit">Make the infinite possible</button>
73         </div>
74       </form>
75     </p>
76
77     <div id="images">
78     </div>
79
80     <dl id="comments">
81     </dl>
82
83     <p>
84       <form action="" id="comment-form">
85         <input id="comment" type="text" style="width:100%" autocomplete="off" placeholder="Add a comment" />
86       </form>
87     </p>
88
89     <audio loop="" src="/zombo_words.mp3" type="audio/mpeg"></audio>
90     <button id="mute" class="menu-button fade volume">
91       <div>🔊</div>
92       <script>
93 const mute = document.querySelector("#mute");
94 const icon = document.querySelector("#mute > div");
95 const audio = document.querySelector("audio");
96
97 mute.addEventListener("click", () => {
98   if (audio.paused) {
99       audio.volume = 0.2;
100       audio.play();
101       icon.innerHTML = "🔈";
102   } else {
103       audio.pause();
104       icon.innerHTML = "🔊";
105   }
106   mute.classList.add("fade");
107 });
108       </script>
109
110     </button>
111
112     <button id="profile" class="menu-button">
113       <div>👤</div>
114     </button>
115
116   </div>
117
118   <script src="/socket.io/socket.io.js"></script>
119   <script>
120     var socket = io();
121
122     const name = document.querySelector("#name");
123     const name_dialog = document.querySelector("#name-dialog");
124     const images = document.querySelector("#images");
125     const comments = document.querySelector("#comments");
126     const comment_form = document.querySelector("#comment-form");
127     const comment = document.querySelector("#comment");
128     const zombo_form = document.querySelector("#zombo-form");
129     const prompt = document.querySelector("#prompt");
130     const code = document.querySelector("#code");
131     const safety= document.querySelector("#safety");
132     const spinner = document.querySelector("#spinner");
133     const profile = document.querySelector("#profile");
134     var spinner_timeout;
135
136     comment.addEventListener('focus', () => {
137         /* Do nothing if name is already set. */
138         if (name.value)
139             return;
140
141         /* Otherwise, bring up the modal dialog to set the name. */
142         name_dialog.showModal();
143     });
144
145     profile.addEventListener('click', () => {
146         name_dialog.showModal();
147     });
148
149     name_dialog.addEventListener('close', () => {
150         socket.emit('set-name', name.value);
151     });
152
153     comment_form.addEventListener('submit', function(e) {
154         e.preventDefault();
155         if (comment.value) {
156             socket.emit('comment', comment.value);
157             comment.value = '';
158         }
159     });
160
161     socket.on('comment', function(comment) {
162         const dt = document.createElement('dt');
163         const dd = document.createElement('dd');
164         dt.textContent = comment.name;
165         dd.textContent = comment.text;
166         comments.appendChild(dt);
167         comments.appendChild(dd);
168     });
169
170     socket.on('inform-name', (name) => {
171         console.log("Received inform-name event: " + name);
172         name.value = name;
173     });
174
175     socket.on('reset', () => {
176         images.replaceChildren();
177     });
178
179     socket.on('image', (image) => {
180         const figure = document.createElement('figure');
181         const img = document.createElement('img');
182         img.src = image.filename;
183         const figcaption = document.createElement('figcaption');
184         const caption_text = document.createTextNode(`${image.prompt} (${image.code})`);
185         figcaption.appendChild(caption_text);
186         figure.appendChild(img);
187         figure.appendChild(figcaption);
188         images.prepend(figure);
189     });
190
191     function hide_spinner() {
192         zombo_form.style.display = "grid";
193         spinner.style.display = "none";
194     }
195
196     zombo_form.addEventListener('submit', function(e) {
197         e.preventDefault();
198         /* Hide the form and show spinner while generation is happening. */
199         zombo_form.style.display = "none";
200         spinner.style.display = "block";
201         spinner_timeout = setTimeout(hide_spinner, 60000);
202         socket.emit('generate', {"prompt": prompt.value, "code": code.value});
203         prompt.value = '';
204     });
205
206     socket.on('generation-done', () => {
207         /* Re-display the form and hide spinner now that generation is over. */
208         clearTimeout(spinner_timeout);
209         hide_spinner();
210     });
211
212     function random_from(items) {
213         return items[Math.floor(Math.random()*items.length)];
214     }
215
216     safety.addEventListener("click", () => {
217         const art_type = [
218             "A portrait of",
219             "A hyperrealistic photograph of",
220             "A matte painting of",
221             "Epic fantasy card art of",
222             "Professional oil painting of",
223             "An image of",
224             "A pencil sketch of",
225             "A watercolor of",
226         ];
227         const subject = [
228             " a modern home",
229             " crashing waves",
230             " a Porsche 911 Carrera",
231             " a Halo spartan",
232             " a cute cat",
233             " a mad scientist",
234             " an elfin princess",
235             " sci-fi buildings",
236             " pastel purple clouds",
237             " a Teenage Mutant Ninja Turtle",
238         ];
239         const scenery = [
240             " in tropical surroundings",
241             " in space",
242             " in an ocean storm",
243             " in a snowy forest",
244             " in a cardboard box",
245             " holding an axe",
246             " in an epic landscape",
247             " in a haunted forest",
248             " riding a motorbike",
249             " in a futuristic city at night",
250             " in a dystopian landscape, foggy",
251             " in the land of snow",
252             " that looks like a watermelon",
253             " on the streets of London at night with neon lights flashing",
254             " that is part octopus",
255             " melting into a puddle",
256         ];
257         const artist = [
258             ", unreal engine 5",
259             ", concept art",
260             ", graphic novel",
261             " by Vincent Van Gogh",
262             " by Claude Monet",
263             " by Johannes Vermeer",
264             ", fantasy art, neon fog",
265             ", epic lighting from above",
266             ", trending on artstation",
267         ];
268
269         prompt.value = random_from(art_type) + random_from(subject) +
270             random_from(scenery) + random_from(artist);
271         return false;
272     });
273
274   </script>
275 </body>
276 </html>