2020-09-14 13:18:49 +02:00
<!DOCTYPE html>
2021-08-21 20:56:25 -05:00
< html xmlns = "https://www.w3.org/1999/xhtml" lang = "en" >
2020-09-14 13:18:49 +02:00
< head >
2021-03-24 18:36:37 +01:00
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" / >
< meta name = "author" content = "Godot Engine" / >
< meta name = "description" content = "Use the Godot Engine editor directly in your web browser, without having to install anything." / >
2021-03-08 15:39:14 +01:00
< meta name = "mobile-web-app-capable" content = "yes" / >
< meta name = "apple-mobile-web-app-capable" content = "yes" / >
< meta name = "application-name" content = "Godot" / >
< meta name = "apple-mobile-web-app-title" content = "Godot" / >
< meta name = "theme-color" content = "#478cbf" / >
< meta name = "msapplication-navbutton-color" content = "#478cbf" / >
< meta name = "apple-mobile-web-app-status-bar-style" content = "black-translucent" / >
< meta name = "msapplication-starturl" content = "/latest" / >
2021-03-24 18:36:37 +01:00
< meta property = "og:site_name" content = "Godot Engine Web Editor" / >
2021-09-20 14:47:55 +02:00
< meta property = "og:url" name = "twitter:url" content = "https://editor.godotengine.org/releases/latest/" / >
2021-03-24 18:36:37 +01:00
< meta property = "og:title" name = "twitter:title" content = "Free and open source 2D and 3D game engine" / >
< meta property = "og:description" name = "twitter:description" content = "Use the Godot Engine editor directly in your web browser, without having to install anything." / >
< meta property = "og:image" name = "twitter:image" content = "https://godotengine.org/themes/godotengine/assets/og_image.png" / >
< meta property = "og:type" content = "website" / >
< meta name = "twitter:card" content = "summary" / >
< link id = "-gd-engine-icon" rel = "icon" type = "image/png" href = "favicon.png" / >
2021-03-08 15:39:14 +01:00
< link rel = "apple-touch-icon" type = "image/png" href = "favicon.png" / >
< link rel = "manifest" href = "manifest.json" / >
2021-02-26 15:04:40 +01:00
< title > Godot Engine Web Editor (@GODOT_VERSION@)< / title >
2021-02-24 22:46:43 +01:00
< style >
2021-01-07 18:46:26 +01:00
* : focus {
/* More visible outline for better keyboard navigation. */
outline : 0.125 rem solid hsl ( 220 , 100 % , 62.5 % ) ;
/* Make the outline always appear above other elements. */
/* Otherwise, one of its sides can be hidden by tabs in the Download and More layouts. */
position : relative ;
}
2020-09-14 13:18:49 +02:00
body {
touch-action : none ;
2020-10-27 20:40:33 +01:00
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" ;
2020-09-14 13:18:49 +02:00
margin : 0 ;
border : 0 none ;
padding : 0 ;
text-align : center ;
2020-10-27 20:40:33 +01:00
background-color : #333b4f ;
2020-09-14 13:18:49 +02:00
overflow : hidden ;
}
2021-01-07 18:46:26 +01:00
a {
color : hsl ( 205 , 100 % , 75 % ) ;
text-decoration-color : hsla ( 205 , 100 % , 75 % , 0.3 ) ;
text-decoration-thickness : 0.125 rem ;
}
a : hover {
filter : brightness ( 117.5 % ) ;
}
a : active {
filter : brightness ( 82.5 % ) ;
}
2021-03-16 18:35:20 +01:00
. welcome-modal {
display : none ;
position : fixed ;
z-index : 1 ;
left : 0 ;
top : 0 ;
width : 100 % ;
height : 100 % ;
overflow : auto ;
background-color : hsla ( 0 , 0 % , 0 % , 0.5 ) ;
}
. welcome-modal-content {
background-color : #333b4f ;
box-shadow : 0 0.25 rem 0.25 rem hsla ( 0 , 0 % , 0 % , 0.5 ) ;
line-height : 1.5 ;
max-width : 38 rem ;
margin : 4 rem auto 0 auto ;
color : white ;
border-radius : 0.5 rem ;
padding : 1 rem 1 rem 2 rem 1 rem ;
}
2021-02-24 22:46:43 +01:00
# tabs-buttons {
/* Match the default background color of the editor window for a seamless appearance. */
background-color : #202531 ;
}
# tab-game {
/* Use a pure black background to better distinguish the running project */
/* from the editor window, and to use a more neutral background color (no tint). */
background-color : black ;
/* Make the background span the entire page height. */
min-height : 100 vh ;
}
2020-09-14 13:18:49 +02:00
# canvas , # gameCanvas {
display : block ;
margin : 0 ;
color : white ;
}
2021-02-24 22:46:43 +01:00
/* Don't show distracting focus outlines for the main tabs' contents. */
# tab-editor canvas : focus ,
# tab-game canvas : focus ,
# canvas : focus ,
# gameCanvas : focus {
2020-09-14 13:18:49 +02:00
outline : none ;
}
. godot {
color : #e0e0e0 ;
background-color : #3b3943 ;
background-image : linear-gradient ( to bottom , #403e48 , #35333c ) ;
border : 1 px solid #45434e ;
box-shadow : 0 0 1 px 1 px #2f2d35 ;
}
2020-10-27 20:40:33 +01:00
. btn {
appearance : none ;
color : #e0e0e0 ;
background-color : #262c3b ;
border : 1 px solid #202531 ;
padding : 0.5 rem 1 rem ;
margin : 0 0.5 rem ;
}
. btn : not ( : disabled ) : hover {
color : #e0e1e5 ;
border-color : #666c7b ;
}
. btn : active {
border-color : #699ce8 ;
color : #699ce8 ;
}
. btn : disabled {
color : #aaa ;
border-color : #242937 ;
}
. btn . tab-btn {
padding : 0.3 rem 1 rem ;
}
. btn . close-btn {
padding : 0.3 rem 1 rem ;
margin-left : -0.75 rem ;
font-weight : 700 ;
}
2020-09-14 13:18:49 +02:00
/* 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 : 366 px ;
height : 7 px ;
background-color : #38363A ;
border : 1 px solid #444246 ;
padding : 1 px ;
box-shadow : 0 0 2 px 1 px #1B1C22 ;
border-radius : 2 px ;
visibility : visible ;
}
@ media only screen and ( orientation : portrait ) {
# status-progress {
width : 61.8 % ;
}
}
# status-progress-inner {
height : 100 % ;
width : 0 ;
box-sizing : border-box ;
transition : width 0.5 s linear ;
background-color : #202020 ;
border : 1 px solid #222223 ;
box-shadow : 0 0 1 px 1 px #27282E ;
border-radius : 3 px ;
}
# status-indeterminate {
visibility : visible ;
position : relative ;
}
# status-indeterminate > div {
width : 4.5 px ;
height : 0 ;
border-style : solid ;
border-width : 9 px 3 px 0 3 px ;
border-color : #2b2b2b transparent transparent transparent ;
transform-origin : center 21 px ;
position : absolute ;
}
# status-indeterminate > div : nth-child ( 1 ) { transform : rotate ( 22.5 deg ) ; }
# status-indeterminate > div : nth-child ( 2 ) { transform : rotate ( 67.5 deg ) ; }
# status-indeterminate > div : nth-child ( 3 ) { transform : rotate ( 112.5 deg ) ; }
# status-indeterminate > div : nth-child ( 4 ) { transform : rotate ( 157.5 deg ) ; }
# status-indeterminate > div : nth-child ( 5 ) { transform : rotate ( 202.5 deg ) ; }
# status-indeterminate > div : nth-child ( 6 ) { transform : rotate ( 247.5 deg ) ; }
# status-indeterminate > div : nth-child ( 7 ) { transform : rotate ( 292.5 deg ) ; }
# status-indeterminate > div : nth-child ( 8 ) { transform : rotate ( 337.5 deg ) ; }
# status-notice {
margin : 0 100 px ;
line-height : 1.3 ;
visibility : visible ;
padding : 4 px 6 px ;
visibility : visible ;
}
< / style >
< / head >
< body >
2021-03-16 18:35:20 +01:00
< div
id = "welcome-modal"
class = "welcome-modal"
role = "dialog"
aria-labelledby = "welcome-modal-title"
aria-describedby = "welcome-modal-description"
onclick = "if (event.target === this) closeWelcomeModal(false)"
>
< div class = "welcome-modal-content" >
< h2 id = "welcome-modal-title" > Important - Please read before continuing< / h2 >
< div id = "welcome-modal-description" >
< p >
The Godot Web Editor has some limitations compared to the native version.
Its main focus is education and experimentation;
< strong > it is not recommended for production< / strong > .
< / p >
< p >
Refer to the
< a
href = "https://docs.godotengine.org/en/latest/tutorials/editor/using_the_web_editor.html"
target = "_blank"
rel = "noopener"
> Web editor documentation< / a > for usage instructions and limitations.
< / p >
< / div >
< button id = "welcome-modal-dismiss" class = "btn" type = "button" onclick = "closeWelcomeModal(true)" style = "margin-top: 1rem" >
OK, don't show again
< / button >
< / div >
< / div >
2020-09-14 13:18:49 +02:00
< div id = "tabs-buttons" >
2020-10-27 20:40:33 +01:00
< button id = "btn-tab-loader" class = "btn tab-btn" onclick = "showTab('loader')" > Loader< / button >
< button id = "btn-tab-editor" class = "btn tab-btn" disabled = "disabled" onclick = "showTab('editor')" > Editor< / button >
< button id = "btn-close-editor" class = "btn close-btn" disabled = "disabled" onclick = "closeEditor()" > × < / button >
< button id = "btn-tab-game" class = "btn tab-btn" disabled = "disabled" onclick = "showTab('game')" > Game< / button >
< button id = "btn-close-game" class = "btn close-btn" disabled = "disabled" onclick = "closeGame()" > × < / button >
2020-09-14 13:18:49 +02:00
< / div >
2021-03-24 18:36:37 +01:00
< div id = "tabs" >
< div id = "tab-loader" >
2020-10-27 20:40:33 +01:00
< div style = "color: #e0e0e0;" id = "persistence" >
2020-09-14 13:18:49 +02:00
< br / >
2021-03-24 18:36:37 +01:00
< img src = "logo.svg" alt = "Godot Engine logo" width = "1024" height = "414" style = "width: auto; height: auto; max-width: 85%; max-height: 250px" / >
2020-12-05 21:02:31 +01:00
< br / >
2021-02-26 15:04:40 +01:00
@GODOT_VERSION@
2021-01-25 04:48:11 +01:00
< br / >
< a href = "releases/" > Need an old version?< / a >
< br / >
< br / >
< br / >
2021-09-20 14:47:55 +02:00
< label for = "videoMode" style = "margin-right: 1rem" > Video driver:< / label >
< select id = "videoMode" >
< option value = "" selected = "selected" > Auto< / option >
2021-10-25 19:16:40 +02:00
< option value = "opengl3" > WebGL 2< / option >
2021-09-20 14:47:55 +02:00
< / select >
< br / >
< br / >
2021-03-24 18:36:37 +01:00
< label for = "zip-file" style = "margin-right: 1rem" > Preload project ZIP:< / label > < input id = "zip-file" type = "file" name = "files" style = "margin-bottom: 1rem" / >
2020-09-14 13:18:49 +02:00
< br / >
2021-01-25 04:48:11 +01:00
< a href = "demo.zip" > (Try this for example)< / a >
< br / >
< br / >
2021-02-24 22:46:43 +01:00
< button id = "startButton" class = "btn" style = "margin-bottom: 4rem; font-weight: 700" > Start Godot editor< / button >
< br / >
< button class = "btn" onclick = "clearPersistence()" style = "margin-bottom: 1.5rem" > Clear persistent data< / button >
2020-09-14 13:18:49 +02:00
< br / >
2021-02-24 22:46:43 +01:00
< a href = "https://docs.godotengine.org/en/latest/tutorials/editor/using_the_web_editor.html" > Web editor documentation< / a >
2020-09-14 13:18:49 +02:00
< / div >
< / div >
2021-03-24 18:36:37 +01:00
< div id = "tab-editor" style = "display: none;" >
< canvas id = "editor-canvas" tabindex = "1" >
2020-09-14 13:18:49 +02:00
HTML5 canvas appears to be unsupported in the current browser.< br / >
Please try updating or use a different browser.
< / canvas >
< / div >
2021-03-24 18:36:37 +01:00
< div id = "tab-game" style = "display: none;" >
< canvas id = "game-canvas" tabindex = "2" >
2020-09-14 13:18:49 +02:00
HTML5 canvas appears to be unsupported in the current browser.< br / >
Please try updating or use a different browser.
< / canvas >
< / div >
2021-03-24 18:36:37 +01:00
< div id = "tab-status" style = "display: none;" >
< 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();" >
2020-09-14 13:18:49 +02:00
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< div > < / div >
< / div >
2021-03-24 18:36:37 +01:00
< div id = "status-notice" class = "godot" style = "display: none;" > < / div >
2020-09-14 13:18:49 +02:00
< / div >
< / div >
2021-03-08 15:39:14 +01:00
< script >
window . addEventListener ( "load" , ( ) => {
if ( "serviceWorker" in navigator ) {
navigator . serviceWorker . register ( "service.worker.js" ) ;
}
2021-03-16 18:35:20 +01:00
if ( localStorage . getItem ( "welcomeModalDismissed" ) !== 'true' ) {
document . getElementById ( "welcome-modal" ) . style . display = "block" ;
document . getElementById ( "welcome-modal-dismiss" ) . focus ( ) ;
}
2021-03-08 15:39:14 +01:00
} ) ;
2021-03-16 18:35:20 +01:00
function closeWelcomeModal ( dontShowAgain ) {
document . getElementById ( "welcome-modal" ) . style . display = "none" ;
if ( dontShowAgain ) {
localStorage . setItem ( "welcomeModalDismissed" , 'true' ) ;
}
}
2021-03-08 15:39:14 +01:00
< / script >
2021-03-24 18:36:37 +01:00
< script src = "godot.tools.js" > < / script >
2021-02-24 22:46:43 +01:00
< script > //<![CDATA[
2020-09-14 13:18:49 +02:00
2021-02-07 13:45:04 +01:00
var editor = null ;
2020-09-14 13:18:49 +02:00
var game = null ;
var setStatusMode ;
var setStatusNotice ;
2021-09-20 14:47:55 +02:00
var video _driver = "" ;
2020-09-14 13:18:49 +02:00
function clearPersistence ( ) {
function deleteDB ( path ) {
return new Promise ( function ( resolve , reject ) {
var req = indexedDB . deleteDatabase ( path ) ;
req . onsuccess = function ( ) {
resolve ( ) ;
} ;
req . onerror = function ( err ) {
reject ( err ) ;
} ;
req . onblocked = function ( err ) {
reject ( err ) ;
}
} ) ;
}
2021-02-24 22:46:43 +01:00
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!" ) ) {
2020-09-14 13:18:49 +02:00
return ;
}
Promise . all ( [
2021-02-08 18:09:15 +01:00
deleteDB ( "/home/web_user" ) ,
2020-09-14 13:18:49 +02:00
] ) . then ( function ( results ) {
alert ( "Done." ) ;
} ) . catch ( function ( err ) {
alert ( "Error deleting local files. Please retry after reloading the page." ) ;
} ) ;
}
function selectVideoMode ( ) {
var select = document . getElementById ( 'videoMode' ) ;
video _driver = select . selectedOptions [ 0 ] . value ;
}
var tabs = [
document . getElementById ( 'tab-loader' ) ,
document . getElementById ( 'tab-editor' ) ,
document . getElementById ( 'tab-game' )
]
function showTab ( name ) {
tabs . forEach ( function ( elem ) {
if ( elem . id == 'tab-' + name ) {
elem . style . display = 'block' ;
2021-02-11 11:41:26 +01:00
if ( name == 'editor' || name == 'game' ) {
const canvas = document . getElementById ( name + '-canvas' ) ;
canvas . focus ( ) ;
}
2020-09-14 13:18:49 +02:00
} else {
elem . style . display = 'none' ;
}
} ) ;
}
function setButtonEnabled ( id , enabled ) {
if ( enabled ) {
document . getElementById ( id ) . disabled = "" ;
} else {
document . getElementById ( id ) . disabled = "disabled" ;
}
}
function setLoaderEnabled ( enabled ) {
setButtonEnabled ( 'btn-tab-loader' , enabled ) ;
setButtonEnabled ( 'btn-tab-editor' , ! enabled ) ;
setButtonEnabled ( 'btn-close-editor' , ! enabled ) ;
}
function setGameTabEnabled ( enabled ) {
setButtonEnabled ( 'btn-tab-game' , enabled ) ;
setButtonEnabled ( 'btn-close-game' , enabled ) ;
}
function closeGame ( ) {
if ( game ) {
game . requestQuit ( ) ;
}
}
function closeEditor ( ) {
closeGame ( ) ;
2021-02-07 13:45:04 +01:00
if ( editor ) {
editor . requestQuit ( ) ;
2020-09-14 13:18:49 +02:00
}
}
function startEditor ( zip ) {
const INDETERMINATE _STATUS _STEP _MS = 100 ;
2021-02-08 18:09:15 +01:00
const persistentPaths = [ '/home/web_user' ] ;
2020-09-14 13:18:49 +02:00
var editorCanvas = document . getElementById ( 'editor-canvas' ) ;
var gameCanvas = document . getElementById ( 'game-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' ) ;
2021-02-07 13:45:04 +01:00
var headerDiv = document . getElementById ( 'tabs-buttons' ) ;
2020-09-14 13:18:49 +02:00
var initializing = true ;
var statusMode = 'hidden' ;
showTab ( 'status' ) ;
var animationCallbacks = [ ] ;
function animate ( time ) {
animationCallbacks . forEach ( callback => callback ( time ) ) ;
requestAnimationFrame ( animate ) ;
}
requestAnimationFrame ( animate ) ;
2021-02-07 13:45:04 +01:00
var lastScale = 0 ;
var lastWidth = 0 ;
var lastHeight = 0 ;
2020-09-14 13:18:49 +02:00
function adjustCanvasDimensions ( ) {
var scale = window . devicePixelRatio || 1 ;
2021-02-07 13:45:04 +01:00
var headerHeight = headerDiv . offsetHeight + 1 ;
2020-09-14 13:18:49 +02:00
var width = window . innerWidth ;
var height = window . innerHeight - headerHeight ;
2021-02-07 13:45:04 +01:00
if ( lastScale !== scale || lastWidth !== width || lastHeight !== height ) {
editorCanvas . width = width * scale ;
editorCanvas . height = height * scale ;
editorCanvas . style . width = width + "px" ;
editorCanvas . style . height = height + "px" ;
lastScale = scale ;
lastWidth = width ;
lastHeight = height ;
}
2020-09-14 13:18:49 +02:00
}
animationCallbacks . push ( adjustCanvasDimensions ) ;
adjustCanvasDimensions ( ) ;
2021-09-20 14:47:55 +02:00
function replaceCanvas ( from ) {
const out = document . createElement ( "canvas" ) ;
out . id = from . id ;
out . tabIndex = from . tabIndex ;
from . parentNode . replaceChild ( out , from ) ;
lastScale = 0 ;
return out ;
}
2020-09-14 13:18:49 +02:00
setStatusMode = function setStatusMode ( mode ) {
if ( statusMode === mode || ! initializing )
return ;
[ statusProgress , statusIndeterminate , statusNotice ] . forEach ( elem => {
elem . style . display = 'none' ;
} ) ;
animationCallbacks = animationCallbacks . filter ( function ( value ) {
return ( value != animateStatusIndeterminate ) ;
} ) ;
switch ( mode ) {
case 'progress' :
statusProgress . style . display = 'block' ;
break ;
case 'indeterminate' :
statusIndeterminate . style . display = 'block' ;
animationCallbacks . push ( animateStatusIndeterminate ) ;
break ;
case 'notice' :
statusNotice . style . display = 'block' ;
break ;
case 'hidden' :
break ;
default :
throw new Error ( 'Invalid status mode' ) ;
}
statusMode = mode ;
2020-11-17 18:18:46 +00:00
} ;
2020-09-14 13:18:49 +02:00
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' ;
}
}
setStatusNotice = function setStatusNotice ( text ) {
while ( statusNotice . lastChild ) {
statusNotice . removeChild ( statusNotice . lastChild ) ;
}
var lines = text . split ( '\n' ) ;
lines . forEach ( ( line ) => {
statusNotice . appendChild ( document . createTextNode ( line ) ) ;
statusNotice . appendChild ( document . createElement ( 'br' ) ) ;
} ) ;
} ;
2021-02-07 13:45:04 +01:00
const gameConfig = {
'persistentPaths' : persistentPaths ,
'unloadAfterInit' : false ,
'canvas' : gameCanvas ,
'canvasResizePolicy' : 1 ,
'onExit' : function ( ) {
2021-09-20 14:47:55 +02:00
gameCanvas = replaceCanvas ( gameCanvas ) ;
2021-02-07 13:45:04 +01:00
setGameTabEnabled ( false ) ;
showTab ( 'editor' ) ;
game = null ;
} ,
} ;
2020-09-14 13:18:49 +02:00
2021-02-07 13:45:04 +01:00
var OnEditorExit = function ( ) {
showTab ( 'loader' ) ;
setLoaderEnabled ( true ) ;
} ;
function Execute ( args ) {
2020-09-14 13:18:49 +02:00
const is _editor = args . filter ( function ( v ) { return v == '--editor' || v == '-e' } ) . length != 0 ;
const is _project _manager = args . filter ( function ( v ) { return v == '--project-manager' } ) . length != 0 ;
const is _game = ! is _editor && ! is _project _manager ;
2021-09-20 14:47:55 +02:00
if ( video _driver ) {
2021-10-25 19:16:40 +02:00
args . push ( '--rendering-driver' , video _driver ) ;
2020-09-14 13:18:49 +02:00
}
2021-10-25 19:16:40 +02:00
2020-09-14 13:18:49 +02:00
if ( is _game ) {
if ( game ) {
console . error ( "A game is already running. Close it first" ) ;
return ;
}
setGameTabEnabled ( true ) ;
2021-02-07 13:45:04 +01:00
game = new Engine ( gameConfig ) ;
2020-09-14 13:18:49 +02:00
showTab ( 'game' ) ;
game . init ( ) . then ( function ( ) {
requestAnimationFrame ( function ( ) {
2021-09-20 14:47:55 +02:00
game . start ( { 'args' : args , 'canvas' : gameCanvas } ) . then ( function ( ) {
2020-09-14 13:18:49 +02:00
gameCanvas . focus ( ) ;
} ) ;
} ) ;
} ) ;
} else { // New editor instances will be run in the same canvas. We want to wait for it to exit.
2021-02-07 13:45:04 +01:00
OnEditorExit = function ( code ) {
2020-09-14 13:18:49 +02:00
setLoaderEnabled ( true ) ;
setTimeout ( function ( ) {
2021-02-07 13:45:04 +01:00
editor . init ( ) . then ( function ( ) {
2020-09-14 13:18:49 +02:00
setLoaderEnabled ( false ) ;
2021-02-07 13:45:04 +01:00
OnEditorExit = function ( ) {
2020-09-14 13:18:49 +02:00
showTab ( 'loader' ) ;
setLoaderEnabled ( true ) ;
2021-02-07 13:45:04 +01:00
} ;
2021-09-20 14:47:55 +02:00
editor . start ( { 'args' : args , 'persistentDrops' : is _project _manager , 'canvas' : editorCanvas } ) ;
2020-09-14 13:18:49 +02:00
} ) ;
} , 0 ) ;
2021-02-07 13:45:04 +01:00
OnEditorExit = null ;
} ;
2020-09-14 13:18:49 +02:00
}
2021-02-07 13:45:04 +01:00
}
const editorConfig = {
'unloadAfterInit' : false ,
'onProgress' : function progressFunction ( current , total ) {
if ( total > 0 ) {
statusProgressInner . style . width = current / total * 100 + '%' ;
setStatusMode ( 'progress' ) ;
if ( current === total ) {
// wait for progress bar animation
setTimeout ( ( ) => {
setStatusMode ( 'indeterminate' ) ;
} , 100 ) ;
}
} else {
setStatusMode ( 'indeterminate' ) ;
}
} ,
'canvas' : editorCanvas ,
'canvasResizePolicy' : 0 ,
'onExit' : function ( ) {
2021-09-20 14:47:55 +02:00
editorCanvas = replaceCanvas ( editorCanvas ) ;
2021-02-07 13:45:04 +01:00
if ( OnEditorExit ) {
OnEditorExit ( ) ;
}
} ,
'onExecute' : Execute ,
'persistentPaths' : persistentPaths ,
} ;
editor = new Engine ( editorConfig ) ;
2020-09-14 13:18:49 +02:00
function displayFailureNotice ( err ) {
var msg = err . message || err ;
console . error ( msg ) ;
setStatusNotice ( msg ) ;
setStatusMode ( 'notice' ) ;
initializing = false ;
} ;
if ( ! Engine . isWebGLAvailable ( ) ) {
displayFailureNotice ( 'WebGL not available' ) ;
} else {
setStatusMode ( 'indeterminate' ) ;
2021-02-07 13:45:04 +01:00
editor . init ( 'godot.tools' ) . then ( function ( ) {
2020-09-14 13:18:49 +02:00
if ( zip ) {
2021-02-07 13:45:04 +01:00
editor . copyToFS ( "/tmp/preload.zip" , zip ) ;
2020-09-14 13:18:49 +02:00
}
try {
// Avoid user creating project in the persistent root folder.
2021-02-07 13:45:04 +01:00
editor . copyToFS ( "/home/web_user/keep" , new Uint8Array ( ) ) ;
2020-09-14 13:18:49 +02:00
} catch ( e ) {
// File exists
}
2021-09-20 14:47:55 +02:00
selectVideoMode ( ) ;
2020-09-14 13:18:49 +02:00
showTab ( 'editor' ) ;
setLoaderEnabled ( false ) ;
2021-10-25 19:16:40 +02:00
const args = [ '--project-manager' , '--single-window' ] ;
2021-09-20 14:47:55 +02:00
if ( video _driver ) {
2021-10-25 19:16:40 +02:00
args . push ( '--rendering-driver' , video _driver ) ;
2021-09-20 14:47:55 +02:00
}
editor . start ( { 'args' : args , 'persistentDrops' : true } ) . then ( function ( ) {
2020-09-14 13:18:49 +02:00
setStatusMode ( 'hidden' ) ;
initializing = false ;
} ) ;
} ) . catch ( displayFailureNotice ) ;
}
} ;
document . getElementById ( "startButton" ) . onclick = function ( ) {
preloadZip ( document . getElementById ( 'zip-file' ) ) . then ( function ( zip ) {
startEditor ( zip ) ;
} ) ;
}
function preloadZip ( target ) {
return new Promise ( function ( resolve , reject ) {
if ( target . files . length > 0 ) {
target . files [ 0 ] . arrayBuffer ( ) . then ( function ( data ) {
resolve ( data ) ;
} ) ;
} else {
resolve ( ) ;
}
} ) ;
}
/ / ] ] > < / script >
< / body >
< / html >