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">

341 lines (338 loc) 11.4 kB
import { ObservablePoint } from '../../maths/point/ObservablePoint.mjs'; import { Texture } from '../../rendering/renderers/shared/texture/Texture.mjs'; import { updateQuadBounds } from '../../utils/data/updateQuadBounds.mjs'; import { deprecation } from '../../utils/logging/deprecation.mjs'; import { ViewContainer } from '../view/ViewContainer.mjs'; "use strict"; class Sprite extends ViewContainer { /** * @param options - The options for creating the sprite. */ constructor(options = Texture.EMPTY) { if (options instanceof Texture) { options = { texture: options }; } const { texture = Texture.EMPTY, anchor, roundPixels, width, height, ...rest } = options; super({ label: "Sprite", ...rest }); /** @internal */ this.renderPipeId = "sprite"; /** @internal */ this.batched = true; this._visualBounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; this._anchor = new ObservablePoint( { _onUpdate: () => { this.onViewUpdate(); } } ); if (anchor) { this.anchor = anchor; } else if (texture.defaultAnchor) { this.anchor = texture.defaultAnchor; } this.texture = texture; this.allowChildren = false; this.roundPixels = roundPixels ?? false; if (width !== void 0) this.width = width; if (height !== void 0) this.height = height; } /** * Creates a new sprite based on a source texture, image, video, or canvas element. * This is a convenience method that automatically creates and manages textures. * @example * ```ts * // Create from path or URL * const sprite = Sprite.from('assets/image.png'); * * // Create from existing texture * const sprite = Sprite.from(texture); * * // Create from canvas * const canvas = document.createElement('canvas'); * const sprite = Sprite.from(canvas, true); // Skip caching new texture * ``` * @param source - The source to create the sprite from. Can be a path to an image, a texture, * or any valid texture source (canvas, video, etc.) * @param skipCache - Whether to skip adding to the texture cache when creating a new texture * @returns A new sprite based on the source * @see {@link Texture.from} For texture creation details * @see {@link Assets} For asset loading and management */ static from(source, skipCache = false) { if (source instanceof Texture) { return new Sprite(source); } return new Sprite(Texture.from(source, skipCache)); } set texture(value) { value || (value = Texture.EMPTY); const currentTexture = this._texture; if (currentTexture === value) return; if (currentTexture && currentTexture.dynamic) currentTexture.off("update", this.onViewUpdate, this); if (value.dynamic) value.on("update", this.onViewUpdate, this); this._texture = value; if (this._width) { this._setWidth(this._width, this._texture.orig.width); } if (this._height) { this._setHeight(this._height, this._texture.orig.height); } this.onViewUpdate(); } /** * The texture that is displayed by the sprite. When changed, automatically updates * the sprite dimensions and manages texture event listeners. * @example * ```ts * // Create sprite with texture * const sprite = new Sprite({ * texture: Texture.from('sprite.png') * }); * * // Update texture * sprite.texture = Texture.from('newSprite.png'); * * // Use texture from spritesheet * const sheet = await Assets.load('spritesheet.json'); * sprite.texture = sheet.textures['frame1.png']; * * // Reset to empty texture * sprite.texture = Texture.EMPTY; * ``` * @see {@link Texture} For texture creation and management * @see {@link Assets} For asset loading */ get texture() { return this._texture; } /** * The bounds of the sprite, taking into account the texture's trim area. * @example * ```ts * const texture = new Texture({ * source: new TextureSource({ width: 300, height: 300 }), * frame: new Rectangle(196, 66, 58, 56), * trim: new Rectangle(4, 4, 58, 56), * orig: new Rectangle(0, 0, 64, 64), * rotate: 2, * }); * const sprite = new Sprite(texture); * const visualBounds = sprite.visualBounds; * // console.log(visualBounds); // { minX: -4, maxX: 62, minY: -4, maxY: 60 } */ get visualBounds() { updateQuadBounds(this._visualBounds, this._anchor, this._texture); return this._visualBounds; } /** * @deprecated * @ignore */ get sourceBounds() { deprecation("8.6.1", "Sprite.sourceBounds is deprecated, use visualBounds instead."); return this.visualBounds; } /** @private */ updateBounds() { const anchor = this._anchor; const texture = this._texture; const bounds = this._bounds; const { width, height } = texture.orig; bounds.minX = -anchor._x * width; bounds.maxX = bounds.minX + width; bounds.minY = -anchor._y * height; bounds.maxY = bounds.minY + height; } /** * Destroys this sprite renderable and optionally its texture. * @param options - Options parameter. A boolean will act as if all options * have been set to that value * @example * sprite.destroy(); * sprite.destroy(true); * sprite.destroy({ texture: true, textureSource: true }); */ destroy(options = false) { super.destroy(options); const destroyTexture = typeof options === "boolean" ? options : options?.texture; if (destroyTexture) { const destroyTextureSource = typeof options === "boolean" ? options : options?.textureSource; this._texture.destroy(destroyTextureSource); } this._texture = null; this._visualBounds = null; this._bounds = null; this._anchor = null; this._gpuData = null; } /** * The anchor sets the origin point of the sprite. The default value is taken from the {@link Texture} * and passed to the constructor. * * - The default is `(0,0)`, this means the sprite's origin is the top left. * - Setting the anchor to `(0.5,0.5)` means the sprite's origin is centered. * - Setting the anchor to `(1,1)` would mean the sprite's origin point will be the bottom right corner. * * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. * @example * ```ts * // Center the anchor point * sprite.anchor = 0.5; // Sets both x and y to 0.5 * sprite.position.set(400, 300); // Sprite will be centered at this position * * // Set specific x/y anchor points * sprite.anchor = { * x: 1, // Right edge * y: 0 // Top edge * }; * * // Using individual coordinates * sprite.anchor.set(0.5, 1); // Center-bottom * * // For rotation around center * sprite.anchor.set(0.5); * sprite.rotation = Math.PI / 4; // 45 degrees around center * * // For scaling from center * sprite.anchor.set(0.5); * sprite.scale.set(2); // Scales from center point * ``` */ get anchor() { return this._anchor; } set anchor(value) { typeof value === "number" ? this._anchor.set(value) : this._anchor.copyFrom(value); } /** * The width of the sprite, setting this will actually modify the scale to achieve the value set. * @example * ```ts * // Set width directly * sprite.width = 200; * console.log(sprite.scale.x); // Scale adjusted to match width * * // Set width while preserving aspect ratio * const ratio = sprite.height / sprite.width; * sprite.width = 300; * sprite.height = 300 * ratio; * * // For better performance when setting both width and height * sprite.setSize(300, 400); // Avoids recalculating bounds twice * * // Reset to original texture size * sprite.width = sprite.texture.orig.width; * ``` */ get width() { return Math.abs(this.scale.x) * this._texture.orig.width; } set width(value) { this._setWidth(value, this._texture.orig.width); this._width = value; } /** * The height of the sprite, setting this will actually modify the scale to achieve the value set. * @example * ```ts * // Set height directly * sprite.height = 150; * console.log(sprite.scale.y); // Scale adjusted to match height * * // Set height while preserving aspect ratio * const ratio = sprite.width / sprite.height; * sprite.height = 200; * sprite.width = 200 * ratio; * * // For better performance when setting both width and height * sprite.setSize(300, 400); // Avoids recalculating bounds twice * * // Reset to original texture size * sprite.height = sprite.texture.orig.height; * ``` */ get height() { return Math.abs(this.scale.y) * this._texture.orig.height; } set height(value) { this._setHeight(value, this._texture.orig.height); this._height = value; } /** * Retrieves the size of the Sprite as a [Size]{@link Size} object based on the texture dimensions and scale. * This is faster than getting width and height separately as it only calculates the bounds once. * @example * ```ts * // Basic size retrieval * const sprite = new Sprite(Texture.from('sprite.png')); * const size = sprite.getSize(); * console.log(`Size: ${size.width}x${size.height}`); * * // Reuse existing size object * const reuseSize = { width: 0, height: 0 }; * sprite.getSize(reuseSize); * ``` * @param out - Optional object to store the size in, to avoid allocating a new object * @returns The size of the Sprite * @see {@link Sprite#width} For getting just the width * @see {@link Sprite#height} For getting just the height * @see {@link Sprite#setSize} For setting both width and height */ getSize(out) { out || (out = {}); out.width = Math.abs(this.scale.x) * this._texture.orig.width; out.height = Math.abs(this.scale.y) * this._texture.orig.height; return out; } /** * Sets the size of the Sprite to the specified width and height. * This is faster than setting width and height separately as it only recalculates bounds once. * @example * ```ts * // Basic size setting * const sprite = new Sprite(Texture.from('sprite.png')); * sprite.setSize(100, 200); // Width: 100, Height: 200 * * // Set uniform size * sprite.setSize(100); // Sets both width and height to 100 * * // Set size with object * sprite.setSize({ * width: 200, * height: 300 * }); * * // Reset to texture size * sprite.setSize( * sprite.texture.orig.width, * sprite.texture.orig.height * ); * ``` * @param value - This can be either a number or a {@link Size} object * @param height - The height to set. Defaults to the value of `width` if not provided * @see {@link Sprite#width} For setting width only * @see {@link Sprite#height} For setting height only * @see {@link Sprite#texture} For the source dimensions */ setSize(value, height) { if (typeof value === "object") { height = value.height ?? value.width; value = value.width; } else { height ?? (height = value); } value !== void 0 && this._setWidth(value, this._texture.orig.width); height !== void 0 && this._setHeight(height, this._texture.orig.height); } } export { Sprite }; //# sourceMappingURL=Sprite.mjs.map