#

API Docs for: 2.0.0
Show: Inherited Protected Private Deprecated

# File: src/pixi/textures/Texture.js

    /**
     * @author Mat Groves http://matgroves.com/ @Doormat23
     */

    PIXI.TextureCache = {};
    PIXI.FrameCache = {};

    PIXI.TextureCacheIdGenerator = 0;

    /**
     * A texture stores the information that represents an image or part of an image. It cannot be added
     * to the display list directly. Instead use it as the texture for a PIXI.Sprite. If no frame is provided then the whole image is used.
     *
     * @class Texture
     * @uses EventTarget
     * @constructor
     * @param baseTexture {BaseTexture} The base texture source to create the texture from
     * @param frame {Rectangle} The rectangle frame of the texture to show
     * @param [crop] {Rectangle} The area of original texture
     * @param [trim] {Rectangle} Trimmed texture rectangle
     */
    PIXI.Texture = function(baseTexture, frame, crop, trim)
    {
        /**
         * Does this Texture have any frame data assigned to it?
         *
         * @property noFrame
         * @type Boolean
         */
        this.noFrame = false;

        if (!frame)
        {
            this.noFrame = true;
            frame = new PIXI.Rectangle(0,0,1,1);
        }

        if (baseTexture instanceof PIXI.Texture)
        {
            baseTexture = baseTexture.baseTexture;
        }

        /**
         * The base texture that this texture uses.
         *
         * @property baseTexture
         * @type BaseTexture
         */
        this.baseTexture = baseTexture;

        /**
         * The frame specifies the region of the base texture that this texture uses
         *
         * @property frame
         * @type Rectangle
         */
        this.frame = frame;

        /**
         * The texture trim data.
         *
         * @property trim
         * @type Rectangle
         */
        this.trim = trim;

        /**
         * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered.
         *
         * @property valid
         * @type Boolean
         */
        this.valid = false;

        /**
         * This will let a renderer know that a texture has been updated (used mainly for webGL uv updates)
         *
         * @property requiresUpdate
         * @type Boolean
         */
        this.requiresUpdate = false;

        /**
         * The WebGL UV data cache.
         *
         * @property _uvs
         * @type Object
         * @private
         */
        this._uvs = null;

        /**
         * The width of the Texture in pixels.
         *
         * @property width
         * @type Number
         */
        this.width = 0;

        /**
         * The height of the Texture in pixels.
         *
         * @property height
         * @type Number
         */
        this.height = 0;

        /**
         * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering,
         * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases)
         *
         * @property crop
         * @type Rectangle
         */
        this.crop = crop || new PIXI.Rectangle(0, 0, 1, 1);

        if (baseTexture.hasLoaded)
        {
            if (this.noFrame) frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height);
            this.setFrame(frame);
        }
        else
        {
            baseTexture.addEventListener('loaded', this.onBaseTextureLoaded.bind(this));
        }
    };

    PIXI.Texture.prototype.constructor = PIXI.Texture;
    PIXI.EventTarget.mixin(PIXI.Texture.prototype);

    /**
     * Called when the base texture is loaded
     *
     * @method onBaseTextureLoaded
     * @private
     */
    PIXI.Texture.prototype.onBaseTextureLoaded = function()
    {
        var baseTexture = this.baseTexture;
        baseTexture.removeEventListener('loaded', this.onLoaded);

        if (this.noFrame) this.frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height);

        this.setFrame(this.frame);

        this.dispatchEvent( { type: 'update', content: this } );
    };

    /**
     * Destroys this texture
     *
     * @method destroy
     * @param destroyBase {Boolean} Whether to destroy the base texture as well
     */
    PIXI.Texture.prototype.destroy = function(destroyBase)
    {
        if (destroyBase) this.baseTexture.destroy();

        this.valid = false;
    };

    /**
     * Specifies the region of the baseTexture that this texture will use.
     *
     * @method setFrame
     * @param frame {Rectangle} The frame of the texture to set it to
     */
    PIXI.Texture.prototype.setFrame = function(frame)
    {
        this.noFrame = false;

        this.frame = frame;
        this.width = frame.width;
        this.height = frame.height;

        this.crop.x = frame.x;
        this.crop.y = frame.y;
        this.crop.width = frame.width;
        this.crop.height = frame.height;

        if (!this.trim && (frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height))
        {
            throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this);
        }

        this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded;

        if (this.trim)
        {
            this.width = this.trim.width;
            this.height = this.trim.height;
            this.frame.width = this.trim.width;
            this.frame.height = this.trim.height;
        }

        if (this.valid) this._updateUvs();

    };

    /**
     * Updates the internal WebGL UV cache.
     *
     * @method _updateUvs
     * @private
     */
    PIXI.Texture.prototype._updateUvs = function()
    {
        if(!this._uvs)this._uvs = new PIXI.TextureUvs();

        var frame = this.crop;
        var tw = this.baseTexture.width;
        var th = this.baseTexture.height;

        this._uvs.x0 = frame.x / tw;
        this._uvs.y0 = frame.y / th;

        this._uvs.x1 = (frame.x + frame.width) / tw;
        this._uvs.y1 = frame.y / th;

        this._uvs.x2 = (frame.x + frame.width) / tw;
        this._uvs.y2 = (frame.y + frame.height) / th;

        this._uvs.x3 = frame.x / tw;
        this._uvs.y3 = (frame.y + frame.height) / th;
    };

    /**
     * Helper function that creates a Texture object from the given image url.
     * If the image is not in the texture cache it will be  created and loaded.
     *
     * @static
     * @method fromImage
     * @param imageUrl {String} The image url of the texture
     * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
     * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts
     * @return Texture
     */
    PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode)
    {
        var texture = PIXI.TextureCache[imageUrl];

        if(!texture)
        {
            texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin, scaleMode));
            PIXI.TextureCache[imageUrl] = texture;
        }

        return texture;
    };

    /**
     * Helper function that returns a Texture objected based on the given frame id.
     * If the frame id is not in the texture cache an error will be thrown.
     *
     * @static
     * @method fromFrame
     * @param frameId {String} The frame id of the texture
     * @return Texture
     */
    PIXI.Texture.fromFrame = function(frameId)
    {
        var texture = PIXI.TextureCache[frameId];
        if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ');
        return texture;
    };

    /**
     * Helper function that creates a new a Texture based on the given canvas element.
     *
     * @static
     * @method fromCanvas
     * @param canvas {Canvas} The canvas element source of the texture
     * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts
     * @return Texture
     */
    PIXI.Texture.fromCanvas = function(canvas, scaleMode)
    {
        var baseTexture = PIXI.BaseTexture.fromCanvas(canvas, scaleMode);

        return new PIXI.Texture( baseTexture );

    };

    /**
     * Adds a texture to the global PIXI.TextureCache. This cache is shared across the whole PIXI object.
     *
     * @static
     * @method addTextureToCache
     * @param texture {Texture} The Texture to add to the cache.
     * @param id {String} The id that the texture will be stored against.
     */
    PIXI.Texture.addTextureToCache = function(texture, id)
    {
        PIXI.TextureCache[id] = texture;
    };

    /**
     * Remove a texture from the global PIXI.TextureCache.
     *
     * @static
     * @method removeTextureFromCache
     * @param id {String} The id of the texture to be removed
     * @return {Texture} The texture that was removed
     */
    PIXI.Texture.removeTextureFromCache = function(id)
    {
        var texture = PIXI.TextureCache[id];
        delete PIXI.TextureCache[id];
        delete PIXI.BaseTextureCache[id];
        return texture;
    };

    PIXI.TextureUvs = function()
    {
        this.x0 = 0;
        this.y0 = 0;

        this.x1 = 0;
        this.y1 = 0;

        this.x2 = 0;
        this.y2 = 0;

        this.x3 = 0;
        this.y3 = 0;
    };