Skip to content

Commit 96735eb

Browse files
committed
Add configurable loading screen.
1 parent 64f8d14 commit 96735eb

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

‎docs/components/loader.md‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
title: loader
3+
type: components
4+
layout: docs
5+
parent_section: components
6+
examples: []
7+
---
8+
9+
The loader component configures the loader visual style.
10+
11+
To configure the style of the title bar one can redefine `.a-loader-title` style. The example below sets the text color to red:
12+
13+
```css
14+
.a-loader-title {
15+
color: red;
16+
}
17+
```
18+
19+
## Example
20+
21+
The example below sets the background color to black and dots color to red.
22+
23+
```html
24+
<a-scene loader="dotsColor: red; backgroundColor: black"></a-scene>
25+
```
26+
27+
## Properties
28+
29+
| Property | Description | Default Value |
30+
|-----------------|-----------------------------------------------------------|---------------|
31+
| dotsColor | Loader dots color. | white |
32+
| backgroundColor | Loader background color. | #24CAFF |

‎src/core/scene/a-scene.js‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ var bind = utils.bind;
1515
var isIOS = utils.device.isIOS();
1616
var isMobile = utils.device.isMobile();
1717
var registerElement = re.registerElement;
18+
var styleParser = utils.styleParser;
1819
var warn = utils.debug('core:a-scene:warn');
1920

21+
var LOADER_TITLE_CLASS = 'a-loader-title';
22+
2023
/**
2124
* Scene element, holds all entities.
2225
*
@@ -507,6 +510,80 @@ module.exports.AScene = registerElement('a-scene', {
507510
writable: true
508511
},
509512

513+
setupLoader: {
514+
value: function () {
515+
var self = this;
516+
var loaderAttribute = this.hasAttribute('loader') ? styleParser.parse(this.getAttribute('loader')) : undefined;
517+
var dotsColor = loaderAttribute && loaderAttribute.dotsColor || 'white';
518+
var backgroundColor = loaderAttribute && loaderAttribute.backgroundColor || '#24CAFF';
519+
var loaderScene = new THREE.Scene();
520+
var sphereGeometry = new THREE.SphereGeometry(0.20, 36, 18, 0, 2 * Math.PI, 0, Math.PI);
521+
var sphereMaterial = new THREE.MeshBasicMaterial({color: dotsColor});
522+
var sphereMesh1 = new THREE.Mesh(sphereGeometry, sphereMaterial);
523+
var sphereMesh2 = sphereMesh1.clone();
524+
var sphereMesh3 = sphereMesh1.clone();
525+
var camera = this.loaderCamera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.0005, 10000);
526+
var clock = new THREE.Clock();
527+
var time = 0;
528+
var render = function () {
529+
self.renderer.render(loaderScene, camera);
530+
time = clock.getElapsedTime() % 4;
531+
sphereMesh1.visible = time >= 1;
532+
sphereMesh2.visible = time >= 2;
533+
sphereMesh3.visible = time >= 3;
534+
};
535+
536+
loaderScene.background = new THREE.Color(backgroundColor);
537+
loaderScene.add(camera);
538+
sphereMesh1.position.set(-1, 0, -15);
539+
sphereMesh2.position.set(0, 0, -15);
540+
sphereMesh3.position.set(1, 0, -15);
541+
camera.add(sphereMesh1);
542+
camera.add(sphereMesh2);
543+
camera.add(sphereMesh3);
544+
545+
// Delay 200ms to avoid loader flashes.
546+
setTimeout(function () {
547+
if (self.hasLoaded) { return; }
548+
self.setupLoaderTitle();
549+
self.resizeLoader = bind(self.resizeLoader, self);
550+
self.resizeLoader();
551+
window.addEventListener('resize', self.resizeLoader);
552+
self.renderer.setAnimationLoop(render);
553+
}, 200);
554+
}
555+
},
556+
557+
setupLoaderTitle: {
558+
value: function () {
559+
var title = this.titleEl = document.createElement('div');
560+
title.className = LOADER_TITLE_CLASS;
561+
title.innerHTML = document.title;
562+
this.appendChild(title);
563+
}
564+
},
565+
566+
resizeLoader: {
567+
value: function () {
568+
var camera = this.loaderCamera;
569+
var size = getCanvasSize(this.canvas, false, this.maxCanvasSize, this.is('vr-mode'));
570+
camera.aspect = size.width / size.height;
571+
camera.updateProjectionMatrix();
572+
// Notify renderer of size change.
573+
this.renderer.setSize(size.width, size.height, false);
574+
},
575+
writable: true
576+
},
577+
578+
removeLoader: {
579+
value: function () {
580+
window.removeEventListener('resize', this.resizeLoader);
581+
if (!this.titleEl) { return; }
582+
// Hide title.
583+
this.titleEl.style.display = 'none';
584+
}
585+
},
586+
510587
setupRenderer: {
511588
value: function () {
512589
var self = this;
@@ -551,6 +628,8 @@ module.exports.AScene = registerElement('a-scene', {
551628
this.addEventListener('camera-set-active', function () {
552629
renderer.vr.setPoseTarget(self.camera);
553630
});
631+
632+
this.setupLoader();
554633
},
555634
writable: window.debug
556635
},
@@ -580,6 +659,7 @@ module.exports.AScene = registerElement('a-scene', {
580659
if (sceneEl.renderer) {
581660
if (window.performance) { window.performance.mark('render-started'); }
582661
sceneEl.clock = new THREE.Clock();
662+
sceneEl.removeLoader();
583663
sceneEl.render();
584664
sceneEl.renderStarted = true;
585665
sceneEl.emit('renderstart');

‎src/style/aframe.css‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,18 @@ a-scene audio {
264264
text-indent: -9999px;
265265
width: 50px;
266266
}
267+
268+
.a-loader-title {
269+
background-color: rgba(0, 0, 0, 0.6);
270+
font-family: sans-serif, monospace;
271+
text-align: center;
272+
font-size: 20px;
273+
height: 50px;
274+
font-weight: 300;
275+
line-height: 50px;
276+
position: absolute;
277+
right: 0px;
278+
left: 0px;
279+
top: 0px;
280+
color: white;
281+
}

0 commit comments

Comments
 (0)