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">
416 lines (413 loc) • 14.5 kB
JavaScript
import { Bounds } from '../../container/bounds/Bounds.mjs';
import { ViewContainer } from '../../view/ViewContainer.mjs';
import { particleData } from './particleData.mjs';
;
const emptyBounds = new Bounds(0, 0, 0, 0);
const _ParticleContainer = class _ParticleContainer extends ViewContainer {
/**
* @param options - The options for creating the sprite.
*/
constructor(options = {}) {
options = {
..._ParticleContainer.defaultOptions,
...options,
dynamicProperties: {
..._ParticleContainer.defaultOptions.dynamicProperties,
...options?.dynamicProperties
}
};
const { dynamicProperties, shader, roundPixels, texture, particles, ...rest } = options;
super({
label: "ParticleContainer",
...rest
});
/**
* The unique identifier for the render pipe of this ParticleContainer.
* @internal
*/
this.renderPipeId = "particle";
/** @internal */
this.batched = false;
/**
* Indicates if the children of this ParticleContainer have changed and need to be updated.
* @internal
*/
this._childrenDirty = false;
this.texture = texture || null;
this.shader = shader;
this._properties = {};
for (const key in particleData) {
const property = particleData[key];
const dynamic = dynamicProperties[key];
this._properties[key] = {
...property,
dynamic
};
}
this.allowChildren = true;
this.roundPixels = roundPixels ?? false;
this.particleChildren = particles ?? [];
}
/**
* Adds one or more particles to the container. The particles will be rendered using the container's shared texture
* and properties. When adding multiple particles, they must all share the same base texture.
* @example
* ```ts
* const container = new ParticleContainer();
*
* // Add a single particle
* const particle = new Particle(Assets.get('particleTexture'));
* container.addParticle(particle);
*
* // Add multiple particles at once
* const particles = [
* new Particle(Assets.get('particleTexture')),
* new Particle(Assets.get('particleTexture')),
* new Particle(Assets.get('particleTexture'))
* ];
*
* container.addParticle(...particles);
* ```
* @param children - The Particle(s) to add to the container
* @returns The first particle that was added, for method chaining
* @see {@link ParticleContainer#texture} For setting the shared texture
* @see {@link ParticleContainer#update} For updating after modifications
*/
addParticle(...children) {
for (let i = 0; i < children.length; i++) {
this.particleChildren.push(children[i]);
}
this.onViewUpdate();
return children[0];
}
/**
* Removes one or more particles from the container. The particles must already be children
* of this container to be removed.
* @example
* ```ts
* // Remove a single particle
* container.removeParticle(particle1);
*
* // Remove multiple particles at once
* container.removeParticle(particle2, particle3);
* ```
* @param children - The Particle(s) to remove from the container
* @returns The first particle that was removed, for method chaining
* @see {@link ParticleContainer#particleChildren} For accessing all particles
* @see {@link ParticleContainer#removeParticles} For removing particles by index
* @see {@link ParticleContainer#removeParticleAt} For removing a particle at a specific index
*/
removeParticle(...children) {
let didRemove = false;
for (let i = 0; i < children.length; i++) {
const index = this.particleChildren.indexOf(children[i]);
if (index > -1) {
this.particleChildren.splice(index, 1);
didRemove = true;
}
}
if (didRemove)
this.onViewUpdate();
return children[0];
}
/**
* Updates the particle container's internal state. Call this method after manually modifying
* the particleChildren array or when changing static properties of particles.
* @example
* ```ts
* // Batch modify particles
* container.particleChildren.push(...particles);
* container.update(); // Required after direct array modification
*
* // Update static properties
* container.particleChildren.forEach(particle => {
* particle.position.set(
* Math.random() * 800,
* Math.random() * 600
* );
* });
* container.update(); // Required after changing static positions
* ```
* @see {@link ParticleProperties} For configuring dynamic vs static properties
* @see {@link ParticleContainer#particleChildren} For direct array access
*/
update() {
this._childrenDirty = true;
}
onViewUpdate() {
this._childrenDirty = true;
super.onViewUpdate();
}
/**
* Returns a static empty bounds object since ParticleContainer does not calculate bounds automatically
* for performance reasons. Use the `boundsArea` property to manually set container bounds.
* @example
* ```ts
* const container = new ParticleContainer({
* texture: Texture.from('particle.png')
* });
*
* // Default bounds are empty
* console.log(container.bounds); // Bounds(0, 0, 0, 0)
*
* // Set manual bounds for the particle area
* container.boundsArea = {
* minX: 0,
* minY: 0,
* maxX: 800,
* maxY: 600
* };
* ```
* @readonly
* @returns {Bounds} An empty bounds object (0,0,0,0)
* @see {@link Container#boundsArea} For manually setting container bounds
* @see {@link Bounds} For bounds object structure
*/
get bounds() {
return emptyBounds;
}
/** @private */
updateBounds() {
}
/**
* 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
* particleContainer.destroy();
* particleContainer.destroy(true);
* particleContainer.destroy({ texture: true, textureSource: true, children: 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;
const texture = this.texture ?? this.particleChildren[0]?.texture;
if (texture) {
texture.destroy(destroyTextureSource);
}
}
this.texture = null;
this.shader?.destroy();
}
/**
* Removes all particles from this container that are within the begin and end indexes.
* @param beginIndex - The beginning position.
* @param endIndex - The ending position. Default value is size of the container.
* @returns - List of removed particles
*/
removeParticles(beginIndex, endIndex) {
beginIndex ?? (beginIndex = 0);
endIndex ?? (endIndex = this.particleChildren.length);
const children = this.particleChildren.splice(
beginIndex,
endIndex - beginIndex
);
this.onViewUpdate();
return children;
}
/**
* Removes a particle from the specified index position.
* @param index - The index to get the particle from
* @returns The particle that was removed.
*/
removeParticleAt(index) {
const child = this.particleChildren.splice(index, 1);
this.onViewUpdate();
return child[0];
}
/**
* Adds a particle to the container at a specified index. If the index is out of bounds an error will be thrown.
* If the particle is already in this container, it will be moved to the specified index.
* @param {Container} child - The particle to add.
* @param {number} index - The absolute index where the particle will be positioned at the end of the operation.
* @returns {Container} The particle that was added.
*/
addParticleAt(child, index) {
this.particleChildren.splice(index, 0, child);
this.onViewUpdate();
return child;
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.addParticle()` instead.
* @param {...any} _children
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
addChild(..._children) {
throw new Error(
"ParticleContainer.addChild() is not available. Please use ParticleContainer.addParticle()"
);
}
/**
* This method is not available in ParticleContainer.
* Calling this method will throw an error. Please use `ParticleContainer.removeParticle()` instead.
* @param {...any} _children
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
removeChild(..._children) {
throw new Error(
"ParticleContainer.removeChild() is not available. Please use ParticleContainer.removeParticle()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.removeParticles()` instead.
* @param {number} [_beginIndex]
* @param {number} [_endIndex]
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
removeChildren(_beginIndex, _endIndex) {
throw new Error(
"ParticleContainer.removeChildren() is not available. Please use ParticleContainer.removeParticles()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.removeParticleAt()` instead.
* @param {number} _index
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
removeChildAt(_index) {
throw new Error(
"ParticleContainer.removeChildAt() is not available. Please use ParticleContainer.removeParticleAt()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.getParticleAt()` instead.
* @param {number} _index
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
getChildAt(_index) {
throw new Error(
"ParticleContainer.getChildAt() is not available. Please use ParticleContainer.getParticleAt()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.setParticleIndex()` instead.
* @param {ContainerChild} _child
* @param {number} _index
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
setChildIndex(_child, _index) {
throw new Error(
"ParticleContainer.setChildIndex() is not available. Please use ParticleContainer.setParticleIndex()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.getParticleIndex()` instead.
* @param {ContainerChild} _child
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
getChildIndex(_child) {
throw new Error(
"ParticleContainer.getChildIndex() is not available. Please use ParticleContainer.getParticleIndex()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.addParticleAt()` instead.
* @param {ContainerChild} _child
* @param {number} _index
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
addChildAt(_child, _index) {
throw new Error(
"ParticleContainer.addChildAt() is not available. Please use ParticleContainer.addParticleAt()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error. Please use `ParticleContainer.swapParticles()` instead.
* @param {ContainerChild} _child
* @param {ContainerChild} _child2
* @ignore
*/
swapChildren(_child, _child2) {
throw new Error(
"ParticleContainer.swapChildren() is not available. Please use ParticleContainer.swapParticles()"
);
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error.
* @param _child - The child to reparent
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
reparentChild(..._child) {
throw new Error("ParticleContainer.reparentChild() is not available with the particle container");
}
/**
* This method is not available in ParticleContainer.
*
* Calling this method will throw an error.
* @param _child - The child to reparent
* @param _index - The index to reparent the child to
* @throws {Error} Always throws an error as this method is not available.
* @ignore
*/
reparentChildAt(_child, _index) {
throw new Error("ParticleContainer.reparentChildAt() is not available with the particle container");
}
};
/**
* Defines the default options for creating a ParticleContainer.
* @example
* ```ts
* // Change defaults globally
* ParticleContainer.defaultOptions = {
* dynamicProperties: {
* position: true, // Update positions each frame
* rotation: true, // Update rotations each frame
* vertex: false, // Static vertices
* uvs: false, // Static texture coordinates
* color: false // Static colors
* },
* roundPixels: true // Enable pixel rounding for crisp rendering
* };
* ```
* @property {Record<string, boolean>} dynamicProperties - Specifies which properties are dynamic.
* @property {boolean} roundPixels - Indicates if pixels should be rounded.
*/
_ParticleContainer.defaultOptions = {
/** Specifies which properties are dynamic. */
dynamicProperties: {
/** Indicates if vertex positions are dynamic. */
vertex: false,
/** Indicates if particle positions are dynamic. */
position: true,
/** Indicates if particle rotations are dynamic. */
rotation: false,
/** Indicates if UV coordinates are dynamic. */
uvs: false,
/** Indicates if particle colors are dynamic. */
color: false
},
/** Indicates if pixels should be rounded for rendering. */
roundPixels: false
};
let ParticleContainer = _ParticleContainer;
export { ParticleContainer };
//# sourceMappingURL=ParticleContainer.mjs.map