{"version":3,"file":"ParticleContainer.mjs","sources":["../src/ParticleContainer.ts"],"sourcesContent":["import { BLEND_MODES, Color } from '@pixi/core';\nimport { Container } from '@pixi/display';\n\nimport type { BaseTexture, ColorSource, Renderer } from '@pixi/core';\nimport type { IDestroyOptions } from '@pixi/display';\nimport type { Sprite } from '@pixi/sprite';\nimport type { ParticleBuffer } from './ParticleBuffer';\n\nexport interface IParticleProperties\n{\n    vertices?: boolean;\n    position?: boolean;\n    rotation?: boolean;\n    uvs?: boolean;\n    tint?: boolean;\n    alpha?: boolean;\n    scale?: boolean;\n}\n\n/**\n * The ParticleContainer class is a really fast version of the Container built solely for speed,\n * so use when you need a lot of sprites or particles.\n *\n * The tradeoff of the ParticleContainer is that most advanced functionality will not work.\n * ParticleContainer implements the basic object transform (position, scale, rotation)\n * and some advanced functionality like tint (as of v4.5.6).\n *\n * Other more advanced functionality like masking, children, filters, etc will not work on sprites in this batch.\n *\n * It's extremely easy to use. And here you have a hundred sprites that will be rendered at the speed of light.\n * @example\n * import { ParticleContainer, Sprite } from 'pixi.js';\n *\n * const container = new ParticleContainer();\n *\n * for (let i = 0; i < 100; ++i)\n * {\n *     let sprite = Sprite.from('myImage.png');\n *     container.addChild(sprite);\n * }\n * @memberof PIXI\n */\nexport class ParticleContainer<T extends Sprite = Sprite> extends Container<T>\n{\n    /**\n     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL`\n     * to reset the blend mode.\n     * @default PIXI.BLEND_MODES.NORMAL\n     */\n    public blendMode: BLEND_MODES;\n\n    /**\n     * If true, container allocates more batches in case there are more than `maxSize` particles.\n     * @default false\n     */\n    public autoResize: boolean;\n\n    /**\n     * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation.\n     * Advantages can include sharper image quality (like text) and faster rendering on canvas.\n     * The main disadvantage is movement of objects may appear less smooth.\n     * Default to true here as performance is usually the priority for particles.\n     * @default true\n     */\n    public roundPixels: boolean;\n\n    /**\n     * The texture used to render the children.\n     * @readonly\n     */\n    public baseTexture: BaseTexture;\n    public tintRgb: Float32Array;\n\n    /** @private */\n    _maxSize: number;\n\n    /** @private */\n    _buffers: ParticleBuffer[];\n\n    /** @private */\n    _batchSize: number;\n\n    /**\n     * Set properties to be dynamic (true) / static (false).\n     * @private\n     */\n    _properties: boolean[];\n\n    /**\n     * For every batch, stores _updateID corresponding to the last change in that batch.\n     * @private\n     */\n    _bufferUpdateIDs: number[];\n\n    /**\n     * When child inserted, removed or changes position this number goes up.\n     * @private\n     */\n    _updateID: number;\n\n    /**\n     * The tint applied to the container.\n     * This is a hex value. A value of 0xFFFFFF will remove any tint effect.\n     * @default 0xFFFFFF\n     */\n    private _tintColor: Color;\n\n    /**\n     * @param maxSize - The maximum number of particles that can be rendered by the container.\n     *  Affects size of allocated buffers.\n     * @param properties - The properties of children that should be uploaded to the gpu and applied.\n     * @param {boolean} [properties.vertices=false] - When true, vertices be uploaded and applied.\n     *                  if sprite's ` scale/anchor/trim/frame/orig` is dynamic, please set `true`.\n     * @param {boolean} [properties.position=true] - When true, position be uploaded and applied.\n     * @param {boolean} [properties.rotation=false] - When true, rotation be uploaded and applied.\n     * @param {boolean} [properties.uvs=false] - When true, uvs be uploaded and applied.\n     * @param {boolean} [properties.tint=false] - When true, alpha and tint be uploaded and applied.\n     * @param {number} [batchSize=16384] - Number of particles per batch. If less than maxSize, it uses maxSize instead.\n     * @param {boolean} [autoResize=false] - If true, container allocates more batches in case\n     *  there are more than `maxSize` particles.\n     */\n    constructor(maxSize = 1500, properties?: IParticleProperties, batchSize = 16384, autoResize = false)\n    {\n        super();\n\n        // Making sure the batch size is valid\n        // 65535 is max vertex index in the index buffer (see ParticleRenderer)\n        // so max number of particles is 65536 / 4 = 16384\n        const maxBatchSize = 16384;\n\n        if (batchSize > maxBatchSize)\n        {\n            batchSize = maxBatchSize;\n        }\n\n        this._properties = [false, true, false, false, false];\n        this._maxSize = maxSize;\n        this._batchSize = batchSize;\n        this._buffers = null;\n        this._bufferUpdateIDs = [];\n        this._updateID = 0;\n\n        this.interactiveChildren = false;\n        this.blendMode = BLEND_MODES.NORMAL;\n        this.autoResize = autoResize;\n        this.roundPixels = true;\n        this.baseTexture = null;\n\n        this.setProperties(properties);\n\n        this._tintColor = new Color(0);\n        this.tintRgb = new Float32Array(3);\n        this.tint = 0xFFFFFF;\n    }\n\n    /**\n     * Sets the private properties array to dynamic / static based on the passed properties object\n     * @param properties - The properties to be uploaded\n     */\n    public setProperties(properties: IParticleProperties): void\n    {\n        if (properties)\n        {\n            this._properties[0] = 'vertices' in properties || 'scale' in properties\n                ? !!properties.vertices || !!properties.scale : this._properties[0];\n            this._properties[1] = 'position' in properties ? !!properties.position : this._properties[1];\n            this._properties[2] = 'rotation' in properties ? !!properties.rotation : this._properties[2];\n            this._properties[3] = 'uvs' in properties ? !!properties.uvs : this._properties[3];\n            this._properties[4] = 'tint' in properties || 'alpha' in properties\n                ? !!properties.tint || !!properties.alpha : this._properties[4];\n        }\n    }\n\n    updateTransform(): void\n    {\n        // TODO don't need to!\n        this.displayObjectUpdateTransform();\n    }\n\n    /**\n     * The tint applied to the container. This is a hex value.\n     * A value of 0xFFFFFF will remove any tint effect.\n     * IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer.\n     * @default 0xFFFFFF\n     */\n    get tint(): ColorSource\n    {\n        return this._tintColor.value;\n    }\n\n    set tint(value: ColorSource)\n    {\n        this._tintColor.setValue(value);\n        this._tintColor.toRgbArray(this.tintRgb);\n    }\n\n    /**\n     * Renders the container using the WebGL renderer.\n     * @param renderer - The WebGL renderer.\n     */\n    public render(renderer: Renderer): void\n    {\n        if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable)\n        {\n            return;\n        }\n\n        if (!this.baseTexture)\n        {\n            this.baseTexture = this.children[0]._texture.baseTexture;\n            if (!this.baseTexture.valid)\n            {\n                this.baseTexture.once('update', () => this.onChildrenChange(0));\n            }\n        }\n\n        renderer.batch.setObjectRenderer(renderer.plugins.particle);\n        renderer.plugins.particle.render(this);\n    }\n\n    /**\n     * Set the flag that static data should be updated to true\n     * @param smallestChildIndex - The smallest child index.\n     */\n    protected onChildrenChange(smallestChildIndex: number): void\n    {\n        const bufferIndex = Math.floor(smallestChildIndex / this._batchSize);\n\n        while (this._bufferUpdateIDs.length < bufferIndex)\n        {\n            this._bufferUpdateIDs.push(0);\n        }\n        this._bufferUpdateIDs[bufferIndex] = ++this._updateID;\n    }\n\n    public dispose(): void\n    {\n        if (this._buffers)\n        {\n            for (let i = 0; i < this._buffers.length; ++i)\n            {\n                this._buffers[i].destroy();\n            }\n\n            this._buffers = null;\n        }\n    }\n\n    /**\n     * Destroys the container\n     * @param options - Options parameter. A boolean will act as if all options\n     *  have been set to that value\n     * @param {boolean} [options.children=false] - if set to true, all the children will have their\n     *  destroy method called as well. 'options' will be passed on to those calls.\n     * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true\n     *  Should it destroy the texture of the child sprite\n     * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true\n     *  Should it destroy the base texture of the child sprite\n     */\n    public destroy(options?: IDestroyOptions | boolean): void\n    {\n        super.destroy(options);\n\n        this.dispose();\n\n        this._properties = null;\n        this._buffers = null;\n        this._bufferUpdateIDs = null;\n    }\n}\n"],"names":[],"mappings":"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"}