Skip to content

Instantly share code, notes, and snippets.

@hajimehoshi
Created October 10, 2024 23:58
Show Gist options
  • Save hajimehoshi/6d4994cee36221ab8dbdb04a363cf1aa to your computer and use it in GitHub Desktop.
Save hajimehoshi/6d4994cee36221ab8dbdb04a363cf1aa to your computer and use it in GitHub Desktop.
Loading screen
<!DOCTYPE html>
<style>
body {
background-color: black;
margin: 0;
padding: 0;
overflow: hidden;
font-family: sans-serif;
color: white;
font-size: 30px;
}
#loading {
width: 100dvw;
height: 100dvh;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
}
#progress {
display: flex;
flex-direction: column;
align-items: end;
width: 80%;
}
#progress > span {
text-align: end;
}
#progress > progress {
width: 100%;
height: 40px;
}
</style>
<div id="loading"><div>DOWNLOADING...</div><div id="progress"><span></span><progress></progress></div></div>
<script src="wasm_exec.js"></script>
<script>
window.addEventListener('DOMContentLoaded', async () => {
const loading = document.getElementById('loading');
const observer = new MutationObserver((mutationList) => {
for (let mutation of mutationList) {
if (mutation.type !== 'childList') {
continue;
}
for (const node of mutation.addedNodes) {
if (node.tagName !== 'CANVAS') {
continue;
}
node.focus();
loading.remove();
observer.disconnect();
return;
}
}
});
observer.observe(document.body, {childList: true, subtree: true});
// Create a stream with progress.
const response = await fetch('game.wasm');
// Unfortunately Content-Length might not be available on some servers.
// Hardcode the value.
const contentLength = 1234567890; // The size of game.wasm in bytes.
let loaded = 0;
const progress = document.getElementById('progress');
const progressBar = progress.querySelector('progress');
progressBar.max = contentLength;
const progressText = progress.querySelector('span');
const responseWithProgress = new Response(new ReadableStream({
async start(controller) {
const reader = response.body.getReader();
for (;;) {
const {done, value} = await reader.read();
if (done) {
break;
}
loaded += value.byteLength;
const rate = loaded / contentLength;
progressText.textContent = `${(rate * 100).toFixed(2)}%`;
progressBar.value = loaded;
controller.enqueue(value);
}
controller.close();
},
}, {
'status': response.status,
'statusText': response.statusText,
}));
for (const pair of response.headers.entries()) {
responseWithProgress.headers.set(pair[0], pair[1]);
}
const go = new Go();
const result = await WebAssembly.instantiateStreaming(responseWithProgress, go.importObject)
go.run(result.instance);
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment