UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 43.9 kB
{"version":3,"file":"AnimatedSprite.mjs","sources":["../../../src/scene/sprite-animated/AnimatedSprite.ts"],"sourcesContent":["import { Texture } from '../../rendering/renderers/shared/texture/Texture';\nimport { UPDATE_PRIORITY } from '../../ticker/const';\nimport { Ticker } from '../../ticker/Ticker';\nimport { Sprite } from '../sprite/Sprite';\n\nimport type { SpriteOptions } from '../sprite/Sprite';\n\n/**\n * A collection of textures or frame objects that can be used to create an `AnimatedSprite`.\n * @see {@link AnimatedSprite}\n * @category scene\n * @standard\n */\nexport type AnimatedSpriteFrames = Texture[] | FrameObject[];\n\n/**\n * Constructor options used for `AnimatedSprite` instances. Allows configuration of animation\n * playback, speed, and texture frames.\n * @example\n * ```ts\n * // Create a basic animated sprite\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png')\n * ],\n * animationSpeed: 0.1,\n * loop: true\n * });\n *\n * // Create with spritesheet frames and callbacks\n * const sheet = await Assets.load('character.json');\n * const animatedSprite = new AnimatedSprite({\n * textures: sheet.animations['walk'],\n * autoPlay: true,\n * updateAnchor: true,\n * onComplete: () => console.log('Animation complete'),\n * onFrameChange: (frame) => console.log('Current frame:', frame),\n * onLoop: () => console.log('Animation looped')\n * });\n *\n * // Create with custom timing for each frame\n * const customTimingSprite = new AnimatedSprite({\n * textures: [\n * { texture: Texture.from('frame1.png'), time: 100 },\n * { texture: Texture.from('frame2.png'), time: 200 },\n * { texture: Texture.from('frame3.png'), time: 300 }\n * ],\n * autoUpdate: true\n * });\n * ```\n * @see {@link AnimatedSprite} For the main sprite class\n * @see {@link Spritesheet} For loading animations from spritesheets\n * @category scene\n * @standard\n * @noInheritDoc\n */\nexport interface AnimatedSpriteOptions extends PixiMixins.AnimatedSpriteOptions, Omit<SpriteOptions, 'texture'>\n{\n /**\n * The speed that the AnimatedSprite will play at. Higher is faster, lower is slower.\n * @example\n * ```ts\n * // Create an AnimatedSprite with a slower animation speed\n * const animation = new AnimatedSprite({\n * textures: [Texture.from('frame1.png'), Texture.from('frame2.png')],\n * animationSpeed: 0.5 // Slower animation\n * });\n *\n * // Update the animation speed to make it faster\n * animation.animationSpeed = 2; // Faster animation\n * ```\n * @default 1\n */\n animationSpeed?: number;\n\n /**\n * Whether to start the animation immediately on creation.\n * If set to `true`, the animation will start playing as soon as the\n * `AnimatedSprite` is created.\n * If set to `false`, you will need to call the `play` method to start the animation.\n * @example\n * ```ts\n * // Create an AnimatedSprite that starts playing immediately\n * const animation = new AnimatedSprite({\n * textures: [Texture.from('frame1.png'), Texture.from('frame2.png')],\n * autoPlay: true\n * });\n *\n * // Create an AnimatedSprite that does not start playing immediately\n * const animation = new AnimatedSprite({\n * textures: [Texture.from('frame1.png'), Texture.from('frame2.png')],\n * autoPlay: false\n * });\n * animation.play(); // Start the animation manually\n * ```\n * @default false\n */\n autoPlay?: boolean;\n\n /**\n * Whether to use Ticker.shared to auto update animation time.\n * This is useful for animations that need to be updated every frame.\n * If set to `false`, you will need to manually call the `update` method\n * to update the animation.\n * @example\n * ```ts\n * // Create an AnimatedSprite that does not auto update\n * const animation = new AnimatedSprite({\n * textures: [Texture.from('frame1.png'), Texture.from('frame2.png')],\n * autoUpdate: false\n * });\n *\n * // Manually update the animation in your game loop\n * ticker.add((ticker) => {\n * animation.update(ticker);\n * }\n * ```\n * @default true\n */\n autoUpdate?: boolean;\n\n /**\n * Whether or not the animation repeats after playing.\n * @default true\n */\n loop?: boolean;\n\n /**\n * User-assigned function to call when an AnimatedSprite finishes playing.\n * @example\n * ```ts\n * animation.onComplete = () => {\n * // Finished!\n * console.log('Animation complete');\n * };\n * ```\n * @default null\n * @see {@link AnimatedSprite#onFrameChange} For the callback when the frame changes\n * @see {@link AnimatedSprite#onLoop} For the callback when the animation loops\n * @see {@link AnimatedSprite#loop} For the loop behavior of the animation\n */\n onComplete?: () => void;\n\n /**\n * User-assigned function to call when an AnimatedSprite changes which texture is being rendered.\n * @example\n * ```ts\n * animation.onFrameChange = (currentFrame) => {\n * // Updated!\n * console.log('Current frame:', currentFrame);\n * };\n * ```\n * @see {@link AnimatedSprite#onComplete} For the callback when the animation finishes\n * @see {@link AnimatedSprite#onLoop} For the callback when the animation loops\n * @default null\n */\n onFrameChange?: (currentFrame: number) => void;\n\n /**\n * User-assigned function to call when `loop` is true,\n * and an AnimatedSprite is played and loops around to start again.\n * @example\n * ```ts\n * animation.onLoop = () => {\n * // Looped!\n * };\n * ```\n * @see {@link AnimatedSprite#onComplete} For the callback when the animation finishes\n * @see {@link AnimatedSprite#onFrameChange} For the callback when the frame changes\n * @see {@link AnimatedSprite#loop} For the loop behavior of the animation\n * @default null\n */\n onLoop?: () => void;\n\n /**\n * An array of {@link Texture} or frame objects that make up the animation.\n * @example\n * ```ts\n * // Create an AnimatedSprite with an array of textures\n * const animation = new AnimatedSprite({\n * textures: [\n * Texture.from('frame1.png'),\n * Texture.from('frame2.png'),\n * Texture.from('frame3.png')\n * ]\n * });\n * * // Create an AnimatedSprite with an array of frame objects\n * const animation = new AnimatedSprite({\n * textures: [\n * { texture: Texture.from('frame1.png'), time: 100 },\n * { texture: Texture.from('frame2.png'), time: 200 },\n * { texture: Texture.from('frame3.png'), time: 300 }\n * ]\n * });\n * ```\n * @see {@link AnimatedSpriteFrames} For the type of the textures array\n */\n textures: AnimatedSpriteFrames;\n\n /**\n * Update anchor to [Texture's defaultAnchor]{@link Texture#defaultAnchor} when frame changes.\n *\n * Useful with [sprite sheet animations]{@link Spritesheet#animations} created with tools.\n * Changing anchor for each frame allows to pin sprite origin to certain moving feature\n * of the frame (e.g. left foot).\n * > [!NOTE] Enabling this will override any previously set `anchor` on each frame change.\n * @example\n * ```ts\n * // Create an AnimatedSprite with updateAnchor enabled\n * const animation = new AnimatedSprite({\n * textures: [Texture.from('frame1.png'), Texture.from('frame2.png')],\n * updateAnchor: true\n * });\n * ```\n * @see {@link Texture#defaultAnchor} For the default anchor of the texture\n * @default false\n */\n updateAnchor?: boolean;\n}\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface AnimatedSprite extends PixiMixins.AnimatedSprite, Sprite {}\n\n/**\n * An AnimatedSprite is a simple way to display an animation depicted by a list of textures.\n * @example\n * ```js\n * import { AnimatedSprite, Texture } from 'pixi.js';\n *\n * const alienImages = [\n * 'image_sequence_01.png',\n * 'image_sequence_02.png',\n * 'image_sequence_03.png',\n * 'image_sequence_04.png',\n * ];\n * const textureArray = [];\n *\n * for (let i = 0; i < 4; i++)\n * {\n * const texture = Texture.from(alienImages[i]);\n * textureArray.push(texture);\n * }\n *\n * const animatedSprite = new AnimatedSprite(textureArray);\n * ```\n *\n * The more efficient and simpler way to create an animated sprite is using a {@link Spritesheet}\n * containing the animation definitions:\n * @example\n * ```js\n * import { AnimatedSprite, Assets } from 'pixi.js';\n *\n * const sheet = await Assets.load('assets/spritesheet.json');\n * animatedSprite = new AnimatedSprite(sheet.animations['image_sequence']);\n * ```\n * @category scene\n * @standard\n */\nexport class AnimatedSprite extends Sprite\n{\n /**\n * The speed that the AnimatedSprite will play at. Higher is faster, lower is slower.\n * @example\n * ```ts\n * // Create a sprite with normal speed animation\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png')\n * ],\n * animationSpeed: 1 // Default speed\n * });\n *\n * // Slow down the animation\n * sprite.animationSpeed = 0.5;\n *\n * // Speed up the animation\n * sprite.animationSpeed = 2;\n *\n * // Reverse the animation\n * sprite.animationSpeed = -1;\n *\n * // Stop the animation\n * sprite.animationSpeed = 0;\n * ```\n * @default 1\n * @see {@link AnimatedSprite#currentFrame} For the current frame index\n * @see {@link AnimatedSprite#totalFrames} For total number of frames\n */\n public animationSpeed: number;\n\n /**\n * Whether or not the animation repeats after playing.\n * When true, the animation will restart from the beginning after reaching the last frame.\n * When false, the animation will stop on the last frame.\n * @example\n * ```ts\n * // Create a looping animation\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png')\n * ],\n * loop: true // Will repeat\n * });\n *\n * // Play animation once\n * sprite.loop = false;\n * sprite.onComplete = () => console.log('Animation finished!');\n * sprite.play();\n *\n * // Toggle looping at runtime\n * sprite.loop = !sprite.loop;\n * ```\n * @default true\n * @see {@link AnimatedSprite#onComplete} Callback when non-looping animation completes\n * @see {@link AnimatedSprite#onLoop} Callback when animation loops\n */\n public loop: boolean;\n\n /**\n * Update anchor to [Texture's defaultAnchor]{@link Texture#defaultAnchor} when frame changes.\n *\n * Useful with [sprite sheet animations]{@link Spritesheet#animations} created with tools.\n * Changing anchor for each frame allows to pin sprite origin to certain moving feature\n * of the frame (e.g. left foot).\n *\n * > [!NOTE] Enabling this will override any previously set `anchor` on each frame change.\n * @default false\n */\n public updateAnchor: boolean;\n\n /**\n * User-assigned function to call when an AnimatedSprite finishes playing.\n *\n * This function is called when the animation reaches the end and stops playing.\n * If the animation is set to loop, this function will not be called.\n * @example\n * ```ts\n * animation.onComplete = () => {\n * // Finished!\n * };\n * ```\n */\n public onComplete?: () => void;\n\n /**\n * User-assigned function to call when an AnimatedSprite changes which texture is being rendered.\n *\n * This function is called every time the current frame changes during playback.\n * It receives the current frame index as an argument.\n * @example\n * animation.onFrameChange = () => {\n * // Updated!\n * };\n */\n public onFrameChange?: (currentFrame: number) => void;\n\n /**\n * User-assigned function to call when `loop` is true, and an AnimatedSprite is played and\n * loops around to start again.\n * @example\n * animation.onLoop = () => {\n * // Looped!\n * };\n */\n public onLoop?: () => void;\n\n private _playing: boolean;\n private _textures: Texture[];\n private _durations: number[];\n\n /**\n * `true` uses Ticker.shared to auto update animation time.\n * @default true\n */\n private _autoUpdate: boolean;\n\n /**\n * `true` if the instance is currently connected to Ticker.shared to auto update animation time.\n * @default false\n */\n private _isConnectedToTicker: boolean;\n\n /** Elapsed time since animation has been started, used internally to display current texture. */\n private _currentTime: number;\n\n /** The texture index that was displayed last time. */\n private _previousFrame: number;\n\n /**\n * @param frames - Collection of textures or frames to use.\n * @param autoUpdate - Whether to use Ticker.shared to auto update animation time.\n */\n constructor(frames: AnimatedSpriteFrames, autoUpdate?: boolean);\n /**\n * @param options - The options for the AnimatedSprite.\n */\n constructor(options: AnimatedSpriteOptions);\n /** @ignore */\n constructor(...args: [AnimatedSpriteOptions?] | [AnimatedSpriteFrames?] | [AnimatedSpriteFrames?, boolean?])\n {\n let options = args[0] as AnimatedSpriteOptions;\n\n if (Array.isArray(args[0]))\n {\n options = {\n textures: args[0] as AnimatedSpriteFrames,\n autoUpdate: args[1] as boolean,\n };\n }\n\n const {\n animationSpeed = 1,\n autoPlay = false,\n autoUpdate = true,\n loop = true,\n onComplete = null,\n onFrameChange = null,\n onLoop = null,\n textures,\n updateAnchor = false,\n ...rest\n } = options;\n const [firstFrame] = textures;\n\n super({\n ...rest,\n texture: firstFrame instanceof Texture ? firstFrame : firstFrame.texture,\n });\n\n this._textures = null;\n this._durations = null;\n this._autoUpdate = autoUpdate;\n this._isConnectedToTicker = false;\n\n this.animationSpeed = animationSpeed;\n this.loop = loop;\n this.updateAnchor = updateAnchor;\n this.onComplete = onComplete;\n this.onFrameChange = onFrameChange;\n this.onLoop = onLoop;\n\n this._currentTime = 0;\n\n this._playing = false;\n this._previousFrame = null;\n\n this.textures = textures;\n\n if (autoPlay)\n {\n this.play();\n }\n }\n\n /**\n * Stops the animation playback and freezes the current frame.\n * Does not reset the current frame or animation progress.\n * @example\n * ```ts\n * // Create an animated sprite\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png')\n * ],\n * autoPlay: true\n * });\n *\n * // Stop at current frame\n * sprite.stop();\n *\n * // Stop at specific frame\n * sprite.gotoAndStop(1); // Stops at second frame\n *\n * // Stop and reset\n * sprite.stop();\n * sprite.currentFrame = 0;\n *\n * // Stop with completion check\n * if (sprite.playing) {\n * sprite.stop();\n * sprite.onComplete?.();\n * }\n * ```\n * @see {@link AnimatedSprite#play} For starting playback\n * @see {@link AnimatedSprite#gotoAndStop} For stopping at a specific frame\n * @see {@link AnimatedSprite#playing} For checking play state\n */\n public stop(): void\n {\n if (!this._playing)\n {\n return;\n }\n\n this._playing = false;\n if (this._autoUpdate && this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.update, this);\n this._isConnectedToTicker = false;\n }\n }\n\n /**\n * Starts or resumes the animation playback.\n * If the animation was previously stopped, it will continue from where it left off.\n * @example\n * ```ts\n * // Basic playback\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * ],\n * autoPlay: false\n * });\n * sprite.play();\n *\n * // Play after stopping\n * sprite.stop();\n * sprite.currentFrame = 0; // Reset to start\n * sprite.play(); // Play from beginning\n *\n * // Play with auto-update disabled\n * sprite.autoUpdate = false;\n * sprite.play();\n * app.ticker.add(() => {\n * sprite.update(app.ticker); // Manual updates\n * });\n * ```\n * @see {@link AnimatedSprite#stop} For stopping playback\n * @see {@link AnimatedSprite#gotoAndPlay} For playing from a specific frame\n * @see {@link AnimatedSprite#playing} For checking play state\n */\n public play(): void\n {\n if (this._playing)\n {\n return;\n }\n\n this._playing = true;\n if (this._autoUpdate && !this._isConnectedToTicker)\n {\n Ticker.shared.add(this.update, this, UPDATE_PRIORITY.HIGH);\n this._isConnectedToTicker = true;\n }\n }\n\n /**\n * Stops the AnimatedSprite and sets it to a specific frame.\n * @example\n * ```ts\n * // Create an animated sprite\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png'),\n * ]\n * });\n *\n * // Go to specific frames\n * sprite.gotoAndStop(0); // First frame\n * sprite.gotoAndStop(2); // Third frame\n *\n * // Jump to last frame\n * sprite.gotoAndStop(sprite.totalFrames - 1);\n * ```\n * @param frameNumber - Frame index to stop at (0-based)\n * @throws {Error} If frameNumber is out of bounds\n * @see {@link AnimatedSprite#gotoAndPlay} For going to a frame and playing\n * @see {@link AnimatedSprite#currentFrame} For getting/setting current frame\n * @see {@link AnimatedSprite#totalFrames} For total number of frames\n */\n public gotoAndStop(frameNumber: number): void\n {\n this.stop();\n this.currentFrame = frameNumber;\n }\n\n /**\n * Goes to a specific frame and begins playing the AnimatedSprite from that point.\n * Combines frame navigation and playback start in one operation.\n * @example\n * ```ts\n * // Start from specific frame\n * sprite.gotoAndPlay(1); // Starts playing from second frame\n * ```\n * @param frameNumber - Frame index to start playing from (0-based)\n * @throws {Error} If frameNumber is out of bounds\n * @see {@link AnimatedSprite#gotoAndStop} For going to a frame without playing\n * @see {@link AnimatedSprite#play} For playing from current frame\n * @see {@link AnimatedSprite#currentFrame} For getting/setting current frame\n */\n public gotoAndPlay(frameNumber: number): void\n {\n this.currentFrame = frameNumber;\n this.play();\n }\n\n /**\n * Updates the object transform for rendering. This method handles animation timing, frame updates,\n * and manages looping behavior.\n * @example\n * ```ts\n * // Create an animated sprite with manual updates\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('frame1.png'),\n * Texture.from('frame2.png'),\n * Texture.from('frame3.png')\n * ],\n * autoUpdate: false // Disable automatic updates\n * });\n *\n * // Manual update with app ticker\n * app.ticker.add((ticker) => {\n * sprite.update(ticker);\n * });\n * ```\n * @param ticker - The ticker to use for updating the animation timing\n * @see {@link AnimatedSprite#autoUpdate} For controlling automatic updates\n * @see {@link AnimatedSprite#animationSpeed} For controlling animation speed\n * @see {@link Ticker} For timing system details\n */\n public update(ticker: Ticker): void\n {\n // If the animation isn't playing, no update is needed.\n if (!this._playing)\n {\n return;\n }\n\n // Calculate elapsed time based on ticker's deltaTime and animation speed.\n const deltaTime = ticker.deltaTime;\n const elapsed = this.animationSpeed * deltaTime;\n const previousFrame = this.currentFrame;\n\n // If there are specific durations set for each frame:\n if (this._durations !== null)\n {\n // Calculate the lag for the current frame based on the current time.\n let lag = this._currentTime % 1 * this._durations[this.currentFrame];\n\n // Adjust the lag based on elapsed time.\n lag += elapsed / 60 * 1000;\n\n // If the lag is negative, adjust the current time and the lag.\n while (lag < 0)\n {\n this._currentTime--;\n lag += this._durations[this.currentFrame];\n }\n\n const sign = Math.sign(this.animationSpeed * deltaTime);\n\n // Floor the current time to get a whole number frame.\n this._currentTime = Math.floor(this._currentTime);\n\n // Adjust the current time and the lag until the lag is less than the current frame's duration.\n while (lag >= this._durations[this.currentFrame])\n {\n lag -= this._durations[this.currentFrame] * sign;\n this._currentTime += sign;\n }\n\n // Adjust the current time based on the lag and current frame's duration.\n this._currentTime += lag / this._durations[this.currentFrame];\n }\n else\n {\n // If no specific durations set, simply adjust the current time by elapsed time.\n this._currentTime += elapsed;\n }\n\n // Handle scenarios when animation reaches the start or the end.\n if (this._currentTime < 0 && !this.loop)\n {\n // If the animation shouldn't loop and it reaches the start, go to the first frame.\n this.gotoAndStop(0);\n\n // If there's an onComplete callback, call it.\n if (this.onComplete)\n {\n this.onComplete();\n }\n }\n else if (this._currentTime >= this._textures.length && !this.loop)\n {\n // If the animation shouldn't loop and it reaches the end, go to the last frame.\n this.gotoAndStop(this._textures.length - 1);\n\n // If there's an onComplete callback, call it.\n if (this.onComplete)\n {\n this.onComplete();\n }\n }\n else if (previousFrame !== this.currentFrame)\n {\n // If the current frame is different from the last update, handle loop scenarios.\n if (this.loop && this.onLoop)\n {\n if ((this.animationSpeed > 0 && this.currentFrame < previousFrame)\n || (this.animationSpeed < 0 && this.currentFrame > previousFrame))\n {\n // If the animation loops, and there's an onLoop callback, call it.\n this.onLoop();\n }\n }\n\n // Update the texture for the current frame.\n this._updateTexture();\n }\n }\n\n /** Updates the displayed texture to match the current frame index. */\n private _updateTexture(): void\n {\n const currentFrame = this.currentFrame;\n\n if (this._previousFrame === currentFrame)\n {\n return;\n }\n\n this._previousFrame = currentFrame;\n\n this.texture = this._textures[currentFrame];\n\n if (this.updateAnchor && this.texture.defaultAnchor)\n {\n this.anchor.copyFrom(this.texture.defaultAnchor);\n }\n\n if (this.onFrameChange)\n {\n this.onFrameChange(this.currentFrame);\n }\n }\n\n /**\n * Stops the AnimatedSprite and destroys it.\n * @example\n * ```ts\n * // Destroy the sprite when done\n * sprite.destroy();\n * ```\n */\n public destroy(): void\n {\n this.stop();\n super.destroy();\n\n this.onComplete = null;\n this.onFrameChange = null;\n this.onLoop = null;\n }\n\n /**\n * A short hand way of creating an AnimatedSprite from an array of frame ids.\n * Uses texture frames from the cache to create an animation sequence.\n * @example\n * ```ts\n * // Create from frame IDs\n * const frameIds = [\n * 'walk_001.png',\n * 'walk_002.png',\n * 'walk_003.png'\n * ];\n *\n * const walkingAnimation = AnimatedSprite.fromFrames(frameIds);\n * walkingAnimation.play();\n * ```\n * @param frames - The array of frame ids to use for the animation\n * @returns A new animated sprite using the frames\n * @see {@link Texture.from} For texture creation from frames\n * @see {@link Spritesheet} For loading spritesheets\n */\n public static fromFrames(frames: string[]): AnimatedSprite\n {\n const textures = [];\n\n for (let i = 0; i < frames.length; ++i)\n {\n textures.push(Texture.from(frames[i]));\n }\n\n return new AnimatedSprite(textures);\n }\n\n /**\n * A short hand way of creating an AnimatedSprite from an array of image urls.\n * Each image will be used as a frame in the animation.\n * @example\n * ```ts\n * // Create from image URLs\n * const images = [\n * 'assets/walk1.png',\n * 'assets/walk2.png',\n * 'assets/walk3.png'\n * ];\n *\n * const walkingSprite = AnimatedSprite.fromImages(images);\n * walkingSprite.play();\n * ```\n * @param images - The array of image urls to use as frames\n * @returns A new animated sprite using the images as frames\n * @see {@link Assets} For asset loading and management\n * @see {@link Texture.from} For texture creation from images\n */\n public static fromImages(images: string[]): AnimatedSprite\n {\n const textures = [];\n\n for (let i = 0; i < images.length; ++i)\n {\n textures.push(Texture.from(images[i]));\n }\n\n return new AnimatedSprite(textures);\n }\n\n /**\n * The total number of frames in the AnimatedSprite. This is the same as number of textures\n * assigned to the AnimatedSprite.\n * @example\n * ```ts\n * // Create an animated sprite\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('frame1.png'),\n * Texture.from('frame2.png'),\n * Texture.from('frame3.png')\n * ]\n * });\n *\n * // Get total frames\n * console.log(sprite.totalFrames); // Outputs: 3\n *\n * // Use with frame navigation\n * sprite.gotoAndStop(sprite.totalFrames - 1); // Go to last frame\n * ```\n * @readonly\n * @see {@link AnimatedSprite#currentFrame} For the current frame index\n * @see {@link AnimatedSprite#textures} For the array of textures\n * @returns {number} The total number of frames\n */\n get totalFrames(): number\n {\n return this._textures.length;\n }\n\n /**\n * The array of textures or frame objects used for the animation sequence.\n * Can be set to either an array of Textures or an array of FrameObjects with custom timing.\n * @example\n * ```ts\n * // Update textures at runtime\n * sprite.textures = [\n * Texture.from('run1.png'),\n * Texture.from('run2.png')\n * ];\n *\n * // Use custom frame timing\n * sprite.textures = [\n * { texture: Texture.from('explosion1.png'), time: 100 },\n * { texture: Texture.from('explosion2.png'), time: 200 },\n * { texture: Texture.from('explosion3.png'), time: 300 }\n * ];\n *\n * // Use with spritesheet\n * const sheet = await Assets.load('animations.json');\n * sprite.textures = sheet.animations['walk'];\n * ```\n * @type {AnimatedSpriteFrames}\n * @see {@link FrameObject} For frame timing options\n * @see {@link Spritesheet} For loading from spritesheets\n */\n get textures(): AnimatedSpriteFrames\n {\n return this._textures;\n }\n\n set textures(value: AnimatedSpriteFrames)\n {\n if (value[0] instanceof Texture)\n {\n this._textures = value as Texture[];\n this._durations = null;\n }\n else\n {\n this._textures = [];\n this._durations = [];\n\n for (let i = 0; i < value.length; i++)\n {\n this._textures.push((value[i] as FrameObject).texture);\n this._durations.push((value[i] as FrameObject).time);\n }\n }\n this._previousFrame = null;\n this.gotoAndStop(0);\n this._updateTexture();\n }\n\n /**\n * Gets or sets the current frame index of the animation.\n * When setting, the value will be clamped between 0 and totalFrames - 1.\n * @example\n * ```ts\n * // Create an animated sprite\n * const sprite = new AnimatedSprite({\n * textures: [\n * Texture.from('walk1.png'),\n * Texture.from('walk2.png'),\n * Texture.from('walk3.png')\n * ]\n * });\n *\n * // Get current frame\n * console.log(sprite.currentFrame); // 0\n *\n * // Set specific frame\n * sprite.currentFrame = 1; // Show second frame\n *\n * // Use with frame callbacks\n * sprite.onFrameChange = (frame) => {\n * console.log(`Now showing frame: ${frame}`);\n * };\n * sprite.currentFrame = 2;\n * ```\n * @throws {Error} If attempting to set a frame index out of bounds\n * @see {@link AnimatedSprite#totalFrames} For the total number of frames\n * @see {@link AnimatedSprite#gotoAndPlay} For playing from a specific frame\n * @see {@link AnimatedSprite#gotoAndStop} For stopping at a specific frame\n */\n get currentFrame(): number\n {\n let currentFrame = Math.floor(this._currentTime) % this._textures.length;\n\n if (currentFrame < 0)\n {\n currentFrame += this._textures.length;\n }\n\n return currentFrame;\n }\n\n set currentFrame(value: number)\n {\n if (value < 0 || value > this.totalFrames - 1)\n {\n throw new Error(`[AnimatedSprite]: Invalid frame index value ${value}, `\n + `expected to be between 0 and totalFrames ${this.totalFrames}.`);\n }\n\n const previousFrame = this.currentFrame;\n\n this._currentTime = value;\n\n if (previousFrame !== this.currentFrame)\n {\n this._updateTexture();\n }\n }\n\n /**\n * Indicates if the AnimatedSprite is currently playing.\n * This is a read-only property that reflects the current playback state.\n * @example\n * ```ts\n * // Check if animation is playing\n * console.log('Playing:', sprite.playing); // true\n *\n * // Use with play control\n * if (!sprite.playing) {\n * sprite.play();\n * }\n * ```\n * @readonly\n * @returns {boolean} True if the animation is currently playing\n * @see {@link AnimatedSprite#play} For starting playback\n * @see {@link AnimatedSprite#stop} For stopping playback\n * @see {@link AnimatedSprite#loop} For controlling looping behavior\n */\n get playing(): boolean\n {\n return this._playing;\n }\n\n /**\n * Controls whether the animation automatically updates using the shared ticker.\n * When enabled, the animation will update on each frame. When disabled, you must\n * manually call update() to advance the animation.\n * @example\n * ```ts\n * // Create sprite with auto-update disabled\n * const sprite = new AnimatedSprite({\n * textures: [],\n * autoUpdate: false\n * });\n *\n * // Manual update with app ticker\n * app.ticker.add((ticker) => {\n * sprite.update(ticker);\n * });\n *\n * // Enable auto-update later\n * sprite.autoUpdate = true;\n * ```\n * @default true\n * @see {@link AnimatedSprite#update} For manual animation updates\n * @see {@link Ticker} For the timing system\n */\n get autoUpdate(): boolean\n {\n return this._autoUpdate;\n }\n\n set autoUpdate(value: boolean)\n {\n if (value !== this._autoUpdate)\n {\n this._autoUpdate = value;\n\n if (!this._autoUpdate && this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.update, this);\n this._isConnectedToTicker = false;\n }\n else if (this._autoUpdate && !this._isConnectedToTicker && this._playing)\n {\n Ticker.shared.add(this.update, this);\n this._isConnectedToTicker = true;\n }\n }\n }\n}\n\n/**\n * A reference to a frame in an {@link AnimatedSprite}\n * @category scene\n * @advanced\n */\nexport interface FrameObject\n{\n /** The {@link Texture} of the frame. */\n texture: Texture;\n\n /** The duration of the frame, in milliseconds. */\n time: number;\n}\n"],"names":[],"mappings":"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"}