File:SpriteSheetLoader.js
/*
* 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 "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}.
* @class SpriteSheetLoader
* @param {LoadItem|Object} loadItem
* @extends AbstractLoader
* @constructor
*/
function SpriteSheetLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, null, createjs.AbstractLoader.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 "AbstractLoader/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.AbstractLoader.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 && callback instanceof Function) {
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();
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");
}());