npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

loadscreen

v0.18.14

Published

A three.js assets loading wrapper

Downloads

16

Readme

LoadScreen.js

Latest NPM release License Dependencies

A Three.js assets loading wrapper.

Summary

  1. Installation
  2. Overview
    1. Main pattern
    2. Load screens
    3. Declarative assets style
  3. Full pattern
  4. Assets declaration
    1. Files
    2. Fonts
    3. Textures
    4. Materials
    5. Geometries
    6. Animations
    7. Objects
  5. FAQ

Installation

Include in your project :

npm install loadscreen

Or in your page :

<script type="text/javascript" src="LoadScreen.min.js"/>

Overview

A full demo is proposed on codepen here.

Main pattern

//First create and append a webgl renderer, then :
const ls = new LoadScreen( renderer ).onComplete( init ).start( ASSETS );

function init () {
    //Init scene, then :
    ls.remove( animate );
}

Load screens

By default LoadScreen.js automatically generates the 'linear-horizontal' load screen. It displays and follows those steps : 'Loading' > 'Processing' > 'Compiling' > 'Creating scene'.

Loader types

Assets style

Passed assets style is declarative, no callback hell.

const ASSETS = {
    textures: {
        foliageMap: {
            path: 'path/to/pic1.png', fileSize: 1467,
            minFilter: THREE.LinearFilter
        },
        foliageAO: { 
            path: 'path/to/pic2.png', fileSize: 1275 
        }
    },
    geometries: {
        shape: {
            path: 'path/to/model.json', fileSize: 3876,
            flatNormals: true,
            toBufferGeometry: true,
            onComplete ( geometry ) {
                geometry.addAttribute( 'uv2', geometry.attributes.uv )
            }
        }
    }, 
    objects: {
        tree: {
            geometry: 'shape',
            map: 'foliageMap',
            aoMap: 'foliageAO',
            material: new THREE.MeshStandardMaterial(),
            castShadow: true,
            transparent: true,
            onComplete ( object ) {
                object.scale.set( 1, 3, 1 );
            }
        }
    }
};

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 = new LoadScreen( renderer, style );//Style is optional.

window.addEventListener( 'resize', () => { 
    renderer.setSize( width, height ); 
    ls.setSize( width, height ); 
});

ls.setOptions( options )

.onProgress( progress => { ... } )//Can be used to update a custom UI.

.onComplete( init )//After processing and compiling.

.start( ASSETS );//Load assets > process assets > compile materials > scene creation.

//or
.start();//Just add the info UI.

//Then for big script progress or just testing.
ls.setProgress( 0.5 );

//Finally at the end of the onComplete callback
ls.remove( animate );//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

  • [x] THREE.FileLoader
ASSETS.files = {
    myFile1: { 
        path: 'path/to/file.txt',
        fileSize: 2789,//in Ko
        onComplete ( file ) {
            //do something
        }
    }
};

2. Fonts

  • [x] THREE.TTFLoader
ASSETS.fonts.myFont1 = {
    path: 'path/to/font.ttf',
    fileSize: 321
};

//After loading :
ASSETS.fonts.myFont1;//THREE.Font

3. Textures

  • [x] THREE.CubeTextureLoader
  • [x] THREE.HDRCubeTextureLoader
  • [x] THREE.KTXLoader
  • [x] THREE.PVRLoader
  • [x] THREE.TextureLoader
  • [x] THREE.TGALoader
ASSETS.textures = {
    myTexture1: {//Regular textures.
        path: 'path/to/pic.jpg',
        fileSize: 2789,//in Ko
        //Other threejs textures properties can be specified.
        minFilter: THREE.LinearFilter,
        onComplete ( texture ) {
            //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.
ASSETS.textures.myTexture1.GPUCompression: {
    PVR: { path: 'path/to/PVR/pic.pvr', fileSize: 3298 },//Apple format.
    KTX: { path: 'path/to/KTX/pic.ktx', fileSize: 2983 }//Khronos format.
};

//After loading :
ASSETS.textures.myTexture1;//THREE.Texture

//Also simply :
ASSETS.textures.myTexture3 = new THREE.Texture(...);//Won't be processed.

4. Materials

  • [x] THREE.MaterialLoader
  • [x] THREE.MTLLoader
ASSETS.materials = {
    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 :
        onComplete ( matCreator ) {
            //matCreator.preload() or matCreator.getAsArray()
        }

    }
};

//After loading :
ASSETS.materials.myMaterial1;//THREE.MTLLoader.MaterialCreator,
//or object with materials ( matCreator.preload() )
//or array with materials ( matCreator.getAsArray() ).

//Also in most other use cases :
ASSETS.materials.myMaterial2 = new THREE.Material();//Won't be processed.

5. Geometries

  • [ ] THREE.BufferGeometryLoader (format conflict with JSONLoader)
  • [x] THREE.CTMLoader (load method)
  • [x] THREE.JSONLoader (threejs blender exporter)
  • [x] THREE.PLYLoader
  • [x] THREE.STLLoader
  • [x] THREE.VTKLoader
ASSETS.geometries = {
    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.
        onComplete ( geometry ) {
            //geometry.translate / center / merge / addAttribute...
        }
    }
};

//After loading :
ASSETS.geometries.myGeometry1;//THREE.Geometry

//Also simply :
ASSETS.geometries.myGeometry2 = new THREE.BoxGeometry( 3, 2, 1 );//Won't be processed.

6. Animations

  • [x] THREE.BVHLoader
ASSETS.animations = {
    myAnimation1: {
        path: 'path/to/anim.bvh',
        fileSize: 4827,
        onComplete ( bvh ) {
            //Catch bvh.skeleton and bvh.clip.
        }
    }
};

7. Objects

  • [x] THREE.ThreeMFLoader
  • [x] THREE.AMFLoader
  • [x] THREE.AssimpLoader
  • [x] THREE.AssimpJSONLoader
  • [x] THREE.AWDLoader
  • [x] THREE.BabylonLoader
  • [x] THREE.BinaryLoader
  • [x] THREE.ColladaLoader
  • [x] THREE.ColladaLoader (2)
  • [ ] THREE.CTMLoader (loadParts method for multiple geometries)
  • [x] THREE.FBXLoader
  • [x] THREE.FBXLoader (2)
  • [x] THREE.GLTFLoader
  • [x] THREE.GLTFLoader (2)
  • [x] THREE.MMDLoader (needs the additional parameter VMDPaths )
  • [x] THREE.PCDLoader
  • [x] THREE.ObjectLoader
  • [x] THREE.OBJLoader
  • [ ] THREE.PlayCanvasLoader (format conflict with ObjectLoader)
  • [x] THREE.UTF8Loader
  • [x] THREE.VRMLLoader
ASSETS.objects = {
    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: new THREE.MeshPhongMaterial()
    },
    myObject3: {//Or create from scratch :
        geometry: new THREE.PlaneBufferGeometry( 5, 3, 9 ),
        material: new THREE.MeshBasicMaterial()
    },
    myObject4: {//The object may have a hierarchy and / or animation(s):
        path: 'path/to/object.dae',
        fileSize: 1111,
        convertUpAxis: true,//Collada loader option.
        onComplete ( collada ) {
            //Catch collada.scene, collada.animation etc.
            //Same with GLTF etc.
        }
    }
};

//Other parameters.
ASSETS.objects.myObject5 = {
    geometry: 'myGeometry1',
    material: new THREE.MeshPhongMaterial(),
    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 : 
ASSETS.objects.myObject5;//THREE.Mesh

//Also simply :
ASSETS.objects.myObject6 = new THREE.Mesh(...);//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 doing e.loaded/e.total. With fileSize 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.