/** * @class Ext.draw.sprite.Image * @extends Ext.draw.sprite.Rect * * A sprite that represents an image. */Ext.define('Ext.draw.sprite.Image', { extend: 'Ext.draw.sprite.Rect', alias: 'sprite.image', type: 'image', statics: { imageLoaders: {} }, inheritableStatics: { def: { processors: { /** * @cfg {String} [src=''] The image source of the sprite. */ src: 'string' /** * @private * @cfg {Number} radius */ }, triggers: { src: 'src' }, updaters: { src: 'updateSource' }, defaults: { src: '', /** * @cfg {Number} [width=null] The width of the image. * For consistent image size on all devices the width must be explicitly set. * Otherwise the natural image width devided by the device pixel ratio * (for a crisp looking image) will be used as the width of the sprite. */ width: null, /** * @cfg {Number} [height=null] The height of the image. * For consistent image size on all devices the height must be explicitly set. * Otherwise the natural image height devided by the device pixel ratio * (for a crisp looking image) will be used as the height of the sprite. */ height: null } } }, updateSurface: function (surface) { if (surface) { this.updateSource(this.attr); } }, updateSource: function (attr) { var me = this, src = attr.src, surface = me.getSurface(), loadingStub = Ext.draw.sprite.Image.imageLoaders[src], width = attr.width, height = attr.height, imageLoader, i; if (!surface) { // First time this is called the sprite won't have a surface yet. return; } if (!loadingStub) { imageLoader = new Image(); loadingStub = Ext.draw.sprite.Image.imageLoaders[src] = { image: imageLoader, done: false, pendingSprites: [me], pendingSurfaces: [surface] }; imageLoader.width = width; imageLoader.height = height; imageLoader.onload = function () { var item; if (!loadingStub.done) { loadingStub.done = true; for (i = 0; i < loadingStub.pendingSprites.length; i++) { item = loadingStub.pendingSprites[i]; if (!item.destroyed) { item.setDirty(true); } } for (i = 0; i < loadingStub.pendingSurfaces.length; i++) { item = loadingStub.pendingSurfaces[i]; if (!item.destroyed) { item.renderFrame(); } } } }; imageLoader.src = src; } else { Ext.Array.include(loadingStub.pendingSprites, me); Ext.Array.include(loadingStub.pendingSurfaces, surface); } }, render: function (surface, ctx) { var me = this, attr = me.attr, mat = attr.matrix, src = attr.src, x = attr.x, y = attr.y, width = attr.width, height = attr.height, loadingStub = Ext.draw.sprite.Image.imageLoaders[src], image; if (loadingStub && loadingStub.done) { mat.toContext(ctx); image = loadingStub.image; ctx.drawImage(image, x, y, width || (image.naturalWidth || image.width) / surface.devicePixelRatio, height || (image.naturalHeight || image.height) / surface.devicePixelRatio); } //<debug> var debug = attr.debug || this.statics().debug || Ext.draw.sprite.Sprite.debug; if (debug) { debug.bbox && this.renderBBox(surface, ctx); } //</debug> }, /** * @private */ isVisible: function () { var attr = this.attr, parent = this.getParent(), hasParent = parent && (parent.isSurface || parent.isVisible()), isSeen = hasParent && !attr.hidden && attr.globalAlpha; return !!isSeen; } });