/* * SpriteSheetLoader * Visit http://createjs.com/ for documentation, updates and examples. * * * Copyright (c) 2012 gskinner.com, inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /** * @module PreloadJS */ // namespace: this.createjs = this.createjs || {}; (function () { "use strict"; // constructor /** * A loader for EaselJS SpriteSheets. Images inside the spritesheet definition are loaded before the loader * completes. To load SpriteSheets using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} * as part of the {{#crossLink "LoadItem"}}{{/crossLink}}. Note that the {{#crossLink "JSONLoader"}}{{/crossLink}} * and {{#crossLink "JSONPLoader"}}{{/crossLink}} are higher priority loaders, so SpriteSheets <strong>must</strong> * set the {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property * to {{#crossLink "Types/SPRITESHEET:property"}}{{/crossLink}}. * * The {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/crossOrigin:property"}}{{/crossLink}} as well * as the {{#crossLink "LoadQueue's"}}{{/crossLink}} `basePath` argument and {{#crossLink "LoadQueue/_preferXHR"}}{{/crossLink}} * property supplied to the {{#crossLink "LoadQueue"}}{{/crossLink}} are passed on to the sub-manifest that loads * the SpriteSheet images. * * Note that the SpriteSheet JSON does not respect the {{#crossLink "LoadQueue/_preferXHR:property"}}{{/crossLink}} * property, which should instead be determined by the presence of a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} * property on the SpriteSheet load item. This is because the JSON loaded will have a different format depending on * if it is loaded as JSON, so just changing `preferXHR` is not enough to change how it is loaded. * @class SpriteSheetLoader * @param {LoadItem|Object} loadItem * @extends AbstractLoader * @constructor */ function SpriteSheetLoader(loadItem, preferXHR) { this.AbstractLoader_constructor(loadItem, preferXHR, createjs.Types.SPRITESHEET); // protected properties /** * An internal queue which loads the SpriteSheet's images. * @method _manifestQueue * @type {LoadQueue} * @private */ this._manifestQueue = null; } var p = createjs.extend(SpriteSheetLoader, createjs.AbstractLoader); var s = SpriteSheetLoader; // static properties /** * The amount of progress that the manifest itself takes up. * @property SPRITESHEET_PROGRESS * @type {number} * @default 0.25 (25%) * @private * @static */ s.SPRITESHEET_PROGRESS = 0.25; // static methods /** * Determines if the loader can load a specific item. This loader can only load items that are of type * {{#crossLink "Types/SPRITESHEET:property"}}{{/crossLink}} * @method canLoadItem * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. * @returns {Boolean} Whether the loader can load the item. * @static */ s.canLoadItem = function (item) { return item.type == createjs.Types.SPRITESHEET; }; // public methods p.destroy = function() { this.AbstractLoader_destroy(); this._manifestQueue.close(); }; // protected methods p._createRequest = function() { var callback = this._item.callback; if (callback != null) { this._request = new createjs.JSONPLoader(this._item); } else { this._request = new createjs.JSONLoader(this._item); } }; p.handleEvent = function (event) { switch (event.type) { case "complete": this._rawResult = event.target.getResult(true); this._result = event.target.getResult(); this._sendProgress(s.SPRITESHEET_PROGRESS); this._loadManifest(this._result); return; case "progress": event.loaded *= s.SPRITESHEET_PROGRESS; this.progress = event.loaded / event.total; if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; } this._sendProgress(event); return; } this.AbstractLoader_handleEvent(event); }; /** * Create and load the images once the SpriteSheet JSON has been loaded. * @method _loadManifest * @param {Object} json * @private */ p._loadManifest = function (json) { if (json && json.images) { var queue = this._manifestQueue = new createjs.LoadQueue(this._preferXHR, this._item.path, this._item.crossOrigin); queue.on("complete", this._handleManifestComplete, this, true); queue.on("fileload", this._handleManifestFileLoad, this); queue.on("progress", this._handleManifestProgress, this); queue.on("error", this._handleManifestError, this, true); queue.loadManifest(json.images); } }; /** * An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed. * @method _handleManifestFileLoad * @param {Event} event * @private */ p._handleManifestFileLoad = function (event) { var image = event.result; if (image != null) { var images = this.getResult().images; var pos = images.indexOf(event.item.src); images[pos] = image; } }; /** * The images have completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} * {{#crossLink "Event"}}{{/crossLink}} from the SpriteSheetLoader. * @method _handleManifestComplete * @param {Event} event * @private */ p._handleManifestComplete = function (event) { this._result = new createjs.SpriteSheet(this._result); this._loadedItems = this._manifestQueue.getItems(true); this._sendComplete(); }; /** * The images {{#crossLink "LoadQueue"}}{{/crossLink}} has reported progress. * @method _handleManifestProgress * @param {ProgressEvent} event * @private */ p._handleManifestProgress = function (event) { this.progress = event.progress * (1 - s.SPRITESHEET_PROGRESS) + s.SPRITESHEET_PROGRESS; this._sendProgress(this.progress); }; /** * An image has reported an error. * @method _handleManifestError * @param {ErrorEvent} event * @private */ p._handleManifestError = function (event) { var newEvent = new createjs.Event("fileerror"); newEvent.item = event.data; this.dispatchEvent(newEvent); }; createjs.SpriteSheetLoader = createjs.promote(SpriteSheetLoader, "AbstractLoader"); }());