{"version":3,"file":"spritesheet.min.mjs","sources":["../../src/Spritesheet.ts","../../src/SpritesheetLoader.ts"],"sourcesContent":["import { Rectangle } from '@pixi/math';\nimport { Texture, BaseTexture } from '@pixi/core';\nimport { deprecation, getResolutionOfUrl } from '@pixi/utils';\nimport type { Dict } from '@pixi/utils';\nimport type { ImageResource } from '@pixi/core';\nimport type { IPointData } from '@pixi/math';\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: Dict;\n animations?: Dict;\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 * PIXI.Loader.shared.add(\"images/spritesheet.json\").load(setup);\n *\n * function setup() {\n * let sheet = PIXI.Loader.shared.resources[\"images/spritesheet.json\"].spritesheet;\n * ...\n * }\n * ```\n *\n * Alternately, you may circumvent the loader by instantiating the Spritesheet directly:\n * ```js\n * const sheet = new PIXI.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,`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 * ```js\n * new PIXI.Sprite(sheet.textures[\"image.png\"]);\n * ```\n */\n public textures: Dict;\n\n /**\n * A map containing the textures for each animation.\n * Can be used to create an {@link PIXI.AnimatedSprite|AnimatedSprite}:\n * ```js\n * new PIXI.AnimatedSprite(sheet.animations[\"anim_name\"])\n * ```\n */\n public animations: Dict;\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: Dict;\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: Dict) => 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 = 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 = scale !== undefined ? 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>;\n\n /**\n * Please use the Promise-based version of this function.\n * @method PIXI.Spritesheet#parse\n * @deprecated since version 6.5.0\n * @param {Function} callback - Callback when complete returns\n * a map of the Textures for this spritesheet.\n */\n public parse(callback?: (textures?: Dict) => void): void;\n\n /** @ignore */\n public parse(callback?: (textures?: Dict) => void): Promise>\n {\n // #if _DEBUG\n if (callback)\n {\n deprecation('6.5.0', 'Spritesheet.parse callback is deprecated, use the return Promise instead.');\n }\n // #endif\n\n return new Promise((resolve) =>\n {\n this._callback = (textures: Dict) =>\n {\n callback?.(textures);\n resolve(textures);\n };\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\n/**\n * Reference to Spritesheet object created.\n * @member {PIXI.Spritesheet} spritesheet\n * @memberof PIXI.LoaderResource\n * @instance\n */\n\n/**\n * Dictionary of textures from Spritesheet.\n * @member {Object} textures\n * @memberof PIXI.LoaderResource\n * @instance\n */\n","import { url } from '@pixi/utils';\nimport { Spritesheet } from './Spritesheet';\nimport { LoaderResource } from '@pixi/loaders';\nimport type { Loader } from '@pixi/loaders';\nimport type { ExtensionMetadata } from '@pixi/core';\nimport { ExtensionType } from '@pixi/core';\n\n/**\n * {@link PIXI.Loader} middleware for loading texture atlases that have been created with\n * TexturePacker or similar JSON-based spritesheet.\n *\n * This middleware automatically generates Texture resources.\n *\n * If you're using Webpack or other bundlers and plan on bundling the atlas' JSON,\n * use the {@link PIXI.Spritesheet} class to directly parse the JSON.\n *\n * The Loader's image Resource name is automatically appended with `\"_image\"`.\n * If a Resource with this name is already loaded, the Loader will skip parsing the\n * Spritesheet. The code below will generate an internal Loader Resource called `\"myatlas_image\"`.\n * @example\n * loader.add('myatlas', 'path/to/myatlas.json');\n * loader.load(() => {\n * loader.resources.myatlas; // atlas JSON resource\n * loader.resources.myatlas_image; // atlas Image resource\n * });\n * @memberof PIXI\n */\nexport class SpritesheetLoader\n{\n /** @ignore */\n static extension: ExtensionMetadata = ExtensionType.Loader;\n\n /**\n * Called after a resource is loaded.\n * @see PIXI.Loader.loaderMiddleware\n * @param resource\n * @param next\n */\n static use(resource: LoaderResource, next: (...args: unknown[]) => void): void\n {\n // because this is middleware, it execute in loader context. `this` = loader\n const loader = (this as any) as Loader;\n const imageResourceName = `${resource.name}_image`;\n\n // skip if no data, its not json, it isn't spritesheet data, or the image resource already exists\n if (!resource.data\n || resource.type !== LoaderResource.TYPE.JSON\n || !resource.data.frames\n || loader.resources[imageResourceName]\n )\n {\n next();\n\n return;\n }\n\n // Check and add the multi atlas\n // Heavily influenced and based on https://github.com/rocket-ua/pixi-tps-loader/blob/master/src/ResourceLoader.js\n // eslint-disable-next-line camelcase\n const multiPacks = resource.data?.meta?.related_multi_packs;\n\n if (Array.isArray(multiPacks))\n {\n for (const item of multiPacks)\n {\n if (typeof item !== 'string')\n {\n continue;\n }\n\n const itemName = item.replace('.json', '');\n const itemUrl = url.resolve(resource.url.replace(loader.baseUrl, ''), item);\n\n // Check if the file wasn't already added as multipacks are redundant\n if (loader.resources[itemName]\n || Object.values(loader.resources).some((r) => url.format(url.parse(r.url)) === itemUrl))\n {\n continue;\n }\n\n const options = {\n crossOrigin: resource.crossOrigin,\n loadType: LoaderResource.LOAD_TYPE.XHR,\n xhrType: LoaderResource.XHR_RESPONSE_TYPE.JSON,\n parentResource: resource,\n metadata: resource.metadata\n };\n\n loader.add(itemName, itemUrl, options);\n }\n }\n\n const loadOptions = {\n crossOrigin: resource.crossOrigin,\n metadata: resource.metadata.imageMetadata,\n parentResource: resource,\n };\n\n const resourcePath = SpritesheetLoader.getResourcePath(resource, loader.baseUrl);\n\n // load the image for this sheet\n loader.add(imageResourceName, resourcePath, loadOptions, function onImageLoad(res: LoaderResource)\n {\n if (res.error)\n {\n next(res.error);\n\n return;\n }\n\n const spritesheet = new Spritesheet(\n res.texture,\n resource.data,\n resource.url\n );\n\n spritesheet.parse().then(() =>\n {\n resource.spritesheet = spritesheet;\n resource.textures = spritesheet.textures;\n next();\n });\n });\n }\n\n /**\n * Get the spritesheets root path\n * @param resource - Resource to check path\n * @param baseUrl - Base root url\n */\n static getResourcePath(resource: LoaderResource, baseUrl: string): string\n {\n // Prepend url path unless the resource image is a data url\n if (resource.isDataUrl)\n {\n return resource.data.meta.image;\n }\n\n return url.resolve(resource.url.replace(baseUrl, ''), resource.data.meta.image);\n }\n}\n"],"names":["Spritesheet","texture","data","resolutionFilename","this","linkedSheets","_texture","Texture","baseTexture","BaseTexture","textures","animations","resource","resolution","_updateResolution","url","_frames","frames","_frameKeys","Object","keys","_batchIndex","_callback","prototype","scale","meta","getResolutionOfUrl","undefined","parseFloat","setResolution","parse","callback","_this","Promise","resolve","length","BATCH_SIZE","_processFrames","_processAnimations","_parseComplete","_nextBatch","initialFrameIndex","frameIndex","maxFrames","i","rect","frame","trim","sourceSize","trimmed","orig","Rectangle","Math","floor","w","h","rotated","x","y","spriteSourceSize","anchor","addToCache","animName","frameName","push","call","setTimeout","destroy","destroyBase","_a","SpritesheetLoader","use","next","loader","imageResourceName","name","type","LoaderResource","TYPE","JSON","resources","multiPacks","_b","related_multi_packs","Array","isArray","item","itemName","replace","itemUrl","baseUrl","values","some","r","format","options","crossOrigin","loadType","LOAD_TYPE","XHR","xhrType","XHR_RESPONSE_TYPE","parentResource","metadata","add","multiPacks_1","_i","loadOptions","imageMetadata","resourcePath","getResourcePath","res","error","spritesheet","then","isDataUrl","image","extension","ExtensionType","Loader"],"mappings":"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"}