index — krinitsin.com @ a214ca4f86169ca8cf4f3eba12862c6688cfd644

personal website

games/fruity-sorter/index.html (view raw)

  1<!DOCTYPE html>
  2<html xmlns='http://www.w3.org/1999/xhtml' lang='' xml:lang=''>
  3<head>
  4	<meta charset='utf-8' />
  5	<meta name='viewport' content='width=device-width, user-scalable=no' />
  6	<title>Fruity Sorter</title>
  7	<style type='text/css'>
  8
  9		body {
 10			touch-action: none;
 11			margin: 0;
 12			border: 0 none;
 13			padding: 0;
 14			text-align: center;
 15			background-color: black;
 16		}
 17
 18		#canvas {
 19			display: block;
 20			margin: 0;
 21			color: white;
 22		}
 23
 24		#canvas:focus {
 25			outline: none;
 26		}
 27
 28		.godot {
 29			font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif;
 30			color: #e0e0e0;
 31			background-color: #3b3943;
 32			background-image: linear-gradient(to bottom, #403e48, #35333c);
 33			border: 1px solid #45434e;
 34			box-shadow: 0 0 1px 1px #2f2d35;
 35		}
 36
 37
 38		/* Status display
 39		 * ============== */
 40
 41		#status {
 42			position: absolute;
 43			left: 0;
 44			top: 0;
 45			right: 0;
 46			bottom: 0;
 47			display: flex;
 48			justify-content: center;
 49			align-items: center;
 50			/* don't consume click events - make children visible explicitly */
 51			visibility: hidden;
 52		}
 53
 54		#status-progress {
 55			width: 366px;
 56			height: 7px;
 57			background-color: #38363A;
 58			border: 1px solid #444246;
 59			padding: 1px;
 60			box-shadow: 0 0 2px 1px #1B1C22;
 61			border-radius: 2px;
 62			visibility: visible;
 63		}
 64
 65		@media only screen and (orientation:portrait) {
 66			#status-progress {
 67				width: 61.8%;
 68			}
 69		}
 70
 71		#status-progress-inner {
 72			height: 100%;
 73			width: 0;
 74			box-sizing: border-box;
 75			transition: width 0.5s linear;
 76			background-color: #202020;
 77			border: 1px solid #222223;
 78			box-shadow: 0 0 1px 1px #27282E;
 79			border-radius: 3px;
 80		}
 81
 82		#status-indeterminate {
 83			height: 42px;
 84			visibility: visible;
 85			position: relative;
 86		}
 87
 88		#status-indeterminate > div {
 89			width: 4.5px;
 90			height: 0;
 91			border-style: solid;
 92			border-width: 9px 3px 0 3px;
 93			border-color: #2b2b2b transparent transparent transparent;
 94			transform-origin: center 21px;
 95			position: absolute;
 96		}
 97
 98		#status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); }
 99		#status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); }
100		#status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); }
101		#status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); }
102		#status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); }
103		#status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); }
104		#status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); }
105		#status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); }
106
107		#status-notice {
108			margin: 0 100px;
109			line-height: 1.3;
110			visibility: visible;
111			padding: 4px 6px;
112			visibility: visible;
113		}
114	</style>
115<link id='-gd-engine-icon' rel='icon' type='image/png' href='Bombs Sorter.icon.png' />
116<link rel='apple-touch-icon' href='Bombs Sorter.apple-touch-icon.png'/>
117
118</head>
119<body>
120	<canvas id='canvas'>
121		HTML5 canvas appears to be unsupported in the current browser.<br />
122		Please try updating or use a different browser.
123	</canvas>
124	<div id='status'>
125		<div id='status-progress' style='display: none;' oncontextmenu='event.preventDefault();'><div id ='status-progress-inner'></div></div>
126		<div id='status-indeterminate' style='display: none;' oncontextmenu='event.preventDefault();'>
127			<div></div>
128			<div></div>
129			<div></div>
130			<div></div>
131			<div></div>
132			<div></div>
133			<div></div>
134			<div></div>
135		</div>
136		<div id='status-notice' class='godot' style='display: none;'></div>
137	</div>
138
139	<script type='text/javascript' src='Bombs Sorter.js'></script>
140	<script type='text/javascript'>//<![CDATA[
141
142		const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"executable":"Bombs Sorter","experimentalVK":false,"fileSizes":{"Bombs Sorter.pck":3710016,"Bombs Sorter.wasm":17862218},"focusCanvas":true,"gdnativeLibs":[]};
143		var engine = new Engine(GODOT_CONFIG);
144
145		(function() {
146			const INDETERMINATE_STATUS_STEP_MS = 100;
147			var statusProgress = document.getElementById('status-progress');
148			var statusProgressInner = document.getElementById('status-progress-inner');
149			var statusIndeterminate = document.getElementById('status-indeterminate');
150			var statusNotice = document.getElementById('status-notice');
151
152			var initializing = true;
153			var statusMode = 'hidden';
154
155			var animationCallbacks = [];
156			function animate(time) {
157				animationCallbacks.forEach(callback => callback(time));
158				requestAnimationFrame(animate);
159			}
160			requestAnimationFrame(animate);
161
162			function setStatusMode(mode) {
163
164				if (statusMode === mode || !initializing)
165					return;
166				[statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
167					elem.style.display = 'none';
168				});
169				animationCallbacks = animationCallbacks.filter(function(value) {
170					return (value != animateStatusIndeterminate);
171				});
172				switch (mode) {
173					case 'progress':
174						statusProgress.style.display = 'block';
175						break;
176					case 'indeterminate':
177						statusIndeterminate.style.display = 'block';
178						animationCallbacks.push(animateStatusIndeterminate);
179						break;
180					case 'notice':
181						statusNotice.style.display = 'block';
182						break;
183					case 'hidden':
184						break;
185					default:
186						throw new Error('Invalid status mode');
187				}
188				statusMode = mode;
189			}
190
191			function animateStatusIndeterminate(ms) {
192				var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);
193				if (statusIndeterminate.children[i].style.borderTopColor == '') {
194					Array.prototype.slice.call(statusIndeterminate.children).forEach(child => {
195						child.style.borderTopColor = '';
196					});
197					statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf';
198				}
199			}
200
201			function setStatusNotice(text) {
202				while (statusNotice.lastChild) {
203					statusNotice.removeChild(statusNotice.lastChild);
204				}
205				var lines = text.split('\n');
206				lines.forEach((line) => {
207					statusNotice.appendChild(document.createTextNode(line));
208					statusNotice.appendChild(document.createElement('br'));
209				});
210			};
211
212			function displayFailureNotice(err) {
213				var msg = err.message || err;
214				console.error(msg);
215				setStatusNotice(msg);
216				setStatusMode('notice');
217				initializing = false;
218			};
219
220			if (!Engine.isWebGLAvailable()) {
221				displayFailureNotice('WebGL not available');
222			} else {
223				setStatusMode('indeterminate');
224				engine.startGame({
225					'onProgress': function (current, total) {
226						if (total > 0) {
227							statusProgressInner.style.width = current/total * 100 + '%';
228							setStatusMode('progress');
229							if (current === total) {
230								// wait for progress bar animation
231								setTimeout(() => {
232									setStatusMode('indeterminate');
233								}, 500);
234							}
235						} else {
236							setStatusMode('indeterminate');
237						}
238					},
239				}).then(() => {
240					setStatusMode('hidden');
241					initializing = false;
242				}, displayFailureNotice);
243			}
244		})();
245	//]]></script>
246</body>
247</html>
248