LoadScreen.js
A Three.js assets loading wrapper.
Summary
Installation
Include in your project :
npm install loadscreen
Or in your page :
Overview
A full demo is proposed on codepen here.
Main pattern
//First create and append a webgl renderer, then :const ls = renderer start ASSETS ; { //Init scene, then : ls;}
Load screens
By default LoadScreen.js automatically generates the 'linear-horizontal' load screen. It displays and follows those steps : 'Loading' > 'Processing' > 'Compiling' > 'Creating scene'.
Assets style
Passed assets style is declarative, no callback hell.
const ASSETS = textures: foliageMap: path: 'path/to/pic1.png' fileSize: 1467 minFilter: THREELinearFilter foliageAO: path: 'path/to/pic2.png' fileSize: 1275 geometries: shape: path: 'path/to/model.json' fileSize: 3876 flatNormals: true toBufferGeometry: true { geometry } objects: tree: geometry: 'shape' map: 'foliageMap' aoMap: 'foliageAO' material: castShadow: true transparent: true { objectscale; } ;
Full pattern
Methods are chainable, except remove
and setProgress
. Values are default.
const style = type: 'linear-horizontal'//Main look. 'custom' empties the info container. size: '170px'//Width of the central info container, in px or in %. background: '#333' progressContainerColor: '#000' progressColor: '#333' infoStyle: //Text style : default values. fontFamily: 'monospace' color: '#666' fontSize: '12px' padding: '10px' weight: '10'//Weight of the progress element (svg units). sizeInfo: true//Display size progress in MB. progressInfo: true//Display the progress element. textInfo: 'Loading' 'Processing' 'Compiling' 'Creating scene' //Or false to remove.; const options = forcedStart: false//Start loading even if the canvas is out of sight (usually bad practice). verbose: false//Logs progress, process and compile duration + total load screen duration. tweenDuration: 5//Progress and removal tweens durations.; const ls = renderer style ;//Style is optional. window; ls //Can be used to update a custom UI. //After processing and compiling. start ASSETS ;//Load assets > process assets > compile materials > scene creation. //orstart;//Just add the info UI. //Then for big script progress or just testing.ls; //Finally at the end of the onComplete callbackls;//Removal is tweened so next action is a callback.
Assets declaration
Note : the fileSize
parameter is necessary for every files, explication here.
By order of processing :
1. Files
- THREE.FileLoader
ASSETSfiles = myFile1: path: 'path/to/file.txt' fileSize: 2789//in Ko { //do something } ;
2. Fonts
- THREE.TTFLoader
ASSETSfontsmyFont1 = path: 'path/to/font.ttf' fileSize: 321; //After loading :ASSETSfontsmyFont1;//THREE.Font
3. Textures
- THREE.CubeTextureLoader
- THREE.HDRCubeTextureLoader
- THREE.KTXLoader
- THREE.PVRLoader
- THREE.TextureLoader
- THREE.TGALoader
ASSETStextures = myTexture1: //Regular textures. path: 'path/to/pic.jpg' fileSize: 2789//in Ko //Other threejs textures properties can be specified. minFilter: THREELinearFilter { //Do something. } myTexture2: //Cubemaps. path: '1.hdr' '2.hdr' '3.hdr' '4.hdr' '5.hdr' '6.hdr' fileSize: 5321 //Optional : if files are HDR, a PMREM can get output. toPMREM: true ; //GPU compression formats can be used, script will check device support.ASSETStexturesmyTexture1GPUCompression: PVR: path: 'path/to/PVR/pic.pvr' fileSize: 3298 //Apple format. KTX: path: 'path/to/KTX/pic.ktx' fileSize: 2983 //Khronos format.; //After loading :ASSETStexturesmyTexture1;//THREE.Texture //Also simply :ASSETStexturesmyTexture3 = ...;//Won't be processed.
4. Materials
- THREE.MaterialLoader
- THREE.MTLLoader
ASSETSmaterials = myMaterial1: path: 'path/to/material.mtl' fileSize: 188 //Optionally : map: 'myTexture1'//Asset assigned after loading. //To use the MTLLoader with the OBJLoader and its 'setMaterials' method, //just add a 'setMaterials' property to the object, of value 'myMaterial1'. //If used alone, the output of the MTLLoader is a THREE.MTLLoader.MaterialCreator : { //matCreator.preload() or matCreator.getAsArray() } ; //After loading :ASSETSmaterialsmyMaterial1;//THREE.MTLLoader.MaterialCreator,//or object with materials ( matCreator.preload() )//or array with materials ( matCreator.getAsArray() ). //Also in most other use cases :ASSETSmaterialsmyMaterial2 = ;//Won't be processed.
5. Geometries
- THREE.BufferGeometryLoader (format conflict with JSONLoader)
- THREE.CTMLoader (
load
method) - THREE.JSONLoader (threejs blender exporter)
- THREE.PLYLoader
- THREE.STLLoader
- THREE.VTKLoader
ASSETSgeometries = myGeometry1: path: 'path/to/geometry.ply' fileSize: 9498//Ko //Next two are optional : flatNormals: true//Call geometry.computeFlatVertexNormals() on THREE.Geometry instances. toBufferGeometry: false//Force creation of a BufferGeometry. { //geometry.translate / center / merge / addAttribute... } ; //After loading :ASSETSgeometriesmyGeometry1;//THREE.Geometry //Also simply :ASSETSgeometriesmyGeometry2 = 3 2 1 ;//Won't be processed.
6. Animations
- THREE.BVHLoader
ASSETSanimations = myAnimation1: path: 'path/to/anim.bvh' fileSize: 4827 { //Catch bvh.skeleton and bvh.clip. } ;
7. Objects
- THREE.ThreeMFLoader
- THREE.AMFLoader
- THREE.AssimpLoader
- THREE.AssimpJSONLoader
- THREE.AWDLoader
- THREE.BabylonLoader
- THREE.BinaryLoader
- THREE.ColladaLoader
- THREE.ColladaLoader (2)
- THREE.CTMLoader (
loadParts
method for multiple geometries) - THREE.FBXLoader
- THREE.FBXLoader (2)
- THREE.GLTFLoader
- THREE.GLTFLoader (2)
- THREE.MMDLoader (needs the additional parameter
VMDPaths
) - THREE.PCDLoader
- THREE.ObjectLoader
- THREE.OBJLoader
- THREE.PlayCanvasLoader (format conflict with ObjectLoader)
- THREE.UTF8Loader
- THREE.VRMLLoader
ASSETSobjects = myObject1: //Load from file : path: 'path/to/object.obj' setMaterials: 'myMaterial1'//OBJLoader option for use with MTLLoader. fileSize: 3846//Ko myObject2: //Or create from asset : geometry: 'myGeometry1'//Use geometry asset 'myGeometry1' material: myObject3: //Or create from scratch : geometry: 5 3 9 material: myObject4: //The object may have a hierarchy and / or animation(s): path: 'path/to/object.dae' fileSize: 1111 convertUpAxis: true//Collada loader option. { //Catch collada.scene, collada.animation etc. //Same with GLTF etc. } ; //Other parameters.ASSETSobjectsmyObject5 = geometry: 'myGeometry1' material: type: 'mesh'//Or 'points' or 'line', defaults to 'mesh'. //Specify any mesh or material property : //(if the object is a hierarchy, they will only get assigned to the root mesh). map: 'myTexture1'//Asset assigned to material. color: 0x33ff89//Converted to a THREE.Color and assigned to material. castShadow: true//Assigned to mesh. info: 'This is my object'//Unknown key 'info' in mesh and material > assigned to mesh.userData.; //After loading : ASSETSobjectsmyObject5;//THREE.Mesh //Also simply :ASSETSobjectsmyObject6 = ...;//Won't be processed.
FAQ
Why is it mandatory to indicate fileSize
?
- XHR issue handling : sometimes the progress events can have
e.total
equaling zero, resulting in an infinite progress value when doinge.loaded/e.total
. WithfileSize
in Ko, the library has a fallback.- UX quality : with this information the loader has a linear progress. Contrarily, if two files of different sizes were to be loaded without the
fileSize
information, one big and one small, and if the small one is immediately received before even having a progress event of the other one, the progress bar can jump to 50%, then take more time to reach 100%, giving a mistaken information.
Why isn't the indicator progression perfectly smooth ?
For one file it should be, but for more, though the progress should be linear, it relies on the three.js loaders which automatically process the received data to output a geometry, a cubemap etc, while other files are still loading. Thus the processing time inside the native loaders can still freeze the rest of the loading sometimes. The HDRCubeTextureLoader is particularly concerned. Of course for performance reasons it should be more visible on mobile than pc.