2

I'm using createJS - preloadJS and ES6 along with Babel and webpack.

const files = [{ src: 'characterSprite.png', id: 'characterSprite' }];

const Loader = new createjs.LoadQueue(false);
Loader.loadManifest(files, true, 'img/');

export default Loader;

What I want to achieve is in preload.js to load all the images, and in other files (eg. hero.js) to do something like:

import Loader from './loader';
Loader.getResult('characterSprite');

The thing is that when I call .getResult() on loader, the loader has not finished preloading so it returns undefined.

I can check when loader is finished by using:

Loader.addEventListener('complete', () => console.log('loader has finished');

My question is if I can export the module only if the loader has finished?

Is there a better way of doing this?

Hawken MacKay Rives
  • 1,171
  • 1
  • 16
  • 26
Hiero
  • 2,182
  • 7
  • 28
  • 47

1 Answers1

3

I'm not familiar with CreateJS, but this should be plain old ES6 (eh), so you could solve this by wrapping the Loader and start it after importing it:

class MyLoader {
    constructor(files) {
        this.files = files;
    }

    load() {
        // Using a promise is optional, but I would recommend it

        return new Promise((resolve) => {
             const Loader = new createjs.LoadQueue(false);
             Loader.loadManifest(files, true, 'img/');

             Loader.addEventListener('complete', () => { resolve(Loader) });
        });
    }
}

export default MyLoader;

This way you could instance run it like this:

import MyLoader from './MyLoader';
const files = [{ src: 'characterSprite.png', id: 'characterSprite' }];

let myLoaderInstance = new MyLoader(files);
myLoaderInstance.load().then( (completedLoader) => {
    console.log('Loader has finished!', completedLoader.getResult('characterSprite') );
} );

Does this make any sense? :)

EDIT: You also might want to look into Webpack's file-loader, which allows you to require images like you would with JS modules, so that they get bundled with the rest of your code. It doesn't have anything to do with runtime image loading, but it's very handy nonetheless!

Gian Marco Toso
  • 11,676
  • 5
  • 29
  • 38
  • thanks juan, makes sense. but if I want to load MyLoader inside hero.js and enemy.js should load again? – Hiero May 04 '16 at 19:29
  • You could either make two separate instances (one to load the hero assets and one to load the enemy assets) and pass two different `files` array to the constructors. You could also create a "cache" object or whatever where you store the loaded assets, and only trigger the loading when the asset has yet to be loaded. Let me edit the answer. – Gian Marco Toso May 04 '16 at 19:33
  • and I have one more question, if I wrap everything inside the promise callback like () => { const new Stage(); const hero = new Hero(); } inside the hero.js can I import Loader and .getResult()? – Hiero May 04 '16 at 19:35
  • http://jsbin.com/dekecoxawo/1/edit?js,output something like this I want to achieve – Hiero May 04 '16 at 19:40
  • so basically I want a module where I preload all ONCE, and whenever I need something I just import and then .getResult() – Hiero May 04 '16 at 19:41
  • Are you sure that CreateJS's loader doesn't already cache resources so that it only loads them once? Anyhow, why not do something like this: http://jsbin.com/menakekobo/1/edit?js,output . Games are a complicated beast, you need a more complex structure (with caching and all, if not already implemented by CreateJS) to achieve what you're looking for. – Gian Marco Toso May 04 '16 at 19:44
  • yes, is doing like this, but I need to wait to be completed – Hiero May 04 '16 at 19:48
  • thanks, however I use a base64 loader with webpack, it does the job :) – Hiero May 04 '16 at 19:52