var core = require('../core'), ImageLoader = require('./ImageLoader'), JsonLoader = require('./JsonLoader'), AtlasLoader = require('./AtlasLoader'), SpineLoader = require('./SpineLoader'), BitmapFontLoader = require('./BitmapFontLoader'); /** * A Class that loads a bunch of images / sprite sheet / bitmap font files. Once the * assets have been loaded they are added to the PIXI Texture cache and can be accessed * easily through Texture.fromImage() and Sprite.fromImage() * When all items have been loaded this class will dispatch a 'onLoaded' event * As each individual item is loaded this class will dispatch a 'onProgress' event * * @class * @namespace PIXI * @mixes EventTarget * @param assetURLs {string[]} An array of image/sprite sheet urls that you would like loaded * supported. Supported image formats include 'jpeg', 'jpg', 'png', 'gif'. Supported * sprite sheet data formats only include 'JSON' at this time. Supported bitmap font * data formats include 'xml' and 'fnt'. * @param crossorigin {boolean} Whether requests should be treated as crossorigin */ function AssetLoader(assetURLs, crossorigin) { /** * The array of asset URLs that are going to be loaded * * @member {string[]} */ this.assetURLs = assetURLs; /** * Whether the requests should be treated as cross origin * * @member {boolean} */ this.crossorigin = crossorigin; /** * Maps file extension to loader types * * @member {object} */ this.loadersByType = { 'jpg': ImageLoader, 'jpeg': ImageLoader, 'png': ImageLoader, 'gif': ImageLoader, 'webp': ImageLoader, 'json': JsonLoader, 'atlas': AtlasLoader, 'anim': SpineLoader, 'xml': BitmapFontLoader, 'fnt': BitmapFontLoader }; } // constructor AssetLoader.prototype.constructor = AssetLoader; module.exports = AssetLoader; core.utils.EventTarget.mixin(AssetLoader.prototype); /** * Fired when an item has loaded * @event onProgress */ /** * Fired when all the assets have loaded * @event onComplete */ /** * Given a filename, returns its extension. * * @param str {string} the name of the asset */ AssetLoader.prototype._getDataType = function (str) { var test = 'data:'; var start = str.slice(0, test.length).toLowerCase(); if (start === test) { var data = str.slice(test.length); var sepIdx = data.indexOf(','); // check for malformed data URI scheme if (sepIdx === -1) { return null; } //e.g. 'image/gif;base64' => 'image/gif' var info = data.slice(0, sepIdx).split(';')[0]; //We might need to handle some special cases here... //standardize text/plain to 'txt' file extension if (!info || info.toLowerCase() === 'text/plain') { return 'txt'; } //User specified mime type, try splitting it by '/' return info.split('/').pop().toLowerCase(); } return null; }; /** * Starts loading the assets sequentially * */ AssetLoader.prototype.load = function () { var scope = this; function onLoad(evt) { scope.onAssetLoaded(evt.data.content); } this.loadCount = this.assetURLs.length; for (var i=0; i < this.assetURLs.length; i++) { var fileName = this.assetURLs[i]; //first see if we have a data URI scheme.. var fileType = this._getDataType(fileName); //if not, assume it's a file URI if (!fileType) { fileType = fileName.split('?').shift().split('.').pop().toLowerCase(); } var Constructor = this.loadersByType[fileType]; if (!Constructor) { throw new Error(fileType + ' is an unsupported file type'); } var loader = new Constructor(fileName, this.crossorigin); loader.on('loaded', onLoad); loader.load(); } }; /** * Invoked after each file is loaded * * @private */ AssetLoader.prototype.onAssetLoaded = function (loader) { this.loadCount--; this.emit('onProgress', { content: this, loader: loader }); if (this.onProgress) { this.onProgress(loader); } if (!this.loadCount) { this.emit('onComplete', { content: this }); if (this.onComplete) { this.onComplete(); } } };