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">
343 lines (339 loc) • 11.6 kB
JavaScript
'use strict';
var ObservablePoint = require('../../maths/point/ObservablePoint.js');
var Texture = require('../../rendering/renderers/shared/texture/Texture.js');
var updateQuadBounds = require('../../utils/data/updateQuadBounds.js');
var deprecation = require('../../utils/logging/deprecation.js');
var ViewContainer = require('../view/ViewContainer.js');
"use strict";
class Sprite extends ViewContainer.ViewContainer {
/**
* @param options - The options for creating the sprite.
*/
constructor(options = Texture.Texture.EMPTY) {
if (options instanceof Texture.Texture) {
options = { texture: options };
}
const { texture = 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.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.Texture) {
return new Sprite(source);
}
return new Sprite(Texture.Texture.from(source, skipCache));
}
set texture(value) {
value || (value = Texture.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.updateQuadBounds(this._visualBounds, this._anchor, this._texture);
return this._visualBounds;
}
/**
* @deprecated
* @ignore
*/
get sourceBounds() {
deprecation.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);
}
}
exports.Sprite = Sprite;
//# sourceMappingURL=Sprite.js.map