diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-21 11:09:56 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-21 11:09:56 +0200 |
| commit | 123144c93bfc77883c8fb517828b47bbe13b8671 (patch) | |
| tree | 762739afedb5f3f168051367515cb9b9a06ec68d /raylib/src/shell.html | |
| download | minesweeper-123144c93bfc77883c8fb517828b47bbe13b8671.tar.gz minesweeper-123144c93bfc77883c8fb517828b47bbe13b8671.zip | |
Diffstat (limited to 'raylib/src/shell.html')
| -rw-r--r-- | raylib/src/shell.html | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/raylib/src/shell.html b/raylib/src/shell.html new file mode 100644 index 0000000..51e675f --- /dev/null +++ b/raylib/src/shell.html | |||
| @@ -0,0 +1,338 @@ | |||
| 1 | <!doctype html> | ||
| 2 | <html lang="EN-us"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||
| 6 | |||
| 7 | <title>raylib web game</title> | ||
| 8 | |||
| 9 | <meta name="title" content="raylib web game"> | ||
| 10 | <meta name="description" content="New raylib web videogame, developed using raylib videogames library"> | ||
| 11 | <meta name="keywords" content="raylib, programming, examples, html5, C, C++, library, learn, games, videogames"> | ||
| 12 | <meta name="viewport" content="width=device-width"> | ||
| 13 | |||
| 14 | <!-- Open Graph metatags for sharing --> | ||
| 15 | <meta property="og:type" content="website" /> | ||
| 16 | <meta property="og:title" content="raylib web game"> | ||
| 17 | <meta property="og:image:type" content="image/png"> | ||
| 18 | <meta property="og:image:alt" content="New raylib web videogame, developed using raylib videogames library" /> | ||
| 19 | <meta property="og:image" content="https://www.raylib.com/common/raylib_logo.png"> | ||
| 20 | <meta property="og:site_name" content="raylib - example"> | ||
| 21 | <meta property="og:url" content="https://www.raylib.com/games.html"> | ||
| 22 | <meta property="og:description" content="New raylib web videogame, developed using raylib videogames library"> | ||
| 23 | |||
| 24 | <!-- Twitter metatags for sharing --> | ||
| 25 | <meta name="twitter:card" content="summary_large_image"> | ||
| 26 | <meta name="twitter:site" content="@raysan5"> | ||
| 27 | <meta name="twitter:title" content="raylib web game"> | ||
| 28 | <meta name="twitter:image" content="https://www.raylib.com/common/raylib_logo.png"> | ||
| 29 | <meta name="twitter:image:alt" content="New raylib web videogame, developed using raylib videogames library"> | ||
| 30 | <meta name="twitter:url" content="https://www.raylib.com/games.html"> | ||
| 31 | <meta name="twitter:description" content="New raylib web videogame, developed using raylib videogames library"> | ||
| 32 | |||
| 33 | <!-- Favicon --> | ||
| 34 | <link rel="shortcut icon" href="https://www.raylib.com/favicon.ico"> | ||
| 35 | |||
| 36 | <style> | ||
| 37 | body { | ||
| 38 | font-family: arial; | ||
| 39 | margin: 0; | ||
| 40 | padding: none; | ||
| 41 | } | ||
| 42 | |||
| 43 | #header { | ||
| 44 | width: 100%; | ||
| 45 | height: 80px; | ||
| 46 | background-color: #888888; | ||
| 47 | } | ||
| 48 | |||
| 49 | /* NOTE: raylib logo is embedded in the page as base64 png image */ | ||
| 50 | #logo { | ||
| 51 | width:64px; | ||
| 52 | height:64px; | ||
| 53 | float:left; | ||
| 54 | position:relative; | ||
| 55 | margin:10px; | ||
| 56 | background-image:url('data:image/png;base64,\ | ||
| 57 | iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADs\ | ||
| 58 | MAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAA7JJREFUaEPtk0FyWzEMQ+37X7fZhxX4\ | ||
| 59 | YY3AD1OKF1nkzTRlSBCCLeVBnvl/AUdaELOunPno1kts1kixdtEZKVs+xIxebBkZsVknn/L5nFGDLR8T4zVC9fX19S/+tTFijr\ | ||
| 60 | YK4jUjbPUtqBHpnEE6PkZD7jQZV8n5Recw1XQKciZuPaEtR6UjNs5ENVGMsBVqpPtER0ZMOhpyp8m4YL4OjD9yxsyZxnQycfMJ\ | ||
| 61 | ETNSzsRE1+dihK3YMiJmpHTW3xpmXPC6BXlCHfqnBlsjY5hxf/6EVEOM2BTEi0fYCX4ONSI6Kq3Blg/prIOMq2CsRur4KQ0x64\ | ||
| 62 | SdjOufEDEdHZGOhmz5RDHCVqhRuQ86YsVskbc+GXchLiHnFyYH+UigQDVGnImbT8hwFkgLg2qiM8JO6Ylx1FNLa3DmYwqCTsZd\ | ||
| 63 | 4BPqGJG7MwKzpeiWKTKxXkLMVE3MSOmsdwxLH6Rd/wCCLSNDx6djeKfJuArGeoYamRHpaEjnCBYZVy8hZqo2GI36qPjsiOiMsB\ | ||
| 64 | XGcev4Mx9TLGTchbgEjN/uz6jGrBvDjg+LTNx8Qp2CbG2xMKgmOiPslJ4Yxx+eSnSkzlosZNwFPiHl7FRTkLNRJm4+IeVM0ymI\ | ||
| 65 | H42wE/wcKalQI4MRl4EW3p6VcRWMua8F6WjIlqZDxvVPiHQ6CjVbYkV9ohhhp/Rk1wiYgpyJ78i4CsZbjkb8Qx+ihvzu3RPaKo\ | ||
| 66 | gZkY6GlEeMsKdPSOFIC8VoOusg44L5c+T8ouOoGhWbdWJ8tMi4egkxo4hoh2yNTGf3iIyr5Lyic4bRENXo+lvDjAt4C1Hk/OKt\ | ||
| 67 | UaAj0+n4dMSZ2D+hrYJsaYh2SClG2jV9kJKKzhlGQ1SsW299Mq6C8dYZHTExo8fzieI5ivipYnYy7nwJqGKmOYyRwfiUBXITfh\ | ||
| 68 | 5qSHRGWEkfqJqURgvsdHyWYv7Ko8DnYYegk3EB00cxprdrJRzFd7YQzawu8L1GMTYS/KpPaAFTkIn1EmJmspJSs5xBzSyGhlkB\ | ||
| 69 | mlxfNFiP5mw4wlbMh4F5Ddxp5jNINBdCEz9zPOC1zD7Q0HBdmXndwv0TMtydEdzlWJT4VZ8Qt9Qn4/onxMIwa5ZYGJU5yufBiC\ | ||
| 70 | jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaBBfOTCGHM2aEbZi1+gO\ | ||
| 71 | 1XTWVXMnzrhAn5DSOZVsiQlHnSITKzGj6DeTcZWc/3oy7h9//PF4PL4BlvsWrb6RE+oAAAAASUVORK5CYII='); | ||
| 72 | } | ||
| 73 | |||
| 74 | .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } | ||
| 75 | div.emscripten { text-align: center; } | ||
| 76 | div.emscripten_border { border: 1px solid black; } | ||
| 77 | |||
| 78 | /* NOTE: Canvas *must not* have any border or padding, or mouse coords will be wrong */ | ||
| 79 | canvas.emscripten { | ||
| 80 | border: 0px none; | ||
| 81 | background: black; | ||
| 82 | width: 100%; | ||
| 83 | } | ||
| 84 | |||
| 85 | .spinner { | ||
| 86 | height: 30px; | ||
| 87 | width: 30px; | ||
| 88 | margin: 0; | ||
| 89 | margin-top: 20px; | ||
| 90 | margin-left: 20px; | ||
| 91 | display: inline-block; | ||
| 92 | vertical-align: top; | ||
| 93 | -webkit-animation: rotation .8s linear infinite; | ||
| 94 | -moz-animation: rotation .8s linear infinite; | ||
| 95 | -o-animation: rotation .8s linear infinite; | ||
| 96 | animation: rotation 0.8s linear infinite; | ||
| 97 | border-left: 5px solid black; | ||
| 98 | border-right: 5px solid black; | ||
| 99 | border-bottom: 5px solid black; | ||
| 100 | border-top: 5px solid red; | ||
| 101 | border-radius: 100%; | ||
| 102 | background-color: rgb(245, 245, 245); | ||
| 103 | } | ||
| 104 | @-webkit-keyframes rotation { | ||
| 105 | from {-webkit-transform: rotate(0deg);} | ||
| 106 | to {-webkit-transform: rotate(360deg);} | ||
| 107 | } | ||
| 108 | @-moz-keyframes rotation { | ||
| 109 | from {-moz-transform: rotate(0deg);} | ||
| 110 | to {-moz-transform: rotate(360deg);} | ||
| 111 | } | ||
| 112 | @-o-keyframes rotation { | ||
| 113 | from {-o-transform: rotate(0deg);} | ||
| 114 | to {-o-transform: rotate(360deg);} | ||
| 115 | } | ||
| 116 | @keyframes rotation { | ||
| 117 | from {transform: rotate(0deg);} | ||
| 118 | to {transform: rotate(360deg);} | ||
| 119 | } | ||
| 120 | |||
| 121 | #status { | ||
| 122 | display: inline-block; | ||
| 123 | vertical-align: top; | ||
| 124 | margin-top: 30px; | ||
| 125 | margin-left: 20px; | ||
| 126 | font-weight: bold; | ||
| 127 | color: rgb(40, 40, 40); | ||
| 128 | } | ||
| 129 | |||
| 130 | #progress { | ||
| 131 | height: 0px; | ||
| 132 | width: 0px; | ||
| 133 | } | ||
| 134 | |||
| 135 | #controls { | ||
| 136 | display: inline-block; | ||
| 137 | float: right; | ||
| 138 | vertical-align: top; | ||
| 139 | margin-top: 15px; | ||
| 140 | margin-right: 20px; | ||
| 141 | } | ||
| 142 | |||
| 143 | #output { | ||
| 144 | border-left: 0px none; | ||
| 145 | border-right: 0px none; | ||
| 146 | border-bottom: 0px none; | ||
| 147 | padding-left: 0; | ||
| 148 | padding-right: 0; | ||
| 149 | width: 100%; | ||
| 150 | height: 140px; | ||
| 151 | margin: 0 auto; | ||
| 152 | margin-top: 10px; | ||
| 153 | display: block; | ||
| 154 | background-color: black; | ||
| 155 | color: rgb(37, 174, 38); | ||
| 156 | font-family: 'Lucida Console', Monaco, monospace; | ||
| 157 | outline: none; | ||
| 158 | } | ||
| 159 | |||
| 160 | input[type=button] { | ||
| 161 | background-color: lightgray; | ||
| 162 | border: 4px solid darkgray; | ||
| 163 | color: black; | ||
| 164 | text-decoration: none; | ||
| 165 | cursor: pointer; | ||
| 166 | width: 140px; | ||
| 167 | height: 50px; | ||
| 168 | margin-left: 10px; | ||
| 169 | } | ||
| 170 | |||
| 171 | input[type=button]:hover { | ||
| 172 | background-color: #f5f5f5ff; | ||
| 173 | border-color: black; | ||
| 174 | } | ||
| 175 | </style> | ||
| 176 | </head> | ||
| 177 | <body> | ||
| 178 | <div id="header"> | ||
| 179 | <a id="logo" href="https://www.raylib.com"></a> | ||
| 180 | |||
| 181 | <div class="spinner" id='spinner'></div> | ||
| 182 | <div class="emscripten" id="status">Downloading...</div> | ||
| 183 | |||
| 184 | <span id='controls'> | ||
| 185 | <span><input type="button" value="📜 SOURCE CODE" onclick="location.href='https://github.com/raysan5/raylib';"/></span> | ||
| 186 | <span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span> | ||
| 187 | <span><input type="button" id="btn-audio" value="🔇 MUTE" onclick="toggleAudio()"></span> | ||
| 188 | </span> | ||
| 189 | |||
| 190 | <div class="emscripten"> | ||
| 191 | <progress value="0" max="100" id="progress" hidden=1></progress> | ||
| 192 | </div> | ||
| 193 | </div> | ||
| 194 | |||
| 195 | <div class="emscripten_border"> | ||
| 196 | <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas> | ||
| 197 | </div> | ||
| 198 | |||
| 199 | <textarea id="output" rows="8"></textarea> | ||
| 200 | |||
| 201 | <script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"> </script> | ||
| 202 | <script type='text/javascript'> | ||
| 203 | function saveFileFromMEMFSToDisk(memoryFSname, localFSname) // This can be called by C/C++ code | ||
| 204 | { | ||
| 205 | var isSafari = false; // Not supported, navigator.userAgent access is being restricted | ||
| 206 | //var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); | ||
| 207 | var data = FS.readFile(memoryFSname); | ||
| 208 | var blob; | ||
| 209 | |||
| 210 | if (isSafari) blob = new Blob([data.buffer], { type: "application/octet-stream" }); | ||
| 211 | else blob = new Blob([data.buffer], { type: "application/octet-binary" }); | ||
| 212 | |||
| 213 | // NOTE: SaveAsDialog is a browser setting. For example, in Google Chrome, | ||
| 214 | // in Settings/Advanced/Downloads section you have a setting: | ||
| 215 | // 'Ask where to save each file before downloading' - which you can set true/false. | ||
| 216 | // If you enable this setting it would always ask you and bring the SaveAsDialog | ||
| 217 | saveAs(blob, localFSname); | ||
| 218 | } | ||
| 219 | </script> | ||
| 220 | <script type='text/javascript'> | ||
| 221 | var statusElement = document.querySelector('#status'); | ||
| 222 | var progressElement = document.querySelector('#progress'); | ||
| 223 | var spinnerElement = document.querySelector('#spinner'); | ||
| 224 | var Module = { | ||
| 225 | preRun: [], | ||
| 226 | postRun: [], | ||
| 227 | print: (function() { | ||
| 228 | var element = document.querySelector('#output'); | ||
| 229 | |||
| 230 | if (element) element.value = ''; // Clear browser cache | ||
| 231 | |||
| 232 | return function(text) { | ||
| 233 | if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); | ||
| 234 | // These replacements are necessary if you render to raw HTML | ||
| 235 | //text = text.replace(/&/g, "&"); | ||
| 236 | //text = text.replace(/</g, "<"); | ||
| 237 | //text = text.replace(/>/g, ">"); | ||
| 238 | //text = text.replace('\n', '<br>', 'g'); | ||
| 239 | console.log(text); | ||
| 240 | |||
| 241 | if (element) { | ||
| 242 | element.value += text + "\n"; | ||
| 243 | element.scrollTop = element.scrollHeight; // focus on bottom | ||
| 244 | } | ||
| 245 | }; | ||
| 246 | })(), | ||
| 247 | printErr: function(text) { | ||
| 248 | if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); | ||
| 249 | |||
| 250 | console.error(text); | ||
| 251 | }, | ||
| 252 | canvas: (function() { | ||
| 253 | var canvas = document.querySelector('#canvas'); | ||
| 254 | |||
| 255 | // As a default initial behavior, pop up an alert when webgl context is lost. | ||
| 256 | // To make your application robust, you may want to override this behavior before shipping! | ||
| 257 | // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 | ||
| 258 | canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false); | ||
| 259 | |||
| 260 | return canvas; | ||
| 261 | })(), | ||
| 262 | setStatus: function(text) { | ||
| 263 | if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; | ||
| 264 | if (text === Module.setStatus.last.text) return; | ||
| 265 | |||
| 266 | var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); | ||
| 267 | var now = Date.now(); | ||
| 268 | |||
| 269 | if (m && now - Module.setStatus.last.time < 30) return; // If this is a progress update, skip it if too soon | ||
| 270 | |||
| 271 | Module.setStatus.last.time = now; | ||
| 272 | Module.setStatus.last.text = text; | ||
| 273 | |||
| 274 | if (m) { | ||
| 275 | text = m[1]; | ||
| 276 | progressElement.value = parseInt(m[2])*100; | ||
| 277 | progressElement.max = parseInt(m[4])*100; | ||
| 278 | progressElement.hidden = true; | ||
| 279 | spinnerElement.hidden = false; | ||
| 280 | } else { | ||
| 281 | progressElement.value = null; | ||
| 282 | progressElement.max = null; | ||
| 283 | progressElement.hidden = true; | ||
| 284 | if (!text) spinnerElement.style.display = 'none'; | ||
| 285 | } | ||
| 286 | |||
| 287 | statusElement.innerHTML = text; | ||
| 288 | }, | ||
| 289 | totalDependencies: 0, | ||
| 290 | monitorRunDependencies: function(left) { | ||
| 291 | this.totalDependencies = Math.max(this.totalDependencies, left); | ||
| 292 | Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); | ||
| 293 | }, | ||
| 294 | //noInitialRun: true | ||
| 295 | }; | ||
| 296 | |||
| 297 | Module.setStatus('Downloading...'); | ||
| 298 | |||
| 299 | window.onerror = function() { | ||
| 300 | Module.setStatus('Exception thrown, see JavaScript console'); | ||
| 301 | spinnerElement.style.display = 'none'; | ||
| 302 | Module.setStatus = function(text) { if (text) Module.printErr('[post-exception status] ' + text); }; | ||
| 303 | }; | ||
| 304 | </script> | ||
| 305 | |||
| 306 | <!-- REF: https://developers.google.com/web/updates/2018/11/web-audio-autoplay --> | ||
| 307 | <script type='text/javascript'> | ||
| 308 | var audioBtn = document.querySelector('#btn-audio'); | ||
| 309 | |||
| 310 | // An array of all contexts to resume on the page | ||
| 311 | const audioContexList = []; | ||
| 312 | (function() { | ||
| 313 | // A proxy object to intercept AudioContexts and | ||
| 314 | // add them to the array for tracking and resuming later | ||
| 315 | self.AudioContext = new Proxy(self.AudioContext, { | ||
| 316 | construct(target, args) { | ||
| 317 | const result = new target(...args); | ||
| 318 | audioContexList.push(result); | ||
| 319 | if (result.state == "suspended") audioBtn.value = "🔈 RESUME"; | ||
| 320 | return result; | ||
| 321 | } | ||
| 322 | }); | ||
| 323 | })(); | ||
| 324 | |||
| 325 | function toggleAudio() { | ||
| 326 | var resumed = false; | ||
| 327 | audioContexList.forEach(ctx => { | ||
| 328 | if (ctx.state == "suspended") { ctx.resume(); resumed = true; } | ||
| 329 | else if (ctx.state == "running") ctx.suspend(); | ||
| 330 | }); | ||
| 331 | |||
| 332 | if (resumed) audioBtn.value = "🔇 MUTE"; | ||
| 333 | else audioBtn.value = "🔈 RESUME"; | ||
| 334 | } | ||
| 335 | </script> | ||
| 336 | {{{ SCRIPT }}} | ||
| 337 | </body> | ||
| 338 | </html> | ||
