summaryrefslogtreecommitdiff
path: root/misc/dist/html
diff options
context:
space:
mode:
authorLeon Krause <lk@leonkrause.com>2017-08-13 13:10:04 +0200
committerLeon Krause <lk@leonkrause.com>2017-09-11 20:56:29 +0200
commit4db801aaeac130a74197ab43e531ce2533414eb9 (patch)
tree65cb628baaea9b9c680557b41f603bba276306bf /misc/dist/html
parentb4ad899ef64df6e341a4cbe52a15109cd3d6b2eb (diff)
HTML5 start-up overhaul
- Implement promise-based JS interface for custom HTML page integration - Add download progress callback - Add progress bar and indeterminate spinner to default HTML page - Try downloading files multiple times when failing - Get rid of godotfs.js - Separate steps for engine initialization, game initialization and game start - Allow multiple games on one HTML page - Substitution placeholders only used in .html file - Placeholders renamed: $GODOT_BASE => $GODOT_BASENAME, $GODOT_TMEM -> $GODOT_TOTAL_MEMORY - Emscripten Module is now Engine.RuntimeEnvironment (no longer a global)
Diffstat (limited to 'misc/dist/html')
-rw-r--r--misc/dist/html/default.html386
1 files changed, 386 insertions, 0 deletions
diff --git a/misc/dist/html/default.html b/misc/dist/html/default.html
new file mode 100644
index 0000000000..9fae34f97e
--- /dev/null
+++ b/misc/dist/html/default.html
@@ -0,0 +1,386 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
+<head>
+ <meta charset="utf-8" />
+ <title></title>
+ <style type="text/css">
+
+ body {
+ margin: 0;
+ border: 0 none;
+ padding: 0;
+ text-align: center;
+ background-color: #222226;
+ font-family: 'Noto Sans', Arial, sans-serif;
+ }
+
+
+ /* Godot Engine default theme style
+ * ================================ */
+
+ .godot {
+ color: #e0e0e0;
+ background-color: #3b3943;
+ background-image: linear-gradient(to bottom, #403e48, #35333c);
+ border: 1px solid #45434e;
+ box-shadow: 0 0 1px 1px #2f2d35;
+ }
+
+ button.godot {
+ font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */
+ padding: 1px 5px;
+ background-color: #37353f;
+ background-image: linear-gradient(to bottom, #413e49, #3a3842);
+ border: 1px solid #514f5d;
+ border-radius: 1px;
+ box-shadow: 0 0 1px 1px #2a2930;
+ }
+
+ button.godot:hover {
+ color: #f0f0f0;
+ background-color: #44414e;
+ background-image: linear-gradient(to bottom, #494652, #423f4c);
+ border: 1px solid #5a5667;
+ box-shadow: 0 0 1px 1px #26252b;
+ }
+
+ button.godot:active {
+ color: #fff;
+ background-color: #3e3b46;
+ background-image: linear-gradient(to bottom, #36343d, #413e49);
+ border: 1px solid #4f4c59;
+ box-shadow: 0 0 1px 1px #26252b;
+ }
+
+ button.godot:disabled {
+ color: rgba(230, 230, 230, 0.2);
+ background-color: #3d3d3d;
+ background-image: linear-gradient(to bottom, #434343, #393939);
+ border: 1px solid #474747;
+ box-shadow: 0 0 1px 1px #2d2b33;
+ }
+
+
+ /* Canvas / wrapper
+ * ================ */
+
+ #container {
+ display: inline-block; /* scale with canvas */
+ vertical-align: top; /* prevent extra height */
+ position: relative; /* root for absolutely positioned overlay */
+ margin: 0;
+ border: 0 none;
+ padding: 0;
+ background-color: #0c0c0c;
+ }
+
+ #canvas {
+ display: block;
+ margin: 0 auto;
+ color: white;
+ }
+
+ #canvas:focus {
+ outline: none;
+ }
+
+
+ /* Status display
+ * ============== */
+
+ #status {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ /* don't consume click events - make children visible explicitly */
+ visibility: hidden;
+ }
+
+ #status-progress {
+ width: 244px;
+ height: 7px;
+ background-color: #38363A;
+ border: 1px solid #444246;
+ padding: 1px;
+ box-shadow: 0 0 2px 1px #1B1C22;
+ border-radius: 2px;
+ visibility: visible;
+ }
+
+ #status-progress-inner {
+ height: 100%;
+ width: 0;
+ box-sizing: border-box;
+ transition: width 0.5s linear;
+ background-color: #202020;
+ border: 1px solid #222223;
+ box-shadow: 0 0 1px 1px #27282E;
+ border-radius: 3px;
+ }
+
+ #status-indeterminate {
+ visibility: visible;
+ position: relative;
+ }
+
+ #status-indeterminate > div {
+ width: 3px;
+ height: 0;
+ border-style: solid;
+ border-width: 6px 2px 0 2px;
+ border-color: #2b2b2b transparent transparent transparent;
+ transform-origin: center 14px;
+ position: absolute;
+ }
+
+ #status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); }
+ #status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); }
+ #status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); }
+ #status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); }
+ #status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); }
+ #status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); }
+ #status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); }
+ #status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); }
+
+ #status-notice {
+ margin: 0 100px;
+ line-height: 1.3;
+ visibility: visible;
+ padding: 4px 6px;
+ visibility: visible;
+ }
+
+
+ /* Debug output
+ * ============ */
+
+ #output-panel {
+ display: none;
+ max-width: 700px;
+ font-size: small;
+ margin: 6px auto 0;
+ padding: 0 4px 4px;
+ text-align: left;
+ line-height: 2.2;
+ }
+
+ #output-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ #output-container {
+ padding: 6px;
+ background-color: #2c2a32;
+ box-shadow: inset 0 0 1px 1px #232127;
+ color: #bbb;
+ }
+
+ #output-scroll {
+ line-height: 1;
+ height: 12em;
+ overflow-y: scroll;
+ white-space: pre-wrap;
+ font-size: small;
+ font-family: "Lucida Console", Monaco, monospace;
+ }
+ </style>
+$GODOT_HEAD_INCLUDE
+</head>
+<body>
+ <div id="container">
+ <canvas id="canvas" oncontextmenu="event.preventDefault();" width="640" height="480">
+ HTML5 canvas appears to be unsupported in the current browser.<br />
+ Please try updating or use a different browser.
+ </canvas>
+ <div id="status">
+ <div id='status-progress' style='display: none;' oncontextmenu="event.preventDefault();"><div id ='status-progress-inner'></div></div>
+ <div id='status-indeterminate' style='display: none;' oncontextmenu="event.preventDefault();">
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+ <div id="status-notice" class="godot" style='display: none;'></div>
+ </div>
+ </div>
+ <div id="output-panel" class="godot">
+ <div id="output-header">
+ Output:
+ <button id='output-clear' class='godot' type='button' autocomplete='off'>Clear</button>
+ </div>
+ <div id="output-container"><div id="output-scroll"></div></div>
+ </div>
+
+ <script type="text/javascript" src="$GODOT_BASENAME.js"></script>
+ <script type="text/javascript">//<![CDATA[
+
+ var game = new Engine;
+
+ (function() {
+
+ const BASENAME = '$GODOT_BASENAME';
+ const MEMORY_SIZE = $GODOT_TOTAL_MEMORY;
+ const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED;
+ const INDETERMINATE_STATUS_STEP_MS = 100;
+
+ var container = document.getElementById('container');
+ var canvas = document.getElementById('canvas');
+ var statusProgress = document.getElementById('status-progress');
+ var statusProgressInner = document.getElementById('status-progress-inner');
+ var statusIndeterminate = document.getElementById('status-indeterminate');
+ var statusNotice = document.getElementById('status-notice');
+
+ var initializing = true;
+ var statusMode = 'hidden';
+ var indeterminiateStatusAnimationId = 0;
+
+ setStatusMode('indeterminate');
+ game.setCanvas(canvas);
+ game.setAsmjsMemorySize(MEMORY_SIZE);
+
+ function setStatusMode(mode) {
+
+ if (statusMode === mode || !initializing)
+ return;
+ [statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
+ elem.style.display = 'none';
+ });
+ if (indeterminiateStatusAnimationId !== 0) {
+ cancelAnimationFrame(indeterminiateStatusAnimationId);
+ indeterminiateStatusAnimationId = 0;
+ }
+ switch (mode) {
+ case 'progress':
+ statusProgress.style.display = 'block';
+ break;
+ case 'indeterminate':
+ statusIndeterminate.style.display = 'block';
+ indeterminiateStatusAnimationId = requestAnimationFrame(animateStatusIndeterminate);
+ break;
+ case 'notice':
+ statusNotice.style.display = 'block';
+ break;
+ case 'hidden':
+ break;
+ default:
+ throw new Error("Invalid status mode");
+ }
+ statusMode = mode;
+ }
+
+ function animateStatusIndeterminate(ms) {
+ var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);
+ if (statusIndeterminate.children[i].style.borderTopColor == '') {
+ Array.prototype.slice.call(statusIndeterminate.children).forEach(child => {
+ child.style.borderTopColor = '';
+ });
+ statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf';
+ }
+ requestAnimationFrame(animateStatusIndeterminate);
+ }
+
+ function setStatusNotice(text) {
+
+ while (statusNotice.lastChild) {
+ statusNotice.removeChild(statusNotice.lastChild);
+ }
+ var lines = text.split('\n');
+ lines.forEach((line, index) => {
+ statusNotice.appendChild(document.createTextNode(line));
+ statusNotice.appendChild(document.createElement('br'));
+ });
+ };
+
+ game.setProgressFunc((current, total) => {
+
+ if (total > 0) {
+ statusProgressInner.style.width = current/total * 100 + '%';
+ setStatusMode('progress');
+ if (current === total) {
+ // wait for progress bar animation
+ setTimeout(() => {
+ setStatusMode('indeterminate');
+ }, 500);
+ }
+ } else {
+ setStatusMode('indeterminate');
+ }
+ });
+
+ if (DEBUG_ENABLED) {
+ var outputRoot = document.getElementById("output-panel");
+ var outputScroll = document.getElementById("output-scroll");
+ var OUTPUT_MSG_COUNT_MAX = 400;
+
+ document.getElementById('output-clear').addEventListener('click', () => {
+ while (outputScroll.firstChild) {
+ outputScroll.firstChild.remove();
+ }
+ });
+
+ outputRoot.style.display = 'block';
+
+ function print(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ if (text.length <= 0) return;
+ while (outputScroll.childElementCount >= OUTPUT_MSG_COUNT_MAX) {
+ outputScroll.firstChild.remove();
+ }
+ var msg = document.createElement("div");
+ if (String.prototype.trim.call(text).startsWith("**ERROR**")) {
+ msg.style.color = "#d44";
+ } else if (String.prototype.trim.call(text).startsWith("**WARNING**")) {
+ msg.style.color = "#ccc000";
+ } else if (String.prototype.trim.call(text).startsWith("**SCRIPT ERROR**")) {
+ msg.style.color = "#c6d";
+ }
+ msg.textContent = text;
+ var scrollToBottom = outputScroll.scrollHeight - (outputScroll.clientHeight + outputScroll.scrollTop) < 10;
+ outputScroll.appendChild(msg);
+ if (scrollToBottom) {
+ outputScroll.scrollTop = outputScroll.scrollHeight;
+ }
+ };
+
+ function printError(text) {
+ print('**ERROR**' + ":", text);
+ }
+
+ game.setStdoutFunc(text => {
+ print(text);
+ console.log(text);
+ });
+
+ game.setStderrFunc(text => {
+ printError(text);
+ console.warn(text);
+ });
+ }
+
+ game.start(BASENAME + '.pck').then(() => {
+ setStatusMode('hidden');
+ initializing = false;
+ }, err => {
+ if (DEBUG_ENABLED)
+ printError(err.message);
+ setStatusNotice(err.message);
+ setStatusMode('notice');
+ initializing = false;
+ });
+ })();
+ //]]></script>
+</body>
+</html>