2017-03-27 15:04:44 -04:00
|
|
|
var AssetType = require('scratch-storage').AssetType;
|
2017-03-27 15:12:25 -04:00
|
|
|
var log = require('../util/log');
|
2017-03-27 15:04:44 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Load a costume's asset into memory asynchronously.
|
|
|
|
* Do not call this unless there is a renderer attached.
|
|
|
|
* @param {string} md5ext - the MD5 and extension of the costume to be loaded.
|
|
|
|
* @param {!object} costume - the Scratch costume object.
|
|
|
|
* @property {int} skinId - the ID of the costume's render skin, once installed.
|
|
|
|
* @property {number} rotationCenterX - the X component of the costume's origin.
|
|
|
|
* @property {number} rotationCenterY - the Y component of the costume's origin.
|
|
|
|
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
|
|
|
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
|
|
|
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
|
|
|
*/
|
|
|
|
var loadCostume = function (md5ext, costume, runtime) {
|
|
|
|
if (!runtime.storage) {
|
|
|
|
log.error('No storage module present; cannot load costume asset: ', md5ext);
|
2017-04-03 15:58:13 -04:00
|
|
|
return Promise.resolve(costume);
|
2017-03-27 15:04:44 -04:00
|
|
|
}
|
2017-03-31 11:26:20 -04:00
|
|
|
|
2017-03-27 15:04:44 -04:00
|
|
|
|
|
|
|
var idParts = md5ext.split('.');
|
|
|
|
var md5 = idParts[0];
|
|
|
|
var ext = idParts[1].toUpperCase();
|
|
|
|
var assetType = (ext === 'SVG') ? AssetType.ImageVector : AssetType.ImageBitmap;
|
|
|
|
|
|
|
|
var rotationCenter = [
|
|
|
|
costume.rotationCenterX / costume.bitmapResolution,
|
|
|
|
costume.rotationCenterY / costume.bitmapResolution
|
|
|
|
];
|
|
|
|
|
2017-04-03 15:58:13 -04:00
|
|
|
var promise = runtime.storage.load(assetType, md5).then(function (costumeAsset) {
|
|
|
|
costume.url = costumeAsset.encodeDataURI();
|
|
|
|
return costumeAsset;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!runtime.renderer) {
|
|
|
|
log.error('No rendering module present; cannot load costume asset: ', md5ext);
|
|
|
|
return promise.then(function () {
|
|
|
|
return costume;
|
|
|
|
});
|
|
|
|
}
|
2017-03-27 15:04:44 -04:00
|
|
|
|
|
|
|
if (assetType === AssetType.ImageVector) {
|
|
|
|
promise = promise.then(function (costumeAsset) {
|
|
|
|
costume.skinId = runtime.renderer.createSVGSkin(costumeAsset.decodeText(), rotationCenter);
|
2017-04-03 15:58:13 -04:00
|
|
|
return costume;
|
2017-03-27 15:04:44 -04:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
promise = promise.then(function (costumeAsset) {
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
|
|
var imageElement = new Image();
|
|
|
|
var removeEventListeners; // fix no-use-before-define
|
|
|
|
var onError = function () {
|
|
|
|
removeEventListeners();
|
|
|
|
reject();
|
|
|
|
};
|
|
|
|
var onLoad = function () {
|
|
|
|
removeEventListeners();
|
|
|
|
resolve(imageElement);
|
|
|
|
};
|
|
|
|
removeEventListeners = function () {
|
|
|
|
imageElement.removeEventListener('error', onError);
|
|
|
|
imageElement.removeEventListener('load', onLoad);
|
|
|
|
};
|
|
|
|
imageElement.addEventListener('error', onError);
|
|
|
|
imageElement.addEventListener('load', onLoad);
|
|
|
|
imageElement.src = costumeAsset.encodeDataURI();
|
|
|
|
});
|
|
|
|
}).then(function (imageElement) {
|
|
|
|
costume.skinId = runtime.renderer.createBitmapSkin(imageElement, costume.bitmapResolution, rotationCenter);
|
2017-04-03 15:58:13 -04:00
|
|
|
return costume;
|
2017-03-27 15:04:44 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return promise;
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = loadCostume;
|