Creating Custom Loading Screens

How To Create a Custom Loading Screen

Starting with Babylon.js 2.3 the loading screen (the screen used when loading assets or a scene) can be changed by the developer.

To create a new loading screen, you will have to create a simple class, implementing the following interface:

interface ILoadingScreen {
//What happens when loading starts
displayLoadingUI: () => void;
//What happens when loading stops
hideLoadingUI: () => void;
//default loader support. Optional!
loadingUIBackgroundColor: string;
loadingUIText: string;
}

In plain JavaScript, your loader code will look like this:

function CustomLoadingScreen( /* variables needed, for example:*/ text) {
//init the loader
this.loadingUIText = text;
}
CustomLoadingScreen.prototype.displayLoadingUI = function() {
alert(this.loadingUIText);
};
CustomLoadingScreen.prototype.hideLoadingUI = function() {
alert("Loaded!");
};

In TypeScript the same will look like this:

class CustomLoadingScreen implements ILoadingScreen {
//optional, but needed due to interface definitions
public loadingUIBackgroundColor: string
constructor(public loadingUIText: string) {}
public displayLoadingUI() {
alert(this.loadingUIText);
}
public hideLoadingUI() {
alert("Loaded!");
}
}

The usage is the same in both languages:

var loadingScreen = new CustomLoadingScreen("I'm loading!!");
// replace the default loading screen
engine.loadingScreen = loadingScreen;
// show the loading screen
engine.displayLoadingUI();
/*
* create your scene over here
*/
// hide the loading screen when you want to
engine.hideLoadingUI();

Example

Here a playground using a custom loading screen:

Custom Loading Screen Example

You might also be interested in a standalone html example:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Babylon.js custom loading screen example</title>
<script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
<script src="https://preview.babylonjs.com/babylon.js"></script>
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
<style>
html,
body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
#loadingScreen {
position: absolute;
width: 100%;
height: 100%;
color: white;
font-size: 50px;
text-align: center;
background-color: #BB464Bcc;
z-index: 9999;
}
</style>
</head>
<body>
<div id="loadingScreen">default div text</div>
<canvas id="renderCanvas"></canvas>
<script>
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var loadingScreenDiv = window.document.getElementById("loadingScreen");
function customLoadingScreen() {
console.log("customLoadingScreen creation")
}
customLoadingScreen.prototype.displayLoadingUI = function () {
console.log("customLoadingScreen loading")
loadingScreenDiv.innerHTML = "loading";
};
customLoadingScreen.prototype.hideLoadingUI = function () {
console.log("customLoadingScreen loaded")
loadingScreenDiv.style.display = "none";
};
var loadingScreen = new customLoadingScreen();
engine.loadingScreen = loadingScreen;
engine.displayLoadingUI();
var delayCreateScene = function () {
var scene = new BABYLON.Scene(engine);
scene.createDefaultCamera(true, true, true);
BABYLON.SceneLoader.ImportMesh(
"",
"http://models.babylonjs.com/CornellBox/",
"cornellBox.glb",
scene,
function () {
scene.createDefaultCamera(true, true, true);
scene.createDefaultEnvironment();
scene.activeCamera.alpha = Math.PI / 2;
engine.hideLoadingUI();
});
return scene;
};
var scene = delayCreateScene();
engine.runRenderLoop(function () {
if (scene) {
scene.render();
}
});
window.addEventListener("resize", function () {
engine.resize();
});
</script>
</body>
</html>

Getting File Loading Rate

When loading files, you can get the SceneLoaderProgressEvent sent in the onProgress callback.

Example using BABYLON.SceneLoader.ImportMesh:

BABYLON.SceneLoader.ImportMesh(
"",
"http://models.babylonjs.com/CornellBox/",
"cornellBox.glb",
scene,
function () {
// onSuccess
scene.createDefaultCamera(true, true, true);
scene.activeCamera.alpha = Math.PI / 2;
engine.hideLoadingUI();
},
function (evt) {
// onProgress
var loadedPercent = 0;
if (evt.lengthComputable) {
loadedPercent = (evt.loaded * 100 / evt.total).toFixed();
} else {
var dlCount = evt.loaded / (1024 * 1024);
loadedPercent = Math.floor(dlCount * 100.0) / 100.0;
}
// assuming "loadingScreenPercent" is an existing html element
document.getElementById("loadingScreenPercent").innerHTML = loadedPercent;
}
);

Related videos