diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2024-05-18 15:49:24 +0200 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2024-05-18 15:49:24 +0200 |
commit | 9155752f861ae43e3534cdfa833d8c644cb0e5d3 (patch) | |
tree | fb1a0b115c1b23099796b56b30a04cb6fd1864d2 /app.html | |
parent | 3e94dd0704d7b4005f17c1086796afdbbe36b1f5 (diff) |
save/load
Diffstat (limited to 'app.html')
-rw-r--r-- | app.html | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/app.html b/app.html new file mode 100644 index 0000000..078d27d --- /dev/null +++ b/app.html @@ -0,0 +1,217 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"> + <title>$GODOT_PROJECT_NAME</title> + <style> + html, body, #canvas { + margin: 0; + padding: 0; + border: 0; + } + + body { + color: white; + background-color: black; + overflow: hidden; + touch-action: none; + } + + #canvas { + display: block; + } + + #canvas:focus { + outline: none; + } + + #status, #status-splash, #status-progress { + position: absolute; + left: 0; + right: 0; + } + + #status, #status-splash { + top: 0; + bottom: 0; + } + + #status { + background-color: #242424; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + visibility: hidden; + } + + #status-splash { + max-height: 100%; + max-width: 100%; + margin: auto; + } + + #status-progress, #status-notice { + display: none; + } + + #status-progress { + bottom: 10%; + width: 50%; + margin: 0 auto; + } + + #status-notice { + background-color: #5b3943; + border-radius: 0.5rem; + border: 1px solid #9b3943; + color: #e0e0e0; + font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif; + line-height: 1.3; + margin: 0 2rem; + overflow: hidden; + padding: 1rem; + text-align: center; + z-index: 1; + } + </style> + $GODOT_HEAD_INCLUDE + <script> + var godotCallbacks = { + dataLoaded: null + } + + function openLoadDialog() { + var input = document.createElement('input'); + input.setAttribute('type', 'file'); + input.setAttribute('accept', '.json'); + input.click(); + + input.addEventListener('change', (event) => { + var file = event.target.files[0]; + var reader = new FileReader(); + + reader.readAsText(file); + + reader.onloadend = () => { + if (godotCallbacks.dataLoaded) { + godotCallbacks.dataLoaded(reader.result); + } + } + }); + } + </script> + </head> + <body> + <canvas id="canvas"> + Your browser does not support the canvas tag. + </canvas> + + <noscript> + Your browser does not support JavaScript. + </noscript> + + <div id="status"> + <img id="status-splash" src="$GODOT_SPLASH" alt=""> + <progress id="status-progress"></progress> + <div id="status-notice"></div> + </div> + + <script src="$GODOT_URL"></script> + <script> + const GODOT_CONFIG = $GODOT_CONFIG; + // const GODOT_THREADS_ENABLED = $GODOT_THREADS_ENABLED; + const GODOT_THREADS_ENABLED = 'yes'; + const engine = new Engine(GODOT_CONFIG); + + (function () { + const statusOverlay = document.getElementById('status'); + const statusProgress = document.getElementById('status-progress'); + const statusNotice = document.getElementById('status-notice'); + + let initializing = true; + let statusMode = ''; + + function setStatusMode(mode) { + if (statusMode === mode || !initializing) { + return; + } + if (mode === 'hidden') { + statusOverlay.remove(); + initializing = false; + return; + } + statusOverlay.style.visibility = 'visible'; + statusProgress.style.display = mode === 'progress' ? 'block' : 'none'; + statusNotice.style.display = mode === 'notice' ? 'block' : 'none'; + statusMode = mode; + } + + function setStatusNotice(text) { + while (statusNotice.lastChild) { + statusNotice.removeChild(statusNotice.lastChild); + } + const lines = text.split('\n'); + lines.forEach((line) => { + statusNotice.appendChild(document.createTextNode(line)); + statusNotice.appendChild(document.createElement('br')); + }); + } + + function displayFailureNotice(err) { + const msg = err.message || err; + console.error(msg); + setStatusNotice(msg); + setStatusMode('notice'); + initializing = false; + } + + const missing = Engine.getMissingFeatures({ + threads: GODOT_THREADS_ENABLED, + }); + + if (missing.length !== 0) { + if (GODOT_CONFIG['serviceWorker'] && GODOT_CONFIG['ensureCrossOriginIsolationHeaders'] && 'serviceWorker' in navigator) { + // There's a chance that installing the service worker would fix the issue + Promise.race([ + navigator.serviceWorker.getRegistration().then((registration) => { + if (registration != null) { + return Promise.reject(new Error('Service worker already exists.')); + } + return registration; + }).then(() => engine.installServiceWorker()), + // For some reason, `getRegistration()` can stall + new Promise((resolve) => { + setTimeout(() => resolve(), 2000); + }), + ]).catch((err) => { + console.error('Error while registering service worker:', err); + }).then(() => { + window.location.reload(); + }); + } else { + // Display the message as usual + const missingMsg = 'Error\nThe following features required to run Godot projects on the Web are missing:\n'; + displayFailureNotice(missingMsg + missing.join('\n')); + } + } else { + setStatusMode('progress'); + engine.startGame({ + 'onProgress': function (current, total) { + if (current > 0 && total > 0) { + statusProgress.value = current; + statusProgress.max = total; + } else { + statusProgress.removeAttribute('value'); + statusProgress.removeAttribute('max'); + } + }, + }).then(() => { + setStatusMode('hidden'); + }, displayFailureNotice); + } + }()); + </script> + </body> +</html> |