src/loader.js
import { EventEmitter } from './event-emitter';
/**
* Service to load asset
* @example
* let layer = {
* create: function() {
* loader.add('img/my-image.png', 'player-image');
* loader.add('config/my-config.json', 'player-config', 'json');
* },
* render: function() {
* const image = loader.get('player-image');
* const config = loader.get('player-config');
* this.ctx.drawImage(image, config.x, config.y);
* }
* }
*/
export class Loader extends EventEmitter {
constructor() {
super();
/** @type {number} */
this.count = 0;
/** @type {number} */
this.queue = 0;
/** @type {number} */
this.progress = 0;
/** @type {boolean} */
this.ready = true;
/** @type {Array} */
this.collection = [];
}
/**
* Add asset to load
* @param {string} src
* @param {string} id
* @param {string} type - (image or json)
*/
add(src, id, type = 'image') {
this.count++;
this.queue++;
this.ready = false;
switch (type) {
case 'image':
this.loadImage(src, id);
break;
case 'json':
this.loadJson(src, id);
break
}
}
/**
* Add asset into the collection and dispatch event
* @param {mixed} el
* @param {string} id
* @emits {load} emit when asset is loaded
* @emits {ready} emit when all assets are loaded
*/
load(el, id) {
this.queue--;
this.progress = 1 - this.queue / this.count;
this.collection.push({ id: id, item: el });
this.dispatch('load', this.progress);
if (this.queue == 0) {
this.count = 0;
this.progress = 0;
this.ready = true;
this.dispatch('ready');
}
}
/**
* Load image
* @private
* @param {string} src
* @param {string} id
*/
loadImage(src, id) {
let img = new Image();
img.src = src;
img.onload = () => this.load(img, id);
}
/**
* Load json file
* @private
* @param {string} src
* @param {string} id
*/
loadJson(src, id) {
var request = new XMLHttpRequest();
request.open("GET", src, true);
request.onload = e => {
let data = JSON.parse(e.target.response);
this.load(data, id);
}
request.send();
}
/**
* Get asset by id
* @param {string} id
* @return {mixed}
*/
get(id) {
let items = this.collection.filter(el => el.id === id);
if (items.length == 0) {
return null;
}
return items.length > 1 ? items.map(el => el.item) : items[0].item;
}
}
const loader = new Loader();
export default loader;