CoolFace
Apppublic

Falln87/godot_editor

sourceHugging Faceupdated 5y agoView on Hugging Face
0likes
index_2.html685 linesDownload Raw Back to root
1<!DOCTYPE html>2<html xmlns="https://www.w3.org/1999/xhtml" lang="en">3<head>4	<meta charset="utf-8" />5	<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />6	<meta name="author" content="Godot Engine" />7	<meta name="description" content="Use the Godot Engine editor directly in your web browser, without having to install anything." />8	<meta name="mobile-web-app-capable" content="yes" />9	<meta name="apple-mobile-web-app-capable" content="yes" />10	<meta name="application-name" content="Godot" />11	<meta name="apple-mobile-web-app-title" content="Godot" />12	<meta name="theme-color" content="#202531" />13	<meta name="msapplication-navbutton-color" content="#202531" />14	<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />15	<meta name="msapplication-starturl" content="/latest" />16	<meta property="og:site_name" content="Godot Engine Web Editor" />17	<meta property="og:url" name="twitter:url" content="https://editor.godotengine.org/releases/latest/" />18	<meta property="og:title" name="twitter:title" content="Free and open source 2D and 3D game engine" />19	<meta property="og:description" name="twitter:description" content="Use the Godot Engine editor directly in your web browser, without having to install anything." />20	<meta property="og:image" name="twitter:image" content="https://godotengine.org/themes/godotengine/assets/og_image.png" />21	<meta property="og:type" content="website" />22	<meta name="twitter:card" content="summary" />23	<link id="-gd-engine-icon" rel="icon" type="image/png" href="favicon.png" />24	<link rel="apple-touch-icon" type="image/png" href="favicon.png" />25	<link rel="manifest" href="manifest.json" />26	<title>Godot Engine Web Editor (3.4.4.rc.custom_build)</title>27	<style>28		*:focus {29			/* More visible outline for better keyboard navigation. */30			outline: 0.125rem solid hsl(220, 100%, 62.5%);31			/* Make the outline always appear above other elements. */32			/* Otherwise, one of its sides can be hidden by tabs in the Download and More layouts. */33			position: relative;34		}35 36		body {37			touch-action: none;38			font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";39			margin: 0;40			border: 0 none;41			padding: 0;42			text-align: center;43			background-color: #333b4f;44			overflow: hidden;45		}46 47		a {48			color: hsl(205, 100%, 75%);49			text-decoration-color: hsla(205, 100%, 75%, 0.3);50			text-decoration-thickness: 0.125rem;51		}52 53		a:hover {54			filter: brightness(117.5%);55		}56 57		a:active {58			filter: brightness(82.5%);59		}60 61		.welcome-modal {62			display: none;63 			position: fixed;64			z-index: 1;65			left: 0;66			top: 0;67			width: 100%;68			height: 100%;69			overflow: auto;70			background-color: hsla(0, 0%, 0%, 0.5);71		}72 73		.welcome-modal-content {74			background-color: #333b4f;75			box-shadow: 0 0.25rem 0.25rem hsla(0, 0%, 0%, 0.5);76			line-height: 1.5;77			max-width: 38rem;78			margin: 4rem auto 0 auto;79			color: white;80			border-radius: 0.5rem;81			padding: 1rem 1rem 2rem 1rem;82		}83 84		#tabs-buttons {85			/* Match the default background color of the editor window for a seamless appearance. */86			background-color: #202531;87		}88 89		#tab-game {90			/* Use a pure black background to better distinguish the running project */91			/* from the editor window, and to use a more neutral background color (no tint). */92			background-color: black;93			/* Make the background span the entire page height. */94			min-height: 100vh;95		}96 97		#canvas, #gameCanvas {98			display: block;99			margin: 0;100			color: white;101		}102 103		/* Don't show distracting focus outlines for the main tabs' contents. */104		#tab-editor canvas:focus,105		#tab-game canvas:focus,106		#canvas:focus,107		#gameCanvas:focus {108			outline: none;109		}110 111		.godot {112			color: #e0e0e0;113			background-color: #3b3943;114			background-image: linear-gradient(to bottom, #403e48, #35333c);115			border: 1px solid #45434e;116			box-shadow: 0 0 1px 1px #2f2d35;117		}118 119		.btn {120			appearance: none;121			color: #e0e0e0;122			background-color: #262c3b;123			border: 1px solid #202531;124			padding: 0.5rem 1rem;125			margin: 0 0.5rem;126		}127 128		.btn:not(:disabled):hover {129			color: #e0e1e5;130			border-color: #666c7b;131		}132 133		.btn:active {134			border-color: #699ce8;135			color: #699ce8;136		}137 138		.btn:disabled {139			color: #aaa;140			border-color: #242937;141		}142 143		.btn.tab-btn {144			padding: 0.3rem 1rem;145		}146 147		.btn.close-btn {148			padding: 0.3rem 1rem;149			margin-left: -0.75rem;150			font-weight: 700;151		}152 153 154		/* Status display155		 * ============== */156 157		#status {158			position: absolute;159			left: 0;160			top: 0;161			right: 0;162			bottom: 0;163			display: flex;164			justify-content: center;165			align-items: center;166			/* don't consume click events - make children visible explicitly */167			visibility: hidden;168		}169 170		#status-progress {171			width: 366px;172			height: 7px;173			background-color: #38363A;174			border: 1px solid #444246;175			padding: 1px;176			box-shadow: 0 0 2px 1px #1B1C22;177			border-radius: 2px;178			visibility: visible;179		}180 181		@media only screen and (orientation:portrait) {182			#status-progress {183				width: 61.8%;184			}185		}186 187		#status-progress-inner {188			height: 100%;189			width: 0;190			box-sizing: border-box;191			transition: width 0.5s linear;192			background-color: #202020;193			border: 1px solid #222223;194			box-shadow: 0 0 1px 1px #27282E;195			border-radius: 3px;196		}197 198		#status-indeterminate {199			visibility: visible;200			position: relative;201		}202 203		#status-indeterminate > div {204			width: 4.5px;205			height: 0;206			border-style: solid;207			border-width: 9px 3px 0 3px;208			border-color: #2b2b2b transparent transparent transparent;209			transform-origin: center 21px;210			position: absolute;211		}212 213		#status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); }214		#status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); }215		#status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); }216		#status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); }217		#status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); }218		#status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); }219		#status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); }220		#status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); }221 222		#status-notice {223			margin: 0 100px;224			line-height: 1.3;225			visibility: visible;226			padding: 4px 6px;227			visibility: visible;228		}229	</style>230</head>231<body>232	<div233		id="welcome-modal"234		class="welcome-modal"235		role="dialog"236		aria-labelledby="welcome-modal-title"237		aria-describedby="welcome-modal-description"238		onclick="if (event.target === this) closeWelcomeModal(false)"239	>240		<div class="welcome-modal-content">241			<h2 id="welcome-modal-title">Important - Please read before continuing</h2>242			<div id="welcome-modal-description">243				<p>244					The Godot Web Editor has some limitations compared to the native version.245					Its main focus is education and experimentation;246					<strong>it is not recommended for production</strong>.247				</p>248				<p>249					Refer to the250					<a251						href="https://docs.godotengine.org/en/latest/tutorials/editor/using_the_web_editor.html"252						target="_blank"253						rel="noopener"254					>Web editor documentation</a> for usage instructions and limitations.255				</p>256			</div>257			<button id="welcome-modal-dismiss" class="btn" type="button" onclick="closeWelcomeModal(true)" style="margin-top: 1rem">258				OK, don't show again259			</button>260		</div>261	</div>262	<div id="tabs-buttons">263		<button id="btn-tab-loader" class="btn tab-btn" onclick="showTab('loader')">Loader</button>264		<button id="btn-tab-editor" class="btn tab-btn" disabled="disabled" onclick="showTab('editor')">Editor</button>265		<button id="btn-close-editor" class="btn close-btn" disabled="disabled" onclick="closeEditor()">×</button>266		<button id="btn-tab-game" class="btn tab-btn" disabled="disabled" onclick="showTab('game')">Game</button>267		<button id="btn-close-game" class="btn close-btn"  disabled="disabled" onclick="closeGame()">×</button>268	</div>269	<div id="tabs">270		<div id="tab-loader">271			<div style="color: #e0e0e0;" id="persistence">272				<br />273				<img src="logo.svg" alt="Godot Engine logo" width="1024" height="414" style="width: auto; height: auto; max-width: min(85%, 50vh); max-height: 250px" />274				<br />275				3.4.4.rc.custom_build276				<br />277				<a href="releases/">Need an old version?</a>278				<br />279				<br />280				<br />281				<label for="videoMode" style="margin-right: 1rem">Video driver:</label>282				<select id="videoMode">283					<option value="" selected="selected">Auto</option>284					<option value="GLES2">WebGL</option>285					<option value="GLES3">WebGL 2</option>286				</select>287				<br />288				<br />289				<label for="zip-file" style="margin-right: 1rem">Preload project ZIP:</label> <input id="zip-file" type="file" name="files" style="margin-bottom: 1rem"/>290				<br />291<a href="demo.zip">(Try this for example)</a>292				<br />293				<br />294				<button id="startButton" class="btn" style="margin-bottom: 4rem; font-weight: 700">Start Godot editor</button>295				<br />296				<button class="btn" onclick="clearPersistence()" style="margin-bottom: 1.5rem">Clear persistent data</button>297				<br />298				<a href="https://docs.godotengine.org/en/3.4/tutorials/editor/using_the_web_editor.html">Web editor documentation</a>299			</div>300		</div>301		<div id="tab-editor" style="display: none;">302			<canvas id="editor-canvas" tabindex="1">303				HTML5 canvas appears to be unsupported in the current browser.<br />304				Please try updating or use a different browser.305			</canvas>306		</div>307		<div id="tab-game" style="display: none;">308			<canvas id="game-canvas" tabindex="2">309				HTML5 canvas appears to be unsupported in the current browser.<br />310				Please try updating or use a different browser.311			</canvas>312		</div>313		<div id="tab-status" style="display: none;">314			<div id="status-progress" style="display: none;" oncontextmenu="event.preventDefault();"><div id="status-progress-inner"></div></div>315			<div id="status-indeterminate" style="display: none;" oncontextmenu="event.preventDefault();">316				<div></div>317				<div></div>318				<div></div>319				<div></div>320				<div></div>321				<div></div>322				<div></div>323				<div></div>324			</div>325			<div id="status-notice" class="godot" style="display: none;"></div>326		</div>327	</div>328	<script>329		window.addEventListener("load", () => {330			if ("serviceWorker" in navigator) {331				navigator.serviceWorker.register("service.worker.js");332			}333 334			if (localStorage.getItem("welcomeModalDismissed") !== 'true') {335				document.getElementById("welcome-modal").style.display = "block";336				document.getElementById("welcome-modal-dismiss").focus();337			}338		});339 340		function closeWelcomeModal(dontShowAgain) {341			document.getElementById("welcome-modal").style.display = "none";342			if (dontShowAgain) {343				localStorage.setItem("welcomeModalDismissed", 'true');344			}345		}346	</script>347	<script src="godot.tools.js"></script>348	<script>//<![CDATA[349 350		var editor = null;351		var game = null;352		var setStatusMode;353		var setStatusNotice;354		var video_driver = "";355 356		function clearPersistence() {357			function deleteDB(path) {358				return new Promise(function(resolve, reject) {359					var req = indexedDB.deleteDatabase(path);360					req.onsuccess = function() {361						resolve();362					};363					req.onerror = function(err) {364						reject(err);365					};366					req.onblocked = function(err) {367						reject(err);368					}369 370				});371			}372			if (!window.confirm("Are you sure you want to delete all the locally stored files?\nClicking \"OK\" will permanently remove your projects and editor settings!")) {373				return;374			}375			Promise.all([376				deleteDB("/home/web_user"),377			]).then(function(results) {378				alert("Done.");379			}).catch(function (err) {380				alert("Error deleting local files. Please retry after reloading the page.");381			});382		}383 384		function selectVideoMode() {385			var select = document.getElementById('videoMode');386			video_driver = select.selectedOptions[0].value;387		}388 389		var tabs = [390			document.getElementById('tab-loader'),391			document.getElementById('tab-editor'),392			document.getElementById('tab-game')393		]394		function showTab(name) {395			tabs.forEach(function (elem) {396				if (elem.id == 'tab-' + name) {397					elem.style.display = 'block';398					if (name == 'editor' || name == 'game') {399						const canvas = document.getElementById(name + '-canvas');400						canvas.focus();401					}402				} else {403					elem.style.display = 'none';404				}405			});406		}407 408		function setButtonEnabled(id, enabled) {409			if (enabled) {410				document.getElementById(id).disabled = "";411			} else {412				document.getElementById(id).disabled = "disabled";413			}414		}415 416		function setLoaderEnabled(enabled) {417			setButtonEnabled('btn-tab-loader', enabled);418			setButtonEnabled('btn-tab-editor', !enabled);419			setButtonEnabled('btn-close-editor', !enabled);420		}421 422		function setGameTabEnabled(enabled) {423			setButtonEnabled('btn-tab-game', enabled);424			setButtonEnabled('btn-close-game', enabled);425		}426 427		function closeGame() {428			if (game) {429				game.requestQuit();430			}431		}432 433		function closeEditor() {434			closeGame();435			if (editor) {436				editor.requestQuit();437			}438		}439 440		function startEditor(zip) {441			const INDETERMINATE_STATUS_STEP_MS = 100;442			const persistentPaths = ['/home/web_user'];443 444			var editorCanvas = document.getElementById('editor-canvas');445			var gameCanvas = document.getElementById('game-canvas');446			var statusProgress = document.getElementById('status-progress');447			var statusProgressInner = document.getElementById('status-progress-inner');448			var statusIndeterminate = document.getElementById('status-indeterminate');449			var statusNotice = document.getElementById('status-notice');450			var headerDiv = document.getElementById('tabs-buttons');451 452			var initializing = true;453			var statusMode = 'hidden';454 455			showTab('status');456 457			var animationCallbacks = [];458			function animate(time) {459				animationCallbacks.forEach(callback => callback(time));460				requestAnimationFrame(animate);461			}462			requestAnimationFrame(animate);463 464			var lastScale = 0;465			var lastWidth = 0;466			var lastHeight = 0;467			function adjustCanvasDimensions() {468				var scale = window.devicePixelRatio || 1;469				var headerHeight = headerDiv.offsetHeight + 1;470				var width = window.innerWidth;471				var height = window.innerHeight - headerHeight;472				if (lastScale !== scale || lastWidth !== width || lastHeight !== height) {473					editorCanvas.width = width * scale;474					editorCanvas.height = height * scale;475					editorCanvas.style.width = width + "px";476					editorCanvas.style.height = height + "px";477					lastScale = scale;478					lastWidth = width;479					lastHeight = height;480				}481			}482			animationCallbacks.push(adjustCanvasDimensions);483			adjustCanvasDimensions();484 485			function replaceCanvas(from) {486				const out = document.createElement("canvas");487				out.id = from.id;488				out.tabIndex = from.tabIndex;489				from.parentNode.replaceChild(out, from);490				lastScale = 0;491				return out;492			}493 494			setStatusMode = function setStatusMode(mode) {495				if (statusMode === mode || !initializing)496					return;497				[statusProgress, statusIndeterminate, statusNotice].forEach(elem => {498					elem.style.display = 'none';499				});500				animationCallbacks = animationCallbacks.filter(function(value) {501					return (value != animateStatusIndeterminate);502				});503				switch (mode) {504					case 'progress':505						statusProgress.style.display = 'block';506						break;507					case 'indeterminate':508						statusIndeterminate.style.display = 'block';509						animationCallbacks.push(animateStatusIndeterminate);510						break;511					case 'notice':512						statusNotice.style.display = 'block';513						break;514					case 'hidden':515						break;516					default:517						throw new Error('Invalid status mode');518				}519				statusMode = mode;520			};521 522			function animateStatusIndeterminate(ms) {523				var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);524				if (statusIndeterminate.children[i].style.borderTopColor == '') {525					Array.prototype.slice.call(statusIndeterminate.children).forEach(child => {526						child.style.borderTopColor = '';527					});528					statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf';529				}530			}531 532			setStatusNotice = function setStatusNotice(text) {533				while (statusNotice.lastChild) {534					statusNotice.removeChild(statusNotice.lastChild);535				}536				var lines = text.split('\n');537				lines.forEach((line) => {538					statusNotice.appendChild(document.createTextNode(line));539					statusNotice.appendChild(document.createElement('br'));540				});541			};542 543			const gameConfig = {544				'persistentPaths': persistentPaths,545				'unloadAfterInit': false,546				'canvas': gameCanvas,547				'canvasResizePolicy': 1,548				'onExit': function () {549					gameCanvas = replaceCanvas(gameCanvas);550					setGameTabEnabled(false);551					showTab('editor');552					game = null;553				},554			};555 556			var OnEditorExit = function () {557				showTab('loader');558				setLoaderEnabled(true);559			};560			function Execute(args) {561				const is_editor = args.filter(function(v) { return v == '--editor' || v == '-e' }).length != 0;562				const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0;563				const is_game = !is_editor && !is_project_manager;564				if (video_driver) {565					args.push('--video-driver', video_driver);566				}567				if (is_game) {568					if (game) {569						console.error("A game is already running. Close it first");570						return;571					}572					setGameTabEnabled(true);573					game = new Engine(gameConfig);574					showTab('game');575					game.init().then(function() {576						requestAnimationFrame(function() {577							game.start({'args': args, 'canvas': gameCanvas}).then(function() {578								gameCanvas.focus();579							});580						});581					});582				} else { // New editor instances will be run in the same canvas. We want to wait for it to exit.583					OnEditorExit = function(code) {584						setLoaderEnabled(true);585						setTimeout(function() {586							editor.init().then(function() {587								setLoaderEnabled(false);588								OnEditorExit = function() {589									showTab('loader');590									setLoaderEnabled(true);591								};592								editor.start({'args': args, 'persistentDrops': is_project_manager, 'canvas': editorCanvas});593							});594						}, 0);595						OnEditorExit = null;596					};597				}598			}599 600			const editorConfig = {601				'unloadAfterInit': false,602				'onProgress': function progressFunction (current, total) {603					if (total > 0) {604						statusProgressInner.style.width = current/total * 100 + '%';605						setStatusMode('progress');606						if (current === total) {607							// wait for progress bar animation608							setTimeout(() => {609								setStatusMode('indeterminate');610							}, 100);611						}612					} else {613						setStatusMode('indeterminate');614					}615				},616				'canvas': editorCanvas,617				'canvasResizePolicy': 0,618				'onExit': function() {619					editorCanvas = replaceCanvas(editorCanvas);620					if (OnEditorExit) {621						OnEditorExit();622					}623				},624				'onExecute': Execute,625				'persistentPaths': persistentPaths,626			};627			editor = new Engine(editorConfig);628 629			function displayFailureNotice(err) {630				var msg = err.message || err;631				console.error(msg);632				setStatusNotice(msg);633				setStatusMode('notice');634				initializing = false;635			};636 637			if (!Engine.isWebGLAvailable()) {638				displayFailureNotice('WebGL not available');639			} else {640				setStatusMode('indeterminate');641				editor.init('godot.tools').then(function() {642					if (zip) {643						editor.copyToFS("/tmp/preload.zip", zip);644					}645					try {646						// Avoid user creating project in the persistent root folder.647						editor.copyToFS("/home/web_user/keep", new Uint8Array());648					} catch(e) {649						// File exists650					}651					selectVideoMode();652					showTab('editor');653					setLoaderEnabled(false);654					const args = ['--project-manager'];655					if (video_driver) {656						args.push('--video-driver', video_driver);657					}658					editor.start({'args': args, 'persistentDrops': true}).then(function() {659						setStatusMode('hidden');660						initializing = false;661					});662				}).catch(displayFailureNotice);663			}664		};665		document.getElementById("startButton").onclick = function() {666			preloadZip(document.getElementById('zip-file')).then(function(zip) {667				startEditor(zip);668			});669		}670 671		function preloadZip(target) {672			return new Promise(function(resolve, reject) {673				if (target.files.length > 0) {674					target.files[0].arrayBuffer().then(function(data) {675						resolve(data);676					});677				} else {678					resolve();679				}680			});681		}682	//]]></script>683</body>684</html>685