{"version":3,"file":"Spritesheet.mjs","sources":["../src/Spritesheet.ts"],"sourcesContent":["import { BaseTexture, Rectangle, Texture, utils } from 'pixijs/core';\n\nimport type { ImageResource, IPointData } from 'pixijs/core';\n\n/** Represents the JSON data for a spritesheet atlas. */\nexport interface ISpritesheetFrameData\n{\n    frame: {\n        x: number;\n        y: number;\n        w: number;\n        h: number;\n    };\n    trimmed?: boolean;\n    rotated?: boolean;\n    sourceSize?: {\n        w: number;\n        h: number;\n    };\n    spriteSourceSize?: {\n        x: number;\n        y: number;\n    };\n    anchor?: IPointData;\n}\n\n/** Atlas format. */\nexport interface ISpritesheetData\n{\n    frames: utils.Dict<ISpritesheetFrameData>;\n    animations?: utils.Dict<string[]>;\n    meta: {\n        scale: string;\n        // eslint-disable-next-line camelcase\n        related_multi_packs?: string[];\n    };\n}\n\n/**\n * Utility class for maintaining reference to a collection\n * of Textures on a single Spritesheet.\n *\n * To access a sprite sheet from your code you may pass its JSON data file to Pixi's loader:\n *\n * ```js\n * import { Assets } from 'pixijs/browser';\n *\n * const sheet = await Assets.load('images/spritesheet.json');\n * ```\n *\n * Alternately, you may circumvent the loader by instantiating the Spritesheet directly:\n *\n * ```js\n * import { Spritesheet } from 'pixijs/browser';\n *\n * const sheet = new Spritesheet(texture, spritesheetData);\n * await sheet.parse();\n * console.log('Spritesheet ready to use!');\n * ```\n *\n * With the `sheet.textures` you can create Sprite objects, and `sheet.animations` can be used to create an AnimatedSprite.\n *\n * Sprite sheets can be packed using tools like {@link https://codeandweb.com/texturepacker|TexturePacker},\n * {@link https://renderhjs.net/shoebox/|Shoebox} or {@link https://github.com/krzysztof-o/spritesheet.js|Spritesheet.js}.\n * Default anchor points (see {@link PIXI.Texture#defaultAnchor}) and grouping of animation sprites are currently only\n * supported by TexturePacker.\n * @memberof PIXI\n */\nexport class Spritesheet\n{\n    /** The maximum number of Textures to build per process. */\n    static readonly BATCH_SIZE = 1000;\n\n    /** For multi-packed spritesheets, this contains a reference to all the other spritesheets it depends on. */\n    public linkedSheets: Spritesheet[] = [];\n\n    /** Reference to ths source texture. */\n    public baseTexture: BaseTexture;\n\n    /**\n     * A map containing all textures of the sprite sheet.\n     * Can be used to create a {@link PIXI.Sprite|Sprite}:\n     * @example\n     * import { Sprite } from 'pixijs/browser';\n     *\n     * new Sprite(sheet.textures['image.png']);\n     */\n    public textures: utils.Dict<Texture>;\n\n    /**\n     * A map containing the textures for each animation.\n     * Can be used to create an {@link PIXI.AnimatedSprite|AnimatedSprite}:\n     * @example\n     * import { AnimatedSprite } from 'pixijs/browser';\n     *\n     * new AnimatedSprite(sheet.animations['anim_name']);\n     */\n    public animations: utils.Dict<Texture[]>;\n\n    /**\n     * Reference to the original JSON data.\n     * @type {object}\n     */\n    public data: ISpritesheetData;\n\n    /** The resolution of the spritesheet. */\n    public resolution: number;\n\n    /**\n     * Reference to original source image from the Loader. This reference is retained so we\n     * can destroy the Texture later on. It is never used internally.\n     */\n    private _texture: Texture;\n\n    /**\n     * Map of spritesheet frames.\n     * @type {object}\n     */\n    private _frames: utils.Dict<ISpritesheetFrameData>;\n\n    /** Collection of frame names. */\n    private _frameKeys: string[];\n\n    /** Current batch index being processed. */\n    private _batchIndex: number;\n\n    /**\n     * Callback when parse is completed.\n     * @type {Function}\n     */\n    private _callback: (textures: utils.Dict<Texture>) => void;\n\n    /**\n     * @param texture - Reference to the source BaseTexture object.\n     * @param {object} data - Spritesheet image data.\n     * @param resolutionFilename - The filename to consider when determining\n     *        the resolution of the spritesheet. If not provided, the imageUrl will\n     *        be used on the BaseTexture.\n     */\n    constructor(texture: BaseTexture | Texture, data: ISpritesheetData, resolutionFilename: string = null)\n    {\n        this._texture = texture instanceof Texture ? texture : null;\n        this.baseTexture = texture instanceof BaseTexture ? texture : this._texture.baseTexture;\n        this.textures = {};\n        this.animations = {};\n        this.data = data;\n\n        const resource = this.baseTexture.resource as ImageResource;\n\n        this.resolution = this._updateResolution(resolutionFilename || (resource ? resource.url : null));\n        this._frames = this.data.frames;\n        this._frameKeys = Object.keys(this._frames);\n        this._batchIndex = 0;\n        this._callback = null;\n    }\n\n    /**\n     * Generate the resolution from the filename or fallback\n     * to the meta.scale field of the JSON data.\n     * @param resolutionFilename - The filename to use for resolving\n     *        the default resolution.\n     * @returns Resolution to use for spritesheet.\n     */\n    private _updateResolution(resolutionFilename: string = null): number\n    {\n        const { scale } = this.data.meta;\n\n        // Use a defaultValue of `null` to check if a url-based resolution is set\n        let resolution = utils.getResolutionOfUrl(resolutionFilename, null);\n\n        // No resolution found via URL\n        if (resolution === null)\n        {\n            // Use the scale value or default to 1\n            resolution = parseFloat(scale ?? '1');\n        }\n\n        // For non-1 resolutions, update baseTexture\n        if (resolution !== 1)\n        {\n            this.baseTexture.setResolution(resolution);\n        }\n\n        return resolution;\n    }\n\n    /**\n     * Parser spritesheet from loaded data. This is done asynchronously\n     * to prevent creating too many Texture within a single process.\n     * @method PIXI.Spritesheet#parse\n     */\n    public parse(): Promise<utils.Dict<Texture>>\n    {\n        return new Promise((resolve) =>\n        {\n            this._callback = resolve;\n            this._batchIndex = 0;\n\n            if (this._frameKeys.length <= Spritesheet.BATCH_SIZE)\n            {\n                this._processFrames(0);\n                this._processAnimations();\n                this._parseComplete();\n            }\n            else\n            {\n                this._nextBatch();\n            }\n        });\n    }\n\n    /**\n     * Process a batch of frames\n     * @param initialFrameIndex - The index of frame to start.\n     */\n    private _processFrames(initialFrameIndex: number): void\n    {\n        let frameIndex = initialFrameIndex;\n        const maxFrames = Spritesheet.BATCH_SIZE;\n\n        while (frameIndex - initialFrameIndex < maxFrames && frameIndex < this._frameKeys.length)\n        {\n            const i = this._frameKeys[frameIndex];\n            const data = this._frames[i];\n            const rect = data.frame;\n\n            if (rect)\n            {\n                let frame = null;\n                let trim = null;\n                const sourceSize = data.trimmed !== false && data.sourceSize\n                    ? data.sourceSize : data.frame;\n\n                const orig = new Rectangle(\n                    0,\n                    0,\n                    Math.floor(sourceSize.w) / this.resolution,\n                    Math.floor(sourceSize.h) / this.resolution\n                );\n\n                if (data.rotated)\n                {\n                    frame = new Rectangle(\n                        Math.floor(rect.x) / this.resolution,\n                        Math.floor(rect.y) / this.resolution,\n                        Math.floor(rect.h) / this.resolution,\n                        Math.floor(rect.w) / this.resolution\n                    );\n                }\n                else\n                {\n                    frame = new Rectangle(\n                        Math.floor(rect.x) / this.resolution,\n                        Math.floor(rect.y) / this.resolution,\n                        Math.floor(rect.w) / this.resolution,\n                        Math.floor(rect.h) / this.resolution\n                    );\n                }\n\n                //  Check to see if the sprite is trimmed\n                if (data.trimmed !== false && data.spriteSourceSize)\n                {\n                    trim = new Rectangle(\n                        Math.floor(data.spriteSourceSize.x) / this.resolution,\n                        Math.floor(data.spriteSourceSize.y) / this.resolution,\n                        Math.floor(rect.w) / this.resolution,\n                        Math.floor(rect.h) / this.resolution\n                    );\n                }\n\n                this.textures[i] = new Texture(\n                    this.baseTexture,\n                    frame,\n                    orig,\n                    trim,\n                    data.rotated ? 2 : 0,\n                    data.anchor\n                );\n\n                // lets also add the frame to pixi's global cache for 'from' and 'fromLoader' functions\n                Texture.addToCache(this.textures[i], i);\n            }\n\n            frameIndex++;\n        }\n    }\n\n    /** Parse animations config. */\n    private _processAnimations(): void\n    {\n        const animations = this.data.animations || {};\n\n        for (const animName in animations)\n        {\n            this.animations[animName] = [];\n            for (let i = 0; i < animations[animName].length; i++)\n            {\n                const frameName = animations[animName][i];\n\n                this.animations[animName].push(this.textures[frameName]);\n            }\n        }\n    }\n\n    /** The parse has completed. */\n    private _parseComplete(): void\n    {\n        const callback = this._callback;\n\n        this._callback = null;\n        this._batchIndex = 0;\n        callback.call(this, this.textures);\n    }\n\n    /** Begin the next batch of textures. */\n    private _nextBatch(): void\n    {\n        this._processFrames(this._batchIndex * Spritesheet.BATCH_SIZE);\n        this._batchIndex++;\n        setTimeout(() =>\n        {\n            if (this._batchIndex * Spritesheet.BATCH_SIZE < this._frameKeys.length)\n            {\n                this._nextBatch();\n            }\n            else\n            {\n                this._processAnimations();\n                this._parseComplete();\n            }\n        }, 0);\n    }\n\n    /**\n     * Destroy Spritesheet and don't use after this.\n     * @param {boolean} [destroyBase=false] - Whether to destroy the base texture as well\n     */\n    public destroy(destroyBase = false): void\n    {\n        for (const i in this.textures)\n        {\n            this.textures[i].destroy();\n        }\n        this._frames = null;\n        this._frameKeys = null;\n        this.data = null;\n        this.textures = null;\n        if (destroyBase)\n        {\n            this._texture?.destroy();\n            this.baseTexture.destroy();\n        }\n        this._texture = null;\n        this.baseTexture = null;\n        this.linkedSheets = [];\n    }\n}\n"],"names":[],"mappings":"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"}