5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
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">
25 animation-duration: 2s;
26 animation-timing-function: ease-in;
27 animation-fill-mode: forwards;
39 animation-duration: 0.8s;
40 animation-timing-function: ease-in;
41 animation-fill-mode: forwards;
48 transform: translate(-50%, -50%);
84 transform: translate(-50%, -50%);
98 font-family: monospace;
100 white-space: pre-wrap;
108 <div id="welcome" style="visibility: hidden">
109 <div id="header" align="center">
111 <img src="images/1403010940_The_Magic_School_Bus_in_the_apocalypse.png">
115 <div id="welcome-message">
116 <div id="timer_div" style="visibility: hidden">
117 Entering Magic School Bus in <span id="timer"></span> seconds.
120 Students present: <span id="students">1</span>/4
124 <div id="program" style="visibility: hidden">
125 <h1>Magic School Bus</h1>
128 <textarea id="code" rows="15" width="100%"></textarea>
129 <button type="submit">Run code</button>
133 <img id="output"></img>
136 <button id="jumpstart">
137 Jumpstart Magic School Bus
142 <script src="/socket.io/socket.io.js"></script>
144 const socket = io("/bus");
146 const welcome = document.getElementById("welcome");
147 const program = document.getElementById("program");
148 const header = document.getElementById("header");
149 const companions = document.getElementById("students");
150 const timer_div = document.getElementById("timer_div");
151 const timer = document.getElementById("timer");
152 const form = document.getElementById("form");
153 const code = document.getElementById("code");
154 const welcome_message = document.getElementById("welcome-message");
155 const jumpstart = document.getElementById("jumpstart");
156 const output = document.getElementById("output");
157 const error = document.getElementById("error");
159 function fade_element(elt) {
160 elt.style.opacity = "100%";
161 elt.className = "fade-out";
162 // Arrange to clear the class name when the animation is over
163 // This will allow for it to be restarted on the next word.
165 elt.style.opacity = "0%";
170 jumpstart.addEventListener('click', event => {
171 socket.emit('jumpstart');
174 form.addEventListener('submit', event => {
175 event.preventDefault();
176 socket.emit('run', code.value);
179 socket.on('students', (count) => {
180 students.textContent = count.toString();
183 socket.on('code', (code_string) => {
184 code.value = code_string;
187 socket.on('timer', (value) => {
188 timer_div.style.visibility = "visible";
189 timer.textContent = value.toString();
192 welcome_message.style.visibility = "hidden";
193 timer_div.style.visibility = "hidden";
194 header.className = "zoom-into";
195 // Clear that className after the animation is complete
197 header.style.visibility = "hidden"
198 header.className = "";
203 socket.on('error', (error_message) => {
204 error.textContent = error_message;
207 socket.on('state', (state) => {
208 if (state === "program") {
209 welcome.style.visibility = "hidden";
210 program.style.visibility = "visible";
211 } else if (state === "welcome") {
212 welcome.style.visibility = "visible";
213 welcome_message.style.visibility = "visible";
214 header.style.opacity = "100%";
215 header.style.transform = "scale(1)";
216 header.style.visibility = "visible";
217 program.style.visibility = "hidden";
222 socket.on('output', (filename) => {
223 error.textContent = "";
224 output.src = filename;