{"version":3,"file":"dist/particle-emitter.min.js.map","names":["PropertyNode","constructor","value","time","ease","this","next","isStepped","generateEase","createList","data","array","list","node","first","hexToRGB","length","i","start","end","GetTextureFromString","Texture","from","verbose","DEG_TO_RADS","Math","PI","rotatePoint","angle","p","s","sin","c","cos","xnew","x","y","ynew","combineRGBComponents","r","g","b","point","sqrt","normalize","oneOverLen","Infinity","scaleBy","color","output","alpha","charAt","substr","indexOf","parseInt","a","segments","qty","oneOverQty","t","cp","e","getBlendMode","name","toUpperCase","replace","BLEND_MODES","NORMAL","BehaviorOrder","numSteps","currentNode","current","nextIndex","lerp","curVal","nextVal","Particle","Sprite","emitter","super","prevChild","nextChild","config","anchor","maxLife","age","agePercent","oneOverLife","prev","init","kill","rotation","position","scale","tint","visible","recycle","destroy","parent","removeChild","ticker","Ticker","shared","PositionParticle","Symbol","Emitter","registerBehavior","knownBehaviors","type","particleParent","initBehaviors","updateBehaviors","recycleBehaviors","minLifetime","maxLifetime","customEase","_frequency","spawnChance","maxParticles","emitterLifetime","spawnPos","Point","particlesPerWave","ownerPos","_prevEmitterPos","_prevPosIsValid","_posChanged","_parent","addAtBack","particleCount","_emit","_spawnTimer","_emitterLife","_activeParticlesFirst","_activeParticlesLast","_poolFirst","_origConfig","_autoUpdate","_destroyWhenComplete","_completeCallback","update","rotate","updateSpawnPos","updateOwnerPos","frequency","cleanup","lifetime","min","max","set","pos","copyFrom","emit","undefined","autoUpdate","behaviors","map","console","error","filter","push","sort","order","Spawn","slice","updateParticle","recycleParticle","getBehavior","find","fillPool","count","particle","fromCleanup","newRot","diff","resetPositionTracking","remove","add","playOnceAndDestroy","callback","playOnce","delta","elapsedMS","prevX","prevY","curX","curY","emitPosX","emitPosY","waveFirst","waveLast","len","random","addChildAt","addChild","behavior","initParticles","cb","emitNow","destroyed","Rectangle","w","h","getRandPos","editorConfig","Torus","radius","innerRadius","affectRotation","PolygonalChain","countingLengths","totalLength","Array","isArray","chain","prevPoint","j","second","p1","p2","l","segLength","out","rand","chosenSeg","AccelerationBehavior","Late","minStart","maxStart","accel","maxSpeed","_a","speed","velocity","deltaSec","vel","oldVX","oldVY","currentSpeed","atan2","intValueSimple","intColorSimple","intValueComplex","intColorComplex","intValueStepped","intColorStepped","PropertyList","isColor","interpolate","reset","AlphaBehavior","Normal","StaticAlphaBehavior","getTextures","textures","outTextures","tex","dupe","texture","RandomAnimatedTextureBehavior","anims","anim","framerate","parsedAnim","duration","loop","index","floor","animElapsed","animDuration","animFramerate","frame","EMPTY","SingleAnimatedTextureBehavior","BlendModeBehavior","blendMode","BurstSpawnBehavior","spacing","distance","ColorBehavior","StaticColorBehavior","OrderedTextureBehavior","helperPoint","MATH_FUNCS","WHITELISTER","RegExp","concat","join","PathBehavior","path","pathString","matches","match","Function","parsePath","minMult","initRotation","initPosition","movement","mult","speedMult","PointSpawnBehavior","_first","RandomTextureBehavior","RotationBehavior","minSpeed","rotSpeed","oldSpeed","StaticRotationBehavior","NoRotationBehavior","ScaleBehavior","scaleMult","StaticScaleBehavior","ShapeSpawnBehavior","registerShape","typeOverride","shapes","ShapeClass","Error","shape","SingleTextureBehavior","SpeedBehavior","StaticSpeedBehavior","LinkedListContainer","Container","_firstChild","_lastChild","_childCount","firstChild","lastChild","childCount","children","child","sortDirty","transform","_parentID","_boundsID","onChildrenChange","target","addChildBelow","relative","addChildAbove","swapChildren","child2","getChildIndex","test","setChildIndex","getChildAt","removeChildAt","removeChildren","beginIndex","endIndex","begin","range","removed","RangeError","updateTransform","worldAlpha","calculateBounds","_bounds","clear","_calculateBounds","renderable","_mask","maskObject","addBoundsMask","filterArea","addBoundsArea","addBounds","updateID","getLocalBounds","rect","skipChildrenUpdate","result","DisplayObject","prototype","call","render","renderer","filters","renderAdvanced","_render","batch","flush","mask","_enabledFilters","enabled","pop","renderCanvas","maskManager","pushMask","_renderCanvas","popMask","behaviors.AccelerationBehavior","behaviors.AlphaBehavior","behaviors.StaticAlphaBehavior","behaviors.RandomAnimatedTextureBehavior","behaviors.SingleAnimatedTextureBehavior","behaviors.BlendModeBehavior","behaviors.BurstSpawnBehavior","behaviors.ColorBehavior","behaviors.StaticColorBehavior","behaviors.OrderedTextureBehavior","behaviors.PathBehavior","behaviors.PointSpawnBehavior","behaviors.RandomTextureBehavior","behaviors.RotationBehavior","behaviors.StaticRotationBehavior","behaviors.NoRotationBehavior","behaviors.ScaleBehavior","behaviors.StaticScaleBehavior","behaviors.ShapeSpawnBehavior","behaviors.SingleTextureBehavior","behaviors.SpeedBehavior","behaviors.StaticSpeedBehavior","art","acceleration","minimumSpeedMultiplier","_b","noRotation","_c","extraData","_d","_e","_f","_g","_h","_j","minimumScaleMultiplier","_k","_l","rotationAcceleration","_m","rotationSpeed","_o","_p","_q","_r","startRotation","_s","_t","_u","_v","_w","orderedArt","spawnType","angleStart","particleSpacing","spawnCircle","minR","spawnRect","spawnPolygon"],"sources":["../src/PropertyNode.ts","../src/ParticleUtils.ts","../src/behaviors/Behaviors.ts","../src/Particle.ts","../src/Emitter.ts","../src/behaviors/shapes/Rectangle.ts","../src/behaviors/shapes/Torus.ts","../src/behaviors/shapes/PolygonalChain.ts","../src/behaviors/AccelerationMovement.ts","../src/PropertyList.ts","../src/behaviors/Alpha.ts","../src/behaviors/AnimatedTexture.ts","../src/behaviors/BlendMode.ts","../src/behaviors/BurstSpawn.ts","../src/behaviors/Color.ts","../src/behaviors/OrderedTexture.ts","../src/behaviors/PathMovement.ts","../src/behaviors/PointSpawn.ts","../src/behaviors/RandomTexture.ts","../src/behaviors/Rotation.ts","../src/behaviors/Scale.ts","../src/behaviors/ShapeSpawn.ts","../src/behaviors/SingleTexture.ts","../src/behaviors/SpeedMovement.ts","../src/LinkedListContainer.ts","../src/index.ts","../src/EmitterConfig.ts"],"sourcesContent":["import { generateEase, hexToRGB, EaseSegment, SimpleEase, Color } from './ParticleUtils';\nimport { BasicTweenable } from './EmitterConfig';\n\n/**\n * A single step of a ValueList.\n */\nexport interface ValueStep {\n /**\n * The color or number to use at this step.\n */\n value: T;\n /**\n * The percentage time of the particle's lifespan that this step happens at.\n * Values are between 0 and 1, inclusive.\n */\n time: number;\n}\n\n/**\n * Configuration for an interpolated or stepped list of numeric or color particle values.\n */\nexport interface ValueList {\n /**\n * The ordered list of values.\n */\n list: ValueStep[];\n /**\n * If the list is stepped. Stepped lists don't determine any in-between values, instead sticking with each value\n * until its time runs out.\n */\n isStepped?: boolean;\n /**\n * Easing that should be applied to this list, in order to alter how quickly the steps progress.\n */\n ease?: SimpleEase|EaseSegment[];\n}\n/**\n * A single node in a PropertyList.\n */\nexport class PropertyNode\n{\n /**\n * Value for the node.\n */\n public value: V;\n /**\n * Time value for the node. Between 0-1.\n */\n public time: number;\n /**\n * The next node in line.\n */\n public next: PropertyNode;\n /**\n * If this is the first node in the list, controls if the entire list is stepped or not.\n */\n public isStepped: boolean;\n public ease: SimpleEase;\n\n /**\n * @param value The value for this node\n * @param time The time for this node, between 0-1\n * @param [ease] Custom ease for this list. Only relevant for the first node.\n */\n constructor(value: V, time: number, ease?: SimpleEase|EaseSegment[])\n {\n this.value = value;\n this.time = time;\n this.next = null;\n this.isStepped = false;\n if (ease)\n {\n this.ease = typeof ease === 'function' ? ease : generateEase(ease);\n }\n else\n {\n this.ease = null;\n }\n }\n\n /**\n * Creates a list of property values from a data object {list, isStepped} with a list of objects in\n * the form {value, time}. Alternatively, the data object can be in the deprecated form of\n * {start, end}.\n * @param data The data for the list.\n * @param data.list The array of value and time objects.\n * @param data.isStepped If the list is stepped rather than interpolated.\n * @param data.ease Custom ease for this list.\n * @return The first node in the list\n */\n // eslint-disable-next-line max-len\n public static createList(data: ValueList|BasicTweenable): PropertyNode\n {\n if ('list' in data)\n {\n const array = data.list;\n let node;\n const { value, time } = array[0];\n\n // eslint-disable-next-line max-len\n const first = node = new PropertyNode(typeof value === 'string' ? hexToRGB(value) : value, time, data.ease);\n\n // only set up subsequent nodes if there are a bunch or the 2nd one is different from the first\n if (array.length > 2 || (array.length === 2 && array[1].value !== value))\n {\n for (let i = 1; i < array.length; ++i)\n {\n const { value, time } = array[i];\n\n node.next = new PropertyNode(typeof value === 'string' ? hexToRGB(value) : value, time);\n node = node.next;\n }\n }\n first.isStepped = !!data.isStepped;\n\n return first as PropertyNode;\n }\n\n // Handle deprecated version here\n const start = new PropertyNode(typeof data.start === 'string' ? hexToRGB(data.start) : data.start, 0);\n // only set up a next value if it is different from the starting value\n\n if (data.end !== data.start)\n {\n start.next = new PropertyNode(typeof data.end === 'string' ? hexToRGB(data.end) : data.end, 1);\n }\n\n return start as PropertyNode;\n }\n}\n","import { Texture } from '@pixi/core';\nimport { IPointData } from '@pixi/math';\nimport { BLEND_MODES } from '@pixi/constants';\nimport { PropertyNode, ValueStep } from './PropertyNode';\n\n/**\n * The method used by behaviors to fetch textures. Defaults to Texture.from.\n */\n// get Texture.from(), only supports V5 and V6 with individual packages\n// eslint-disable-next-line prefer-const\nexport let GetTextureFromString:(d:string) => Texture = Texture.from;\n\n/**\n * A color value, split apart for interpolation.\n */\nexport interface Color {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\nexport interface EaseSegment {\n cp: number;\n s: number;\n e: number;\n}\n\n/**\n * The basic easing function used. Takes in a value between 0-1, and outputs another value between 0-1.\n * For example, a basic quadratic in ease would be `(time) => time * time`\n */\nexport type SimpleEase = (time: number) => number;\n\n/**\n * If errors and warnings should be logged within the library.\n */\nexport const verbose = false;\n\nexport const DEG_TO_RADS = Math.PI / 180;\n\n/**\n * Rotates a point by a given angle.\n * @param angle The angle to rotate by in radians\n * @param p The point to rotate around 0,0.\n */\nexport function rotatePoint(angle: number, p: IPointData): void\n{\n if (!angle) return;\n\n const s = Math.sin(angle);\n const c = Math.cos(angle);\n const xnew = (p.x * c) - (p.y * s);\n const ynew = (p.x * s) + (p.y * c);\n\n p.x = xnew;\n p.y = ynew;\n}\n\n/**\n * Combines separate color components (0-255) into a single uint color.\n * @param r The red value of the color\n * @param g The green value of the color\n * @param b The blue value of the color\n * @return The color in the form of 0xRRGGBB\n */\nexport function combineRGBComponents(r: number, g: number, b: number/* , a*/): number\n{\n return /* a << 24 |*/ (r << 16) | (g << 8) | b;\n}\n\n/**\n * Returns the length (or magnitude) of this point.\n * @param point The point to measure length\n * @return The length of this point.\n */\nexport function length(point: IPointData): number\n{\n return Math.sqrt((point.x * point.x) + (point.y * point.y));\n}\n\n/**\n * Reduces the point to a length of 1.\n * @param point The point to normalize\n */\nexport function normalize(point: IPointData): void\n{\n let oneOverLen = 1 / length(point);\n\n // if NaN or Infinity (length of 0), change to 0 so the resulting point is 0\n // eslint-disable-next-line no-self-compare\n if (oneOverLen !== oneOverLen || oneOverLen === Infinity)\n {\n oneOverLen = 0;\n }\n\n point.x *= oneOverLen;\n point.y *= oneOverLen;\n}\n\n/**\n * Multiplies the x and y values of this point by a value.\n * @param point The point to scaleBy\n * @param value The value to scale by.\n */\nexport function scaleBy(point: IPointData, value: number): void\n{\n point.x *= value;\n point.y *= value;\n}\n\n/**\n * Converts a hex string from \"#AARRGGBB\", \"#RRGGBB\", \"0xAARRGGBB\", \"0xRRGGBB\",\n * \"AARRGGBB\", or \"RRGGBB\" to an object of ints of 0-255, as\n * {r, g, b, (a)}.\n * @param color The input color string.\n * @param output An object to put the output in. If omitted, a new object is created.\n * @return The object with r, g, and b properties, possibly with an a property.\n */\nexport function hexToRGB(color: string, output?: Color): Color\n{\n if (!output)\n {\n output = {} as Color;\n }\n if (color.charAt(0) === '#')\n {\n color = color.substr(1);\n }\n else if (color.indexOf('0x') === 0)\n {\n color = color.substr(2);\n }\n let alpha;\n\n if (color.length === 8)\n {\n alpha = color.substr(0, 2);\n color = color.substr(2);\n }\n output.r = parseInt(color.substr(0, 2), 16);// Red\n output.g = parseInt(color.substr(2, 2), 16);// Green\n output.b = parseInt(color.substr(4, 2), 16);// Blue\n if (alpha)\n {\n output.a = parseInt(alpha, 16);\n }\n\n return output;\n}\n\n/**\n * Generates a custom ease function, based on the GreenSock custom ease, as demonstrated\n * by the related tool at http://www.greensock.com/customease/.\n * @param segments An array of segments, as created by\n * http://www.greensock.com/customease/.\n * @return A function that calculates the percentage of change at\n * a given point in time (0-1 inclusive).\n */\nexport function generateEase(segments: EaseSegment[]): SimpleEase\n{\n const qty = segments.length;\n const oneOverQty = 1 / qty;\n /*\n * Calculates the percentage of change at a given point in time (0-1 inclusive).\n * @param {Number} time The time of the ease, 0-1 inclusive.\n * @return {Number} The percentage of the change, 0-1 inclusive (unless your\n * ease goes outside those bounds).\n */\n\n // eslint-disable-next-line func-names\n return function (time: number): number\n {\n const i = (qty * time) | 0;// do a quick floor operation\n\n const t = (time - (i * oneOverQty)) * qty;\n const s = segments[i] || segments[qty - 1];\n\n return (s.s + (t * ((2 * (1 - t) * (s.cp - s.s)) + (t * (s.e - s.s)))));\n };\n}\n\n/**\n * Gets a blend mode, ensuring that it is valid.\n * @param name The name of the blend mode to get.\n * @return The blend mode as specified in the PIXI.BLEND_MODES enumeration.\n */\nexport function getBlendMode(name: string): number\n{\n if (!name) return BLEND_MODES.NORMAL;\n name = name.toUpperCase().replace(/ /g, '_');\n\n return (BLEND_MODES as any)[name] || BLEND_MODES.NORMAL;\n}\n\n/**\n * Converts a list of {value, time} objects starting at time 0 and ending at time 1 into an evenly\n * spaced stepped list of PropertyNodes for color values. This is primarily to handle conversion of\n * linear gradients to fewer colors, allowing for some optimization for Canvas2d fallbacks.\n * @param list The list of data to convert.\n * @param [numSteps=10] The number of steps to use.\n * @return The blend mode as specified in the PIXI.blendModes enumeration.\n */\nexport function createSteppedGradient(list: ValueStep[], numSteps = 10): PropertyNode\n{\n if (typeof numSteps !== 'number' || numSteps <= 0)\n {\n numSteps = 10;\n }\n const first = new PropertyNode(hexToRGB(list[0].value), list[0].time);\n\n first.isStepped = true;\n let currentNode = first;\n let current = list[0];\n let nextIndex = 1;\n let next = list[nextIndex];\n\n for (let i = 1; i < numSteps; ++i)\n {\n let lerp = i / numSteps;\n // ensure we are on the right segment, if multiple\n\n while (lerp > next.time)\n {\n current = next;\n next = list[++nextIndex];\n }\n // convert the lerp value to the segment range\n lerp = (lerp - current.time) / (next.time - current.time);\n const curVal = hexToRGB(current.value);\n const nextVal = hexToRGB(next.value);\n const output: Color = {\n r: ((nextVal.r - curVal.r) * lerp) + curVal.r,\n g: ((nextVal.g - curVal.g) * lerp) + curVal.g,\n b: ((nextVal.b - curVal.b) * lerp) + curVal.b,\n };\n\n currentNode.next = new PropertyNode(output, i / numSteps);\n currentNode = currentNode.next;\n }\n\n // we don't need to have a PropertyNode for time of 1, because in a stepped version at that point\n // the particle has died of old age\n return first;\n}\n","import { Particle } from '../Particle';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * All behaviors instances must implement this interface, and the class must match the\n * {@link IEmitterBehaviorClass} interface. All behaviors must have an order property and\n * `initParticles` method. Implementing the `updateParticle` or `recycleParticle` methods is optional.\n */\nexport interface IEmitterBehavior\n{\n /**\n * Order in which the behavior will be handled. Lower numbers are handled earlier, with an order of 0 getting\n * special treatment before the Emitter's transformation is applied.\n */\n order: number;\n /**\n * Called to initialize a wave of particles, with a reference to the first particle in the linked list.\n * @param first The first (maybe only) particle in a newly spawned wave of particles.\n */\n initParticles(first: Particle): void;\n /**\n * Updates a single particle for a given period of time elapsed. Return `true` to recycle the particle.\n * @param particle The particle to update.\n * @param deltaSec The time to advance the particle by in seconds.\n */\n updateParticle?(particle: Particle, deltaSec: number): void|boolean;\n /**\n * A hook for when a particle is recycled.\n * @param particle The particle that was just recycled.\n * @param natural `true` if the reycling was due to natural lifecycle, `false` if it was due to emitter cleanup.\n */\n recycleParticle?(particle: Particle, natural: boolean): void;\n}\n\n/**\n * All behavior classes must match this interface. The instances need to implement the {@link IEmitterBehavior} interface.\n */\nexport interface IEmitterBehaviorClass\n{\n /**\n * The unique type name that the behavior is registered under.\n */\n type: string;\n /**\n * Configuration data for an editor to display this behavior. Does not need to exist in production code.\n */\n editorConfig?: BehaviorEditorConfig;\n /**\n * The behavior constructor itself.\n * @param config The config for the behavior, which should match its defined specifications.\n */\n new (config: any): IEmitterBehavior;\n}\n\n/**\n * Standard behavior order values, specifying when/how they are used. Other numeric values can be used,\n * but only the Spawn value will be handled in a special way. All other values will be sorted numerically.\n * Behaviors with the same value will not be given any specific sort order, as they are assumed to not\n * interfere with each other.\n */\nexport enum BehaviorOrder\n{\n /**\n * Spawn - initial placement and/or rotation. This happens before rotation/translation due to\n * emitter rotation/position is applied.\n */\n Spawn = 0,\n /**\n * Normal priority, for things that don't matter when they are applied.\n */\n Normal = 2,\n /**\n * Delayed priority, for things that need to read other values in order to act correctly.\n */\n Late = 5,\n}\n","import { Emitter } from './Emitter';\nimport { LinkedListChild } from './LinkedListContainer';\nimport { Sprite } from '@pixi/sprite';\n\n/**\n * An individual particle image. You shouldn't have to deal with these.\n */\nexport class Particle extends Sprite implements LinkedListChild\n{\n /**\n * The emitter that controls this particle.\n */\n public emitter: Emitter;\n /**\n * The maximum lifetime of this particle, in seconds.\n */\n public maxLife: number;\n /**\n * The current age of the particle, in seconds.\n */\n public age: number;\n /**\n * The current age of the particle as a normalized value between 0 and 1.\n */\n public agePercent: number;\n /**\n * One divided by the max life of the particle, saved for slightly faster math.\n */\n public oneOverLife: number;\n /**\n * Reference to the next particle in the list.\n */\n public next: Particle;\n\n /**\n * Reference to the previous particle in the list.\n */\n public prev: Particle;\n\n public prevChild: LinkedListChild;\n public nextChild: LinkedListChild;\n\n /**\n * Static per-particle configuration for behaviors to use. Is not cleared when recycling.\n */\n public config: {[key: string]: any};\n\n /**\n * @param emitter The emitter that controls this particle.\n */\n constructor(emitter: Emitter)\n {\n // start off the sprite with a blank texture, since we are going to replace it\n // later when the particle is initialized.\n super();\n // initialize LinkedListChild props so they are included in underlying JS class definition\n this.prevChild = this.nextChild = null;\n\n this.emitter = emitter;\n this.config = {};\n // particles should be centered\n this.anchor.x = this.anchor.y = 0.5;\n this.maxLife = 0;\n this.age = 0;\n this.agePercent = 0;\n this.oneOverLife = 0;\n this.next = null;\n this.prev = null;\n\n // save often used functions on the instance instead of the prototype for better speed\n this.init = this.init;\n this.kill = this.kill;\n }\n\n /**\n * Initializes the particle for use, based on the properties that have to\n * have been set already on the particle.\n */\n public init(maxLife: number): void\n {\n this.maxLife = maxLife;\n // reset the age\n this.age = this.agePercent = 0;\n // reset the sprite props\n this.rotation = 0;\n this.position.x = this.position.y = 0;\n this.scale.x = this.scale.y = 1;\n this.tint = 0xffffff;\n this.alpha = 1;\n // save our lerp helper\n this.oneOverLife = 1 / this.maxLife;\n\n // ensure visibility\n this.visible = true;\n }\n\n /**\n * Kills the particle, removing it from the display list\n * and telling the emitter to recycle it.\n */\n public kill(): void\n {\n this.emitter.recycle(this);\n }\n\n /**\n * Destroys the particle, removing references and preventing future use.\n */\n public destroy(): void\n {\n if (this.parent)\n {\n this.parent.removeChild(this);\n }\n this.emitter = this.next = this.prev = null;\n super.destroy();\n }\n}\n","import { generateEase, rotatePoint, SimpleEase } from './ParticleUtils';\nimport { Particle } from './Particle';\nimport { EmitterConfigV3 } from './EmitterConfig';\nimport { Container } from '@pixi/display';\nimport { Point } from '@pixi/math';\nimport { Ticker } from '@pixi/ticker';\nimport { BehaviorOrder, IEmitterBehavior, IEmitterBehaviorClass } from './behaviors/Behaviors';\n// get the shared ticker, only supports V5 and V6 with individual packages\n/**\n * @hidden\n */\nconst ticker = Ticker.shared;\n\n/**\n * Key used in sorted order to determine when to set particle position from the emitter position\n * and rotation.\n */\nconst PositionParticle = Symbol('Position particle per emitter position');\n\n/**\n * A particle emitter.\n */\nexport class Emitter\n{\n private static knownBehaviors: {[key: string]: IEmitterBehaviorClass} = {};\n\n /**\n * Registers a new behavior, so that it will be recognized when initializing emitters.\n * Behaviors registered later with duplicate types will override older ones, although there is no limit on\n * the allowed types.\n * @param constructor The behavior class to register.\n */\n public static registerBehavior(constructor: IEmitterBehaviorClass): void\n {\n Emitter.knownBehaviors[constructor.type] = constructor;\n }\n\n /**\n * Active initialization behaviors for this emitter.\n */\n protected initBehaviors: (IEmitterBehavior | typeof PositionParticle)[];\n /**\n * Active update behaviors for this emitter.\n */\n protected updateBehaviors: IEmitterBehavior[];\n /**\n * Active recycle behaviors for this emitter.\n */\n protected recycleBehaviors: IEmitterBehavior[];\n // properties for individual particles\n /**\n * The minimum lifetime for a particle, in seconds.\n */\n public minLifetime: number;\n /**\n * The maximum lifetime for a particle, in seconds.\n */\n public maxLifetime: number;\n /**\n * An easing function for nonlinear interpolation of values. Accepts a single\n * parameter of time as a value from 0-1, inclusive. Expected outputs are values\n * from 0-1, inclusive.\n */\n public customEase: SimpleEase;\n // properties for spawning particles\n /**\n * Time between particle spawns in seconds.\n */\n protected _frequency: number;\n /**\n * Chance that a particle will be spawned on each opportunity to spawn one.\n * 0 is 0%, 1 is 100%.\n */\n public spawnChance: number;\n /**\n * Maximum number of particles to keep alive at a time. If this limit\n * is reached, no more particles will spawn until some have died.\n */\n public maxParticles: number;\n /**\n * The amount of time in seconds to emit for before setting emit to false.\n * A value of -1 is an unlimited amount of time.\n */\n public emitterLifetime: number;\n /**\n * Position at which to spawn particles, relative to the emitter's owner's origin.\n * For example, the flames of a rocket travelling right might have a spawnPos\n * of {x:-50, y:0}.\n * to spawn at the rear of the rocket.\n * To change this, use updateSpawnPos().\n */\n public spawnPos: Point;\n /**\n * Number of particles to spawn time that the frequency allows for particles to spawn.\n */\n public particlesPerWave: number;\n /**\n * Rotation of the emitter or emitter's owner in degrees. This is added to\n * the calculated spawn angle.\n * To change this, use rotate().\n */\n protected rotation: number;\n /**\n * The world position of the emitter's owner, to add spawnPos to when\n * spawning particles. To change this, use updateOwnerPos().\n */\n protected ownerPos: Point;\n /**\n * The origin + spawnPos in the previous update, so that the spawn position\n * can be interpolated to space out particles better.\n */\n protected _prevEmitterPos: Point;\n /**\n * If _prevEmitterPos is valid, to prevent interpolation on the first update\n */\n protected _prevPosIsValid: boolean;\n /**\n * If either ownerPos or spawnPos has changed since the previous update.\n */\n protected _posChanged: boolean;\n /**\n * The container to add particles to.\n */\n protected _parent: Container;\n /**\n * If particles should be added at the back of the display list instead of the front.\n */\n public addAtBack: boolean;\n /**\n * The current number of active particles.\n */\n public particleCount: number;\n /**\n * If particles should be emitted during update() calls. Setting this to false\n * stops new particles from being created, but allows existing ones to die out.\n */\n protected _emit: boolean;\n /**\n * The timer for when to spawn particles in seconds, where numbers less\n * than 0 mean that particles should be spawned.\n */\n protected _spawnTimer: number;\n /**\n * The life of the emitter in seconds.\n */\n protected _emitterLife: number;\n /**\n * The particles that are active and on the display list. This is the first particle in a\n * linked list.\n */\n protected _activeParticlesFirst: Particle;\n /**\n * The particles that are active and on the display list. This is the last particle in a\n * linked list.\n */\n protected _activeParticlesLast: Particle;\n /**\n * The particles that are not currently being used. This is the first particle in a\n * linked list.\n */\n protected _poolFirst: Particle;\n /**\n * The original config object that this emitter was initialized with.\n */\n protected _origConfig: any;\n /**\n * If the update function is called automatically from the shared ticker.\n * Setting this to false requires calling the update function manually.\n */\n protected _autoUpdate: boolean;\n /**\n * If the emitter should destroy itself when all particles have died out. This is set by\n * playOnceAndDestroy();\n */\n protected _destroyWhenComplete: boolean;\n /**\n * A callback for when all particles have died out. This is set by\n * playOnceAndDestroy() or playOnce();\n */\n protected _completeCallback: () => void;\n\n /**\n * @param particleParent The container to add the particles to.\n * @param particleImages A texture or array of textures to use\n * for the particles. Strings will be turned\n * into textures via Texture.from().\n * @param config A configuration object containing settings for the emitter.\n * @param config.emit If config.emit is explicitly passed as false, the\n * Emitter will start disabled.\n * @param config.autoUpdate If config.autoUpdate is explicitly passed as\n * true, the Emitter will automatically call\n * update via the PIXI shared ticker.\n */\n constructor(particleParent: Container, config: EmitterConfigV3)\n {\n this.initBehaviors = [];\n this.updateBehaviors = [];\n this.recycleBehaviors = [];\n // properties for individual particles\n this.minLifetime = 0;\n this.maxLifetime = 0;\n this.customEase = null;\n // properties for spawning particles\n this._frequency = 1;\n this.spawnChance = 1;\n this.maxParticles = 1000;\n this.emitterLifetime = -1;\n this.spawnPos = new Point();\n this.particlesPerWave = 1;\n // emitter properties\n this.rotation = 0;\n this.ownerPos = new Point();\n this._prevEmitterPos = new Point();\n this._prevPosIsValid = false;\n this._posChanged = false;\n this._parent = null;\n this.addAtBack = false;\n this.particleCount = 0;\n this._emit = false;\n this._spawnTimer = 0;\n this._emitterLife = -1;\n this._activeParticlesFirst = null;\n this._activeParticlesLast = null;\n this._poolFirst = null;\n this._origConfig = null;\n this._autoUpdate = false;\n this._destroyWhenComplete = false;\n this._completeCallback = null;\n\n // set the initial parent\n this.parent = particleParent;\n\n if (config)\n {\n this.init(config);\n }\n\n // save often used functions on the instance instead of the prototype for better speed\n this.recycle = this.recycle;\n this.update = this.update;\n this.rotate = this.rotate;\n this.updateSpawnPos = this.updateSpawnPos;\n this.updateOwnerPos = this.updateOwnerPos;\n }\n\n /**\n * Time between particle spawns in seconds. If this value is not a number greater than 0,\n * it will be set to 1 (particle per second) to prevent infinite loops.\n */\n public get frequency(): number { return this._frequency; }\n public set frequency(value: number)\n {\n // do some error checking to prevent infinite loops\n if (typeof value === 'number' && value > 0)\n {\n this._frequency = value;\n }\n else\n {\n this._frequency = 1;\n }\n }\n\n /**\n * The container to add particles to. Settings this will dump any active particles.\n */\n public get parent(): Container { return this._parent; }\n public set parent(value: Container)\n {\n this.cleanup();\n this._parent = value;\n }\n\n /**\n * Sets up the emitter based on the config settings.\n * @param config A configuration object containing settings for the emitter.\n */\n public init(config: EmitterConfigV3): void\n {\n if (!config)\n {\n return;\n }\n // clean up any existing particles\n this.cleanup();\n\n // store the original config and particle images, in case we need to re-initialize\n // when the particle constructor is changed\n this._origConfig = config;\n\n // /////////////////////////\n // Particle Properties //\n // /////////////////////////\n\n // set up the lifetime\n this.minLifetime = config.lifetime.min;\n this.maxLifetime = config.lifetime.max;\n // use the custom ease if provided\n if (config.ease)\n {\n this.customEase = typeof config.ease === 'function'\n ? config.ease : generateEase(config.ease);\n }\n else\n {\n this.customEase = null;\n }\n // ////////////////////////\n // Emitter Properties //\n // ////////////////////////\n // reset spawn type specific settings\n this.particlesPerWave = 1;\n if (config.particlesPerWave && config.particlesPerWave > 1)\n {\n this.particlesPerWave = config.particlesPerWave;\n }\n // set the spawning frequency\n this.frequency = config.frequency;\n this.spawnChance = (typeof config.spawnChance === 'number' && config.spawnChance > 0) ? config.spawnChance : 1;\n // set the emitter lifetime\n this.emitterLifetime = config.emitterLifetime || -1;\n // set the max particles\n this.maxParticles = config.maxParticles > 0 ? config.maxParticles : 1000;\n // determine if we should add the particle at the back of the list or not\n this.addAtBack = !!config.addAtBack;\n // reset the emitter position and rotation variables\n this.rotation = 0;\n this.ownerPos.set(0);\n if (config.pos)\n {\n this.spawnPos.copyFrom(config.pos);\n }\n else\n {\n this.spawnPos.set(0);\n }\n\n this._prevEmitterPos.copyFrom(this.spawnPos);\n // previous emitter position is invalid and should not be used for interpolation\n this._prevPosIsValid = false;\n // start emitting\n this._spawnTimer = 0;\n this.emit = config.emit === undefined ? true : !!config.emit;\n this.autoUpdate = !!config.autoUpdate;\n\n // ////////////////////////\n // Behaviors //\n // ////////////////////////\n const behaviors: (IEmitterBehavior | typeof PositionParticle)[] = config.behaviors.map((data) =>\n {\n const constructor = Emitter.knownBehaviors[data.type];\n\n if (!constructor)\n {\n console.error(`Unknown behavior: ${data.type}`);\n\n return null;\n }\n\n return new constructor(data.config);\n })\n .filter((b) => !!b);\n\n behaviors.push(PositionParticle);\n behaviors.sort((a, b) =>\n {\n if (a === PositionParticle)\n {\n return (b as IEmitterBehavior).order === BehaviorOrder.Spawn ? 1 : -1;\n }\n else if (b === PositionParticle)\n {\n return (a as IEmitterBehavior).order === BehaviorOrder.Spawn ? -1 : 1;\n }\n\n return (a as IEmitterBehavior).order - (b as IEmitterBehavior).order;\n });\n this.initBehaviors = behaviors.slice();\n this.updateBehaviors = behaviors.filter((b) => b !== PositionParticle && b.updateParticle) as IEmitterBehavior[];\n this.recycleBehaviors = behaviors.filter((b) => b !== PositionParticle && b.recycleParticle) as IEmitterBehavior[];\n }\n\n /**\n * Gets the instantiated behavior of the specified type, if it is present on this emitter.\n * @param type The behavior type to find.\n */\n public getBehavior(type: string): IEmitterBehavior|null\n {\n // bail if we don't know about such an emitter\n if (!Emitter.knownBehaviors[type]) return null;\n\n // find one that is an instance of the specified type\n return this.initBehaviors.find((b) => b instanceof Emitter.knownBehaviors[type]) as IEmitterBehavior || null;\n }\n\n /**\n * Fills the pool with the specified number of particles, so that they don't have to be instantiated later.\n * @param count The number of particles to create.\n */\n public fillPool(count: number): void\n {\n for (; count > 0; --count)\n {\n const p = new Particle(this);\n\n p.next = this._poolFirst;\n this._poolFirst = p;\n }\n }\n\n /**\n * Recycles an individual particle. For internal use only.\n * @param particle The particle to recycle.\n * @param fromCleanup If this is being called to manually clean up all particles.\n * @internal\n */\n public recycle(particle: Particle, fromCleanup = false): void\n {\n for (let i = 0; i < this.recycleBehaviors.length; ++i)\n {\n this.recycleBehaviors[i].recycleParticle(particle, !fromCleanup);\n }\n if (particle.next)\n {\n particle.next.prev = particle.prev;\n }\n if (particle.prev)\n {\n particle.prev.next = particle.next;\n }\n if (particle === this._activeParticlesLast)\n {\n this._activeParticlesLast = particle.prev;\n }\n if (particle === this._activeParticlesFirst)\n {\n this._activeParticlesFirst = particle.next;\n }\n // add to pool\n particle.prev = null;\n particle.next = this._poolFirst;\n this._poolFirst = particle;\n // remove child from display, or make it invisible if it is in a ParticleContainer\n if (particle.parent)\n {\n particle.parent.removeChild(particle);\n }\n // decrease count\n --this.particleCount;\n }\n\n /**\n * Sets the rotation of the emitter to a new value. This rotates the spawn position in addition\n * to particle direction.\n * @param newRot The new rotation, in degrees.\n */\n public rotate(newRot: number): void\n {\n if (this.rotation === newRot) return;\n // caclulate the difference in rotation for rotating spawnPos\n const diff = newRot - this.rotation;\n\n this.rotation = newRot;\n // rotate spawnPos\n rotatePoint(diff, this.spawnPos);\n // mark the position as having changed\n this._posChanged = true;\n }\n\n /**\n * Changes the spawn position of the emitter.\n * @param x The new x value of the spawn position for the emitter.\n * @param y The new y value of the spawn position for the emitter.\n */\n public updateSpawnPos(x: number, y: number): void\n {\n this._posChanged = true;\n this.spawnPos.x = x;\n this.spawnPos.y = y;\n }\n\n /**\n * Changes the position of the emitter's owner. You should call this if you are adding\n * particles to the world container that your emitter's owner is moving around in.\n * @param x The new x value of the emitter's owner.\n * @param y The new y value of the emitter's owner.\n */\n public updateOwnerPos(x: number, y: number): void\n {\n this._posChanged = true;\n this.ownerPos.x = x;\n this.ownerPos.y = y;\n }\n\n /**\n * Prevents emitter position interpolation in the next update.\n * This should be used if you made a major position change of your emitter's owner\n * that was not normal movement.\n */\n public resetPositionTracking(): void\n {\n this._prevPosIsValid = false;\n }\n\n /**\n * If particles should be emitted during update() calls. Setting this to false\n * stops new particles from being created, but allows existing ones to die out.\n */\n public get emit(): boolean { return this._emit; }\n public set emit(value: boolean)\n {\n this._emit = !!value;\n this._emitterLife = this.emitterLifetime;\n }\n\n /**\n * If the update function is called automatically from the shared ticker.\n * Setting this to false requires calling the update function manually.\n */\n public get autoUpdate(): boolean { return this._autoUpdate; }\n public set autoUpdate(value: boolean)\n {\n if (this._autoUpdate && !value)\n {\n ticker.remove(this.update, this);\n }\n else if (!this._autoUpdate && value)\n {\n ticker.add(this.update, this);\n }\n this._autoUpdate = !!value;\n }\n\n /**\n * Starts emitting particles, sets autoUpdate to true, and sets up the Emitter to destroy itself\n * when particle emission is complete.\n * @param callback Callback for when emission is complete (all particles have died off)\n */\n public playOnceAndDestroy(callback?: () => void): void\n {\n this.autoUpdate = true;\n this.emit = true;\n this._destroyWhenComplete = true;\n this._completeCallback = callback;\n }\n\n /**\n * Starts emitting particles and optionally calls a callback when particle emission is complete.\n * @param callback Callback for when emission is complete (all particles have died off)\n */\n public playOnce(callback?: () => void): void\n {\n this.emit = true;\n this._completeCallback = callback;\n }\n\n /**\n * Updates all particles spawned by this emitter and emits new ones.\n * @param delta Time elapsed since the previous frame, in __seconds__.\n */\n public update(delta: number): void\n {\n if (this._autoUpdate)\n {\n delta = ticker.elapsedMS * 0.001;\n }\n\n // if we don't have a parent to add particles to, then don't do anything.\n // this also works as a isDestroyed check\n if (!this._parent) return;\n\n // == update existing particles ==\n\n // update all particle lifetimes before turning them over to behaviors\n for (let particle = this._activeParticlesFirst, next; particle; particle = next)\n {\n // save next particle in case we recycle this one\n next = particle.next;\n // increase age\n particle.age += delta;\n // recycle particle if it is too old\n if (particle.age > particle.maxLife || particle.age < 0)\n {\n this.recycle(particle);\n }\n else\n {\n // determine our interpolation value\n let lerp = particle.age * particle.oneOverLife;// lifetime / maxLife;\n\n // global ease affects all interpolation calculations\n if (this.customEase)\n {\n if (this.customEase.length === 4)\n {\n // the t, b, c, d parameters that some tween libraries use\n // (time, initial value, end value, duration)\n lerp = (this.customEase as any)(lerp, 0, 1, 1);\n }\n else\n {\n // the simplified version that we like that takes\n // one parameter, time from 0-1. TweenJS eases provide this usage.\n lerp = this.customEase(lerp);\n }\n }\n\n // set age percent for all interpolation calculations\n particle.agePercent = lerp;\n\n // let each behavior run wild on the active particles\n for (let i = 0; i < this.updateBehaviors.length; ++i)\n {\n if (this.updateBehaviors[i].updateParticle(particle, delta))\n {\n this.recycle(particle);\n break;\n }\n }\n }\n }\n\n let prevX: number;\n let prevY: number;\n\n // if the previous position is valid, store these for later interpolation\n if (this._prevPosIsValid)\n {\n prevX = this._prevEmitterPos.x;\n prevY = this._prevEmitterPos.y;\n }\n // store current position of the emitter as local variables\n const curX = this.ownerPos.x + this.spawnPos.x;\n const curY = this.ownerPos.y + this.spawnPos.y;\n // spawn new particles\n\n if (this._emit)\n {\n // decrease spawn timer\n this._spawnTimer -= delta < 0 ? 0 : delta;\n // while _spawnTimer < 0, we have particles to spawn\n while (this._spawnTimer <= 0)\n {\n // determine if the emitter should stop spawning\n if (this._emitterLife >= 0)\n {\n this._emitterLife -= this._frequency;\n if (this._emitterLife <= 0)\n {\n this._spawnTimer = 0;\n this._emitterLife = 0;\n this.emit = false;\n break;\n }\n }\n // determine if we have hit the particle limit\n if (this.particleCount >= this.maxParticles)\n {\n this._spawnTimer += this._frequency;\n continue;\n }\n let emitPosX: number;\n let emitPosY: number;\n\n // If the position has changed and this isn't the first spawn,\n // interpolate the spawn position\n if (this._prevPosIsValid && this._posChanged)\n {\n // 1 - _spawnTimer / delta, but _spawnTimer is negative\n const lerp = 1 + (this._spawnTimer / delta);\n\n emitPosX = ((curX - prevX) * lerp) + prevX;\n emitPosY = ((curY - prevY) * lerp) + prevY;\n }\n // otherwise just set to the spawn position\n else\n {\n emitPosX = curX;\n emitPosY = curY;\n }\n\n let waveFirst: Particle = null;\n let waveLast: Particle = null;\n\n // create enough particles to fill the wave\n for (let len = Math.min(this.particlesPerWave, this.maxParticles - this.particleCount), i = 0; i < len; ++i)\n {\n // see if we actually spawn one\n if (this.spawnChance < 1 && Math.random() >= this.spawnChance)\n {\n continue;\n }\n // determine the particle lifetime\n let lifetime;\n\n if (this.minLifetime === this.maxLifetime)\n {\n lifetime = this.minLifetime;\n }\n else\n {\n lifetime = (Math.random() * (this.maxLifetime - this.minLifetime)) + this.minLifetime;\n }\n // only make the particle if it wouldn't immediately destroy itself\n if (-this._spawnTimer >= lifetime)\n {\n continue;\n }\n // create particle\n let p: Particle;\n\n if (this._poolFirst)\n {\n p = this._poolFirst;\n this._poolFirst = this._poolFirst.next;\n p.next = null;\n }\n else\n {\n p = new Particle(this);\n }\n\n // initialize particle\n p.init(lifetime);\n // add the particle to the display list\n if (this.addAtBack)\n {\n this._parent.addChildAt(p, 0);\n }\n else\n {\n this._parent.addChild(p);\n }\n // add particles to list of ones in this wave\n if (waveFirst)\n {\n waveLast.next = p;\n p.prev = waveLast;\n waveLast = p;\n }\n else\n {\n waveLast = waveFirst = p;\n }\n // increase our particle count\n ++this.particleCount;\n }\n\n if (waveFirst)\n {\n // add particle to list of active particles\n if (this._activeParticlesLast)\n {\n this._activeParticlesLast.next = waveFirst;\n waveFirst.prev = this._activeParticlesLast;\n this._activeParticlesLast = waveLast;\n }\n else\n {\n this._activeParticlesFirst = waveFirst;\n this._activeParticlesLast = waveLast;\n }\n // run behavior init on particles\n for (let i = 0; i < this.initBehaviors.length; ++i)\n {\n const behavior = this.initBehaviors[i];\n\n // if we hit our special key, interrupt behaviors to apply\n // emitter position/rotation\n if (behavior === PositionParticle)\n {\n for (let particle = waveFirst, next; particle; particle = next)\n {\n // save next particle in case we recycle this one\n next = particle.next;\n // rotate the particle's position by the emitter's rotation\n if (this.rotation !== 0)\n {\n rotatePoint(this.rotation, particle.position);\n particle.rotation += this.rotation;\n }\n // offset by the emitter's position\n particle.position.x += emitPosX;\n particle.position.y += emitPosY;\n\n // also, just update the particle's age properties while we are looping through\n particle.age += -this._spawnTimer;\n // determine our interpolation value\n let lerp = particle.age * particle.oneOverLife;// lifetime / maxLife;\n\n // global ease affects all interpolation calculations\n if (this.customEase)\n {\n if (this.customEase.length === 4)\n {\n // the t, b, c, d parameters that some tween libraries use\n // (time, initial value, end value, duration)\n lerp = (this.customEase as any)(lerp, 0, 1, 1);\n }\n else\n {\n // the simplified version that we like that takes\n // one parameter, time from 0-1. TweenJS eases provide this usage.\n lerp = this.customEase(lerp);\n }\n }\n // set age percent for all interpolation calculations\n particle.agePercent = lerp;\n }\n }\n else\n {\n behavior.initParticles(waveFirst);\n }\n }\n for (let particle = waveFirst, next; particle; particle = next)\n {\n // save next particle in case we recycle this one\n next = particle.next;\n // now update the particles by the time passed, so the particles are spread out properly\n for (let i = 0; i < this.updateBehaviors.length; ++i)\n {\n // we want a positive delta, because a negative delta messes things up\n if (this.updateBehaviors[i].updateParticle(particle, -this._spawnTimer))\n {\n // bail if the particle got reycled\n this.recycle(particle);\n break;\n }\n }\n }\n }\n // increase timer and continue on to any other particles that need to be created\n this._spawnTimer += this._frequency;\n }\n }\n // if the position changed before this update, then keep track of that\n if (this._posChanged)\n {\n this._prevEmitterPos.x = curX;\n this._prevEmitterPos.y = curY;\n this._prevPosIsValid = true;\n this._posChanged = false;\n }\n\n // if we are all done and should destroy ourselves, take care of that\n if (!this._emit && !this._activeParticlesFirst)\n {\n if (this._completeCallback)\n {\n const cb = this._completeCallback;\n\n this._completeCallback = null;\n cb();\n }\n if (this._destroyWhenComplete)\n {\n this.destroy();\n }\n }\n }\n\n /**\n * Emits a single wave of particles, using standard spawnChance & particlesPerWave settings. Does not affect\n * regular spawning through the frequency, and ignores the emit property. The max particle count is respected, however,\n * so if there are already too many particles then nothing will happen.\n */\n public emitNow(): void\n {\n const emitPosX = this.ownerPos.x + this.spawnPos.x;\n const emitPosY = this.ownerPos.y + this.spawnPos.y;\n\n let waveFirst: Particle = null;\n let waveLast: Particle = null;\n\n // create enough particles to fill the wave\n for (let len = Math.min(this.particlesPerWave, this.maxParticles - this.particleCount), i = 0; i < len; ++i)\n {\n // see if we actually spawn one\n if (this.spawnChance < 1 && Math.random() >= this.spawnChance)\n {\n continue;\n }\n // create particle\n let p: Particle;\n\n if (this._poolFirst)\n {\n p = this._poolFirst;\n this._poolFirst = this._poolFirst.next;\n p.next = null;\n }\n else\n {\n p = new Particle(this);\n }\n\n let lifetime: number;\n\n if (this.minLifetime === this.maxLifetime)\n {\n lifetime = this.minLifetime;\n }\n else\n {\n lifetime = (Math.random() * (this.maxLifetime - this.minLifetime)) + this.minLifetime;\n }\n // initialize particle\n p.init(lifetime);\n // add the particle to the display list\n if (this.addAtBack)\n {\n this._parent.addChildAt(p, 0);\n }\n else\n {\n this._parent.addChild(p);\n }\n // add particles to list of ones in this wave\n if (waveFirst)\n {\n waveLast.next = p;\n p.prev = waveLast;\n waveLast = p;\n }\n else\n {\n waveLast = waveFirst = p;\n }\n // increase our particle count\n ++this.particleCount;\n }\n\n if (waveFirst)\n {\n // add particle to list of active particles\n if (this._activeParticlesLast)\n {\n this._activeParticlesLast.next = waveFirst;\n waveFirst.prev = this._activeParticlesLast;\n this._activeParticlesLast = waveLast;\n }\n else\n {\n this._activeParticlesFirst = waveFirst;\n this._activeParticlesLast = waveLast;\n }\n // run behavior init on particles\n for (let i = 0; i < this.initBehaviors.length; ++i)\n {\n const behavior = this.initBehaviors[i];\n\n // if we hit our special key, interrupt behaviors to apply\n // emitter position/rotation\n if (behavior === PositionParticle)\n {\n for (let particle = waveFirst, next; particle; particle = next)\n {\n // save next particle in case we recycle this one\n next = particle.next;\n // rotate the particle's position by the emitter's rotation\n if (this.rotation !== 0)\n {\n rotatePoint(this.rotation, particle.position);\n particle.rotation += this.rotation;\n }\n // offset by the emitter's position\n particle.position.x += emitPosX;\n particle.position.y += emitPosY;\n }\n }\n else\n {\n behavior.initParticles(waveFirst);\n }\n }\n }\n }\n\n /**\n * Kills all active particles immediately.\n */\n public cleanup(): void\n {\n let particle;\n let next;\n\n for (particle = this._activeParticlesFirst; particle; particle = next)\n {\n next = particle.next;\n this.recycle(particle, true);\n }\n this._activeParticlesFirst = this._activeParticlesLast = null;\n this.particleCount = 0;\n }\n\n /**\n * If this emitter has been destroyed. Note that a destroyed emitter can still be reused, after\n * having a new parent set and being reinitialized.\n */\n public get destroyed(): boolean\n {\n return !(this._parent && this.initBehaviors.length);\n }\n\n /**\n * Destroys the emitter and all of its particles.\n */\n public destroy(): void\n {\n // make sure we aren't still listening to any tickers\n this.autoUpdate = false;\n // puts all active particles in the pool, and removes them from the particle parent\n this.cleanup();\n // wipe the pool clean\n let next;\n\n for (let particle = this._poolFirst; particle; particle = next)\n {\n // store next value so we don't lose it in our destroy call\n next = particle.next;\n particle.destroy();\n }\n this._poolFirst = this._parent = this.spawnPos = this.ownerPos\n = this.customEase = this._completeCallback = null;\n\n this.initBehaviors.length = this.updateBehaviors.length = this.recycleBehaviors.length = 0;\n }\n}\n","import { Particle } from '../../Particle';\nimport type { ObjectProperty } from '../editor/Types';\nimport { SpawnShape } from './SpawnShape';\n\n/**\n * A SpawnShape that randomly picks locations inside a rectangle.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'rect',\n * data: {\n * x: 0,\n * y: 0,\n * w: 10,\n * h: 100\n * }\n * }\n * ```\n */\nexport class Rectangle implements SpawnShape\n{\n public static type = 'rect';\n public static editorConfig: ObjectProperty = null;\n /**\n * X (left) position of the rectangle.\n */\n public x: number;\n /**\n * Y (top) position of the rectangle.\n */\n public y: number;\n /**\n * Width of the rectangle.\n */\n public w: number;\n /**\n * Height of the rectangle.\n */\n public h: number;\n\n constructor(config: {\n /**\n * X (left) position of the rectangle.\n */\n x: number;\n /**\n * Y (top) position of the rectangle.\n */\n y: number;\n /**\n * Width of the rectangle.\n */\n w: number;\n /**\n * Height of the rectangle.\n */\n h: number;\n })\n {\n this.x = config.x;\n this.y = config.y;\n this.w = config.w;\n this.h = config.h;\n }\n\n getRandPos(particle: Particle): void\n {\n // place the particle at a random point in the rectangle\n particle.x = (Math.random() * this.w) + this.x;\n particle.y = (Math.random() * this.h) + this.y;\n }\n}\n","import { Particle } from '../../Particle';\nimport { rotatePoint } from '../../ParticleUtils';\nimport { ObjectProperty } from '../editor/Types';\nimport { SpawnShape } from './SpawnShape';\n\n/**\n * A class for spawning particles in a circle or ring.\n * Can optionally apply rotation to particles so that they are aimed away from the center of the circle.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'torus',\n * data: {\n * radius: 30,\n * x: 0,\n * y: 0,\n * innerRadius: 10,\n * rotation: true\n * }\n * }\n * ```\n */\nexport class Torus implements SpawnShape\n{\n public static type = 'torus';\n public static editorConfig: ObjectProperty = null;\n /**\n * X position of the center of the shape.\n */\n public x: number;\n /**\n * Y position of the center of the shape.\n */\n public y: number;\n /**\n * Radius of circle, or outer radius of a ring.\n */\n public radius: number;\n /**\n * Inner radius of a ring. Use 0 to have a circle.\n */\n public innerRadius: number;\n /**\n * If rotation should be applied to particles.\n */\n public rotation: boolean;\n\n constructor(config: {\n /**\n * Radius of circle, or outer radius of a ring. Note that this uses the full name of 'radius',\n * where earlier versions of the library may have used 'r'.\n */\n radius: number;\n /**\n * X position of the center of the shape.\n */\n x: number;\n /**\n * Y position of the center of the shape.\n */\n y: number;\n /**\n * Inner radius of a ring. Omit, or use 0, to have a circle.\n */\n innerRadius?: number;\n /**\n * If rotation should be applied to particles, pointing them away from the center of the torus.\n * Defaults to false.\n */\n affectRotation?: boolean\n })\n {\n this.x = config.x || 0;\n this.y = config.y || 0;\n this.radius = config.radius;\n this.innerRadius = config.innerRadius || 0;\n this.rotation = !!config.affectRotation;\n }\n\n getRandPos(particle: Particle): void\n {\n // place the particle at a random radius in the ring\n if (this.innerRadius !== this.radius)\n {\n particle.x = (Math.random() * (this.radius - this.innerRadius)) + this.innerRadius;\n }\n else\n {\n particle.x = this.radius;\n }\n particle.y = 0;\n // rotate the point to a random angle in the circle\n const angle = Math.random() * Math.PI * 2;\n\n if (this.rotation)\n {\n particle.rotation += angle;\n }\n rotatePoint(angle, particle.position);\n // now add in the center of the torus\n particle.position.x += this.x;\n particle.position.y += this.y;\n }\n}\n","import { IPointData } from '@pixi/math';\nimport { ListProperty } from '../editor/Types';\nimport { SpawnShape } from './SpawnShape';\n\n/**\n * Data structure for internal parsed data in PolygonalChain spawn shapes.\n */\nexport interface Segment\n{\n p1: IPointData;\n p2: IPointData;\n l: number;\n}\n\n/**\n * A spawn shape that picks a random position along a series of line segments. If those\n * line segments form a polygon, particles will only be placed on the perimeter of that polygon.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'polygonalChain',\n * data: [\n * [{x: 0, y: 0}, {x: 10, y: 10}, {x: 20, y: 0}],\n * [{x: 0, y, -10}, {x: 10, y: 0}, {x: 20, y: -10}]\n * ]\n * }\n * ```\n */\nexport class PolygonalChain implements SpawnShape\n{\n public static type = 'polygonalChain';\n public static editorConfig: ListProperty = null;\n /**\n * List of segment objects in the chain.\n */\n private segments: Segment[];\n /**\n * Total length of all segments of the chain.\n */\n private totalLength: number;\n /**\n * Total length of segments up to and including the segment of the same index.\n * Used for weighted random selection of segment.\n */\n private countingLengths: number[];\n\n /**\n * @param data Point data for polygon chains. Either a list of points for a single chain, or a list of chains.\n */\n constructor(data: IPointData[]|IPointData[][])\n {\n this.segments = [];\n this.countingLengths = [];\n this.totalLength = 0;\n this.init(data);\n }\n\n /**\n * @param data Point data for polygon chains. Either a list of points for a single chain, or a list of chains.\n */\n private init(data: IPointData[]|IPointData[][]): void\n {\n // if data is not present, set up a segment of length 0\n if (!data || !data.length)\n {\n this.segments.push({ p1: { x: 0, y: 0 }, p2: { x: 0, y: 0 }, l: 0 });\n }\n else if (Array.isArray(data[0]))\n {\n // list of segment chains, each defined as a list of points\n for (let i = 0; i < data.length; ++i)\n {\n // loop through the chain, connecting points\n const chain = data[i] as IPointData[];\n let prevPoint = chain[0] as IPointData;\n\n for (let j = 1; j < chain.length; ++j)\n {\n const second = chain[j] as IPointData;\n\n this.segments.push({ p1: prevPoint, p2: second, l: 0 });\n prevPoint = second;\n }\n }\n }\n else\n {\n let prevPoint = data[0] as IPointData;\n // list of points\n\n for (let i = 1; i < data.length; ++i)\n {\n const second = data[i] as IPointData;\n\n this.segments.push({ p1: prevPoint, p2: second, l: 0 });\n prevPoint = second;\n }\n }\n // now go through our segments to calculate the lengths so that we\n // can set up a nice weighted random distribution\n for (let i = 0; i < this.segments.length; ++i)\n {\n const { p1, p2 } = this.segments[i];\n const segLength = Math.sqrt(((p2.x - p1.x) * (p2.x - p1.x)) + ((p2.y - p1.y) * (p2.y - p1.y)));\n // save length so we can turn a random number into a 0-1 interpolation value later\n\n this.segments[i].l = segLength;\n this.totalLength += segLength;\n // keep track of the length so far, counting up\n this.countingLengths.push(this.totalLength);\n }\n }\n\n /**\n * Gets a random point in the chain.\n * @param out The point to store the selected position in.\n */\n public getRandPos(out: IPointData): void\n {\n // select a random spot in the length of the chain\n const rand = Math.random() * this.totalLength;\n let chosenSeg: Segment;\n let lerp: number;\n\n // if only one segment, it wins\n if (this.segments.length === 1)\n {\n chosenSeg = this.segments[0];\n lerp = rand;\n }\n else\n {\n // otherwise, go through countingLengths until we have determined\n // which segment we chose\n for (let i = 0; i < this.countingLengths.length; ++i)\n {\n if (rand < this.countingLengths[i])\n {\n chosenSeg = this.segments[i];\n // set lerp equal to the length into that segment\n // (i.e. the remainder after subtracting all the segments before it)\n lerp = i === 0 ? rand : rand - this.countingLengths[i - 1];\n break;\n }\n }\n }\n // divide lerp by the segment length, to result in a 0-1 number.\n lerp /= chosenSeg.l || 1;\n const { p1, p2 } = chosenSeg;\n // now calculate the position in the segment that the lerp value represents\n\n out.x = p1.x + (lerp * (p2.x - p1.x));\n out.y = p1.y + (lerp * (p2.y - p1.y));\n }\n}\n","import { Point } from '@pixi/math';\nimport { Particle } from '../Particle';\nimport { rotatePoint, scaleBy, length } from '../ParticleUtils';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Movement behavior that handles movement by applying a constant acceleration to all particles.\n *\n * Example configuration:\n * ```javascript\n * {\n * \"type\": \"moveAcceleration\",\n * \"config\": {\n * \"accel\": {\n * \"x\": 0,\n * \"y\": 2000\n * },\n * \"minStart\": 600,\n * \"maxStart\": 600,\n * \"rotate\": true\n * }\n *}\n * ```\n */\nexport class AccelerationBehavior implements IEmitterBehavior\n{\n public static type = 'moveAcceleration';\n public static editorConfig: BehaviorEditorConfig = null;\n\n // doesn't _really_ need to be late, but doing so ensures that we can override any\n // rotation behavior that is mistakenly added\n public order = BehaviorOrder.Late;\n private minStart: number;\n private maxStart: number;\n private accel: {x: number; y: number};\n private rotate: boolean;\n private maxSpeed: number;\n constructor(config: {\n /**\n * Minimum speed when initializing the particle, in world units/second.\n */\n minStart: number;\n /**\n * Maximum speed when initializing the particle. in world units/second.\n */\n maxStart: number;\n /**\n * Constant acceleration, in the coordinate space of the particle parent, in world units/second.\n */\n accel: {x: number; y: number};\n /**\n * Rotate the particle with its direction of movement.\n * While initial movement direction reacts to rotation settings, this overrides any dynamic rotation.\n * Defaults to false.\n */\n rotate?: boolean;\n /**\n * Maximum linear speed. 0 is unlimited. Defaults to 0.\n */\n maxSpeed?: number;\n })\n {\n this.minStart = config.minStart;\n this.maxStart = config.maxStart;\n this.accel = config.accel;\n this.rotate = !!config.rotate;\n this.maxSpeed = config.maxSpeed ?? 0;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const speed = (Math.random() * (this.maxStart - this.minStart)) + this.minStart;\n\n if (!next.config.velocity)\n {\n next.config.velocity = new Point(speed, 0);\n }\n else\n {\n (next.config.velocity as Point).set(speed, 0);\n }\n\n rotatePoint(next.rotation, next.config.velocity);\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n const vel = particle.config.velocity;\n const oldVX = vel.x;\n const oldVY = vel.y;\n\n vel.x += this.accel.x * deltaSec;\n vel.y += this.accel.y * deltaSec;\n if (this.maxSpeed)\n {\n const currentSpeed = length(vel);\n // if we are going faster than we should, clamp at the max speed\n // DO NOT recalculate vector length\n\n if (currentSpeed > this.maxSpeed)\n {\n scaleBy(vel, this.maxSpeed / currentSpeed);\n }\n }\n // calculate position delta by the midpoint between our old velocity and our new velocity\n particle.x += (oldVX + vel.x) / 2 * deltaSec;\n particle.y += (oldVY + vel.y) / 2 * deltaSec;\n if (this.rotate)\n {\n particle.rotation = Math.atan2(vel.y, vel.x);\n }\n }\n}\n","import { combineRGBComponents, SimpleEase, Color } from './ParticleUtils';\nimport { PropertyNode } from './PropertyNode';\n\nfunction intValueSimple(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n return ((this.first.next.value - this.first.value) * lerp) + this.first.value;\n}\n\nfunction intColorSimple(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n const curVal = this.first.value;\n const nextVal = this.first.next.value;\n const r = ((nextVal.r - curVal.r) * lerp) + curVal.r;\n const g = ((nextVal.g - curVal.g) * lerp) + curVal.g;\n const b = ((nextVal.b - curVal.b) * lerp) + curVal.b;\n\n return combineRGBComponents(r, g, b);\n}\n\nfunction intValueComplex(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n let next = current.next;\n\n while (lerp > next.time)\n {\n current = next;\n next = next.next;\n }\n // convert the lerp value to the segment range\n lerp = (lerp - current.time) / (next.time - current.time);\n\n return ((next.value - current.value) * lerp) + current.value;\n}\n\nfunction intColorComplex(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n let next = current.next;\n\n while (lerp > next.time)\n {\n current = next;\n next = next.next;\n }\n // convert the lerp value to the segment range\n lerp = (lerp - current.time) / (next.time - current.time);\n const curVal = current.value;\n const nextVal = next.value;\n const r = ((nextVal.r - curVal.r) * lerp) + curVal.r;\n const g = ((nextVal.g - curVal.g) * lerp) + curVal.g;\n const b = ((nextVal.b - curVal.b) * lerp) + curVal.b;\n\n return combineRGBComponents(r, g, b);\n}\n\nfunction intValueStepped(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n\n while (current.next && lerp > current.next.time)\n {\n current = current.next;\n }\n\n return current.value;\n}\n\nfunction intColorStepped(this: PropertyList, lerp: number): number\n{\n if (this.ease) lerp = this.ease(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n\n while (current.next && lerp > current.next.time)\n {\n current = current.next;\n }\n const curVal = current.value;\n\n return combineRGBComponents(curVal.r, curVal.g, curVal.b);\n}\n\n/**\n * Singly linked list container for keeping track of interpolated properties for particles.\n * Each Particle will have one of these for each interpolated property.\n */\nexport class PropertyList\n{\n /**\n * The first property node in the linked list.\n */\n public first: PropertyNode;\n /**\n * Calculates the correct value for the current interpolation value. This method is set in\n * the reset() method.\n * @param lerp The interpolation value from 0-1.\n * @return The interpolated value. Colors are converted to the hex value.\n */\n public interpolate: (lerp: number) => number;\n /**\n * A custom easing method for this list.\n * @param lerp The interpolation value from 0-1.\n * @return The eased value, also from 0-1.\n */\n public ease: SimpleEase;\n /**\n * If this list manages colors, which requires a different method for interpolation.\n */\n private isColor: boolean;\n\n /**\n * @param isColor If this list handles color values\n */\n constructor(isColor = false)\n {\n this.first = null;\n this.isColor = !!isColor;\n this.interpolate = null;\n this.ease = null;\n }\n\n /**\n * Resets the list for use.\n * @param first The first node in the list.\n * @param first.isStepped If the values should be stepped instead of interpolated linearly.\n */\n public reset(first: PropertyNode): void\n {\n this.first = first;\n const isSimple = first.next && first.next.time >= 1;\n\n if (isSimple)\n {\n this.interpolate = this.isColor ? intColorSimple : intValueSimple;\n }\n else if (first.isStepped)\n {\n this.interpolate = this.isColor ? intColorStepped : intValueStepped;\n }\n else\n {\n this.interpolate = this.isColor ? intColorComplex : intValueComplex;\n }\n this.ease = this.first.ease;\n }\n}\n","import { Particle } from '../Particle';\nimport { PropertyList } from '../PropertyList';\nimport { PropertyNode, ValueList } from '../PropertyNode';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * An Alpha behavior that applies an interpolated or stepped list of values to the particle's opacity.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'alpha',\n * config: {\n * alpha: {\n * list: [{value: 0, time: 0}, {value: 1, time: 0.25}, {value: 0, time: 1}]\n * },\n * }\n * }\n * ```\n */\nexport class AlphaBehavior implements IEmitterBehavior\n{\n public static type = 'alpha';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private list: PropertyList;\n constructor(config: {\n /**\n * Transparency of the particles from 0 (transparent) to 1 (opaque)\n */\n alpha: ValueList;\n })\n {\n this.list = new PropertyList(false);\n this.list.reset(PropertyNode.createList(config.alpha));\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.alpha = this.list.first.value;\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle): void\n {\n particle.alpha = this.list.interpolate(particle.agePercent);\n }\n}\n\n/**\n * An Alpha behavior that applies a static value to the particle's opacity at particle initialization.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'alphaStatic',\n * config: {\n * alpha: 0.75,\n * }\n * }\n * ```\n */\nexport class StaticAlphaBehavior implements IEmitterBehavior\n{\n public static type = 'alphaStatic';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private value: number;\n constructor(config: {\n /**\n * Transparency of the particles from 0 (transparent) to 1 (opaque)\n */\n alpha: number;\n })\n {\n this.value = config.alpha;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.alpha = this.value;\n next = next.next;\n }\n }\n}\n","import { Texture } from '@pixi/core';\nimport { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { GetTextureFromString } from '../ParticleUtils';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * The format of a single animation to be used on a particle.\n */\nexport interface AnimatedParticleArt\n{\n /**\n * Framerate for the animation (in frames per second). A value of -1 will tie the framerate to\n * the particle's lifetime so that the animation lasts exactly as long as the particle.\n */\n framerate: -1|number;\n /**\n * If the animation should loop. Defaults to false.\n */\n loop?: boolean;\n /**\n * A list of textures or frame descriptions for duplicated frames.\n * String values will be converted to textures with {@link ParticleUtils.GetTextureFromString}.\n * Example of a texture repeated for 5 frames, followed by a second texture for one frame:\n * ```javascript\n * [{texture: 'myFirstTex', count: 5}, 'mySecondTex']\n * ```\n */\n textures: (string|Texture|{texture: string|Texture; count: number})[];\n}\n\n/**\n * Internal data format for playback.\n */\nexport interface ParsedAnimatedParticleArt\n{\n textures: Texture[];\n duration: number;\n framerate: number;\n loop: boolean;\n}\n\nfunction getTextures(textures: (string|Texture|{texture: string|Texture; count: number})[]): Texture[]\n{\n const outTextures: Texture[] = [];\n\n for (let j = 0; j < textures.length; ++j)\n {\n let tex = textures[j];\n\n if (typeof tex === 'string')\n {\n outTextures.push(GetTextureFromString(tex));\n }\n else if (tex instanceof Texture)\n {\n outTextures.push(tex);\n }\n // assume an object with extra data determining duplicate frame data\n else\n {\n let dupe = tex.count || 1;\n\n if (typeof tex.texture === 'string')\n {\n tex = GetTextureFromString(tex.texture);\n }\n else// if(tex.texture instanceof Texture)\n {\n tex = tex.texture;\n }\n for (; dupe > 0; --dupe)\n {\n outTextures.push(tex);\n }\n }\n }\n\n return outTextures;\n}\n\n/**\n * A Texture behavior that picks a random animation for each particle to play.\n * See {@link AnimatedParticleArt} for detailed configuration info.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'animatedRandom',\n * config: {\n * anims: [\n * {\n * framerate: 25,\n * loop: true,\n * textures: ['frame1', 'frame2', 'frame3']\n * },\n * {\n * framerate: 25,\n * loop: true,\n * textures: ['frame3', 'frame2', 'frame1']\n * }\n * ],\n * }\n * }\n * ```\n */\nexport class RandomAnimatedTextureBehavior implements IEmitterBehavior\n{\n public static type = 'animatedRandom';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private anims: ParsedAnimatedParticleArt[];\n constructor(config: {\n /**\n * Animation configuration to use for each particle, randomly chosen from the list.\n */\n anims: AnimatedParticleArt[];\n })\n {\n this.anims = [];\n for (let i = 0; i < config.anims.length; ++i)\n {\n const anim = config.anims[i];\n const textures = getTextures(anim.textures);\n // eslint-disable-next-line no-nested-ternary\n const framerate = anim.framerate < 0 ? -1 : (anim.framerate > 0 ? anim.framerate : 60);\n const parsedAnim: ParsedAnimatedParticleArt = {\n textures,\n duration: framerate > 0 ? textures.length / framerate : 0,\n framerate,\n loop: framerate > 0 ? !!anim.loop : false,\n };\n\n this.anims.push(parsedAnim);\n }\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const index = Math.floor(Math.random() * this.anims.length);\n const anim = next.config.anim = this.anims[index];\n\n next.texture = anim.textures[0];\n next.config.animElapsed = 0;\n // if anim should match particle life exactly\n if (anim.framerate === -1)\n {\n next.config.animDuration = next.maxLife;\n next.config.animFramerate = anim.textures.length / next.maxLife;\n }\n else\n {\n next.config.animDuration = anim.duration;\n next.config.animFramerate = anim.framerate;\n }\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n const config = particle.config;\n const anim = config.anim;\n\n config.animElapsed += deltaSec;\n if (config.animElapsed >= config.animDuration)\n {\n // loop elapsed back around\n if (config.anim.loop)\n {\n config.animElapsed = config.animElapsed % config.animDuration;\n }\n // subtract a small amount to prevent attempting to go past the end of the animation\n else\n {\n config.animElapsed = config.animDuration - 0.000001;\n }\n }\n // add a very small number to the frame and then floor it to avoid\n // the frame being one short due to floating point errors.\n const frame = ((config.animElapsed * config.animFramerate) + 0.0000001) | 0;\n\n // in the very rare case that framerate * elapsed math ends up going past the end, use the last texture\n particle.texture = anim.textures[frame] || anim.textures[anim.textures.length - 1] || Texture.EMPTY;\n }\n}\n\n/**\n * A Texture behavior that uses a single animation for each particle to play.\n * See {@link AnimatedParticleArt} for detailed configuration info.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'animatedSingle',\n * config: {\n * anim: {\n * framerate: 25,\n * loop: true,\n * textures: ['frame1', 'frame2', 'frame3']\n * }\n * }\n * }\n * ```\n */\nexport class SingleAnimatedTextureBehavior implements IEmitterBehavior\n{\n public static type = 'animatedSingle';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private anim: ParsedAnimatedParticleArt;\n constructor(config: {\n /**\n * Animation configuration to use for each particle.\n */\n anim: AnimatedParticleArt;\n })\n {\n const anim = config.anim;\n const textures = getTextures(anim.textures);\n // eslint-disable-next-line no-nested-ternary\n const framerate = anim.framerate < 0 ? -1 : (anim.framerate > 0 ? anim.framerate : 60);\n\n this.anim = {\n textures,\n duration: framerate > 0 ? textures.length / framerate : 0,\n framerate,\n loop: framerate > 0 ? !!anim.loop : false,\n };\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n const anim = this.anim;\n\n while (next)\n {\n next.texture = anim.textures[0];\n next.config.animElapsed = 0;\n // if anim should match particle life exactly\n if (anim.framerate === -1)\n {\n next.config.animDuration = next.maxLife;\n next.config.animFramerate = anim.textures.length / next.maxLife;\n }\n else\n {\n next.config.animDuration = anim.duration;\n next.config.animFramerate = anim.framerate;\n }\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n const anim = this.anim;\n const config = particle.config;\n\n config.animElapsed += deltaSec;\n if (config.animElapsed >= config.animDuration)\n {\n // loop elapsed back around\n if (anim.loop)\n {\n config.animElapsed = config.animElapsed % config.animDuration;\n }\n // subtract a small amount to prevent attempting to go past the end of the animation\n else\n {\n config.animElapsed = config.animDuration - 0.000001;\n }\n }\n // add a very small number to the frame and then floor it to avoid\n // the frame being one short due to floating point errors.\n const frame = ((config.animElapsed * config.animFramerate) + 0.0000001) | 0;\n\n // in the very rare case that framerate * elapsed math ends up going past the end, use the last texture\n particle.texture = anim.textures[frame] || anim.textures[anim.textures.length - 1] || Texture.EMPTY;\n }\n}\n","import { Particle } from '../Particle';\nimport { getBlendMode } from '../ParticleUtils';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Blend Mode behavior that applies a blend mode value to the particle at initialization.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'blendMode',\n * config: {\n * blendMode: 'multiply',\n * }\n * }\n * ```\n */\nexport class BlendModeBehavior implements IEmitterBehavior\n{\n public static type = 'blendMode';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private value: string;\n constructor(config: {\n /**\n * Blend mode of all particles. This value is a key from\n * [PixiJs's BLEND_MODE enum](https://pixijs.download/release/docs/PIXI.html#BLEND_MODES).\n */\n blendMode: string;\n })\n {\n this.value = config.blendMode;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.blendMode = getBlendMode(this.value);\n next = next.next;\n }\n }\n}\n","import { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { DEG_TO_RADS, rotatePoint } from '../ParticleUtils';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Spawn behavior that sends particles out from a single point or ring, and is capable of evenly spacing\n * the particle's starting angles.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'spawnBurst',\n * config: {\n * spacing: 90,\n * start: 0,\n * distance: 40,\n * }\n * }\n * ```\n */\nexport class BurstSpawnBehavior implements IEmitterBehavior\n{\n public static type = 'spawnBurst';\n public static editorConfig: BehaviorEditorConfig = null;\n\n order = BehaviorOrder.Spawn;\n private spacing: number;\n private start: number;\n private distance: number;\n\n constructor(config: {\n /**\n * Description: Spacing between each particle spawned in a wave, in degrees.\n */\n spacing: number;\n /**\n * Description: Angle to start placing particles at, in degrees. 0 is facing right, 90 is facing upwards.\n */\n start: number;\n /**\n * Description: Distance from the emitter to spawn particles, forming a ring/arc.\n */\n distance: number;\n })\n {\n this.spacing = config.spacing * DEG_TO_RADS;\n this.start = config.start * DEG_TO_RADS;\n this.distance = config.distance;\n }\n\n initParticles(first: Particle): void\n {\n let count = 0;\n let next = first;\n\n while (next)\n {\n let angle: number;\n\n if (this.spacing)\n {\n angle = this.start + (this.spacing * count);\n }\n else\n {\n angle = Math.random() * Math.PI * 2;\n }\n\n next.rotation = angle;\n if (this.distance)\n {\n next.position.x = this.distance;\n rotatePoint(angle, next.position);\n }\n next = next.next;\n ++count;\n }\n }\n}\n","import { Particle } from '../Particle';\nimport { Color, combineRGBComponents } from '../ParticleUtils';\nimport { PropertyList } from '../PropertyList';\nimport { PropertyNode, ValueList } from '../PropertyNode';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Color behavior that applies an interpolated or stepped list of values to the particle's tint property.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'color',\n * config: {\n * color: {\n * list: [{value: '#ff0000' time: 0}, {value: '#00ff00', time: 0.5}, {value: '#0000ff', time: 1}]\n * },\n * }\n * }\n * ```\n */\nexport class ColorBehavior implements IEmitterBehavior\n{\n public static type = 'color';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private list: PropertyList;\n constructor(config: {\n /**\n * Color of the particles as 6 digit hex codes.\n */\n color: ValueList;\n })\n {\n this.list = new PropertyList(true);\n this.list.reset(PropertyNode.createList(config.color));\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n const color = this.list.first.value;\n const tint = combineRGBComponents(color.r, color.g, color.b);\n\n while (next)\n {\n next.tint = tint;\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle): void\n {\n particle.tint = this.list.interpolate(particle.agePercent);\n }\n}\n\n/**\n * A Color behavior that applies a single color to the particle's tint property at initialization.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'colorStatic',\n * config: {\n * color: '#ffff00',\n * }\n * }\n * ```\n */\nexport class StaticColorBehavior implements IEmitterBehavior\n{\n public static type = 'colorStatic';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private value: number;\n constructor(config: {\n /**\n * Color of the particles as 6 digit hex codes.\n */\n color: string;\n })\n {\n let color = config.color;\n\n if (color.charAt(0) === '#')\n {\n color = color.substr(1);\n }\n else if (color.indexOf('0x') === 0)\n {\n color = color.substr(2);\n }\n\n this.value = parseInt(color, 16);\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.tint = this.value;\n next = next.next;\n }\n }\n}\n","import { Texture } from '@pixi/core';\nimport { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { GetTextureFromString } from '../ParticleUtils';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Texture behavior that assigns a texture to each particle from its list, in order, before looping around to the first\n * texture again. String values will be converted to textures with {@link ParticleUtils.GetTextureFromString}.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'textureOrdered',\n * config: {\n * textures: [\"myTex1Id\", \"myTex2Id\", \"myTex3Id\", \"myTex4Id\"],\n * }\n * }\n * ```\n */\nexport class OrderedTextureBehavior implements IEmitterBehavior\n{\n public static type = 'textureOrdered';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private textures: Texture[];\n private index: number;\n constructor(config: {\n /**\n * Images to use for each particle, used in order before looping around\n */\n textures: Texture[];\n })\n {\n this.index = 0;\n this.textures = config.textures.map((tex) => (typeof tex === 'string' ? GetTextureFromString(tex) : tex));\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.texture = this.textures[this.index];\n if (++this.index >= this.textures.length)\n {\n this.index = 0;\n }\n next = next.next;\n }\n }\n}\n","import { Point } from '@pixi/math';\nimport { Particle } from '../Particle';\nimport { rotatePoint, verbose } from '../ParticleUtils';\nimport { PropertyList } from '../PropertyList';\nimport { PropertyNode, ValueList } from '../PropertyNode';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A helper point for math things.\n * @hidden\n */\nconst helperPoint = new Point();\n\n/**\n * A hand picked list of Math functions (and a couple properties) that are\n * allowable. They should be used without the preceding \"Math.\"\n * @hidden\n */\nconst MATH_FUNCS = [\n 'E',\n 'LN2',\n 'LN10',\n 'LOG2E',\n 'LOG10E',\n 'PI',\n 'SQRT1_2',\n 'SQRT2',\n 'abs',\n 'acos',\n 'acosh',\n 'asin',\n 'asinh',\n 'atan',\n 'atanh',\n 'atan2',\n 'cbrt',\n 'ceil',\n 'cos',\n 'cosh',\n 'exp',\n 'expm1',\n 'floor',\n 'fround',\n 'hypot',\n 'log',\n 'log1p',\n 'log10',\n 'log2',\n 'max',\n 'min',\n 'pow',\n 'random',\n 'round',\n 'sign',\n 'sin',\n 'sinh',\n 'sqrt',\n 'tan',\n 'tanh',\n];\n/**\n * create an actual regular expression object from the string\n * @hidden\n */\nconst WHITELISTER = new RegExp(\n [\n // Allow the 4 basic operations, parentheses and all numbers/decimals, as well\n // as 'x', for the variable usage.\n '[01234567890\\\\.\\\\*\\\\-\\\\+\\\\/\\\\(\\\\)x ,]',\n ].concat(MATH_FUNCS).join('|'),\n 'g',\n);\n\n/**\n * Parses a string into a function for path following.\n * This involves whitelisting the string for safety, inserting \"Math.\" to math function\n * names, and using `new Function()` to generate a function.\n * @hidden\n * @param pathString The string to parse.\n * @return The path function - takes x, outputs y.\n */\nfunction parsePath(pathString: string): (x: number) => number\n{\n const matches = pathString.match(WHITELISTER);\n\n for (let i = matches.length - 1; i >= 0; --i)\n {\n if (MATH_FUNCS.indexOf(matches[i]) >= 0)\n { matches[i] = `Math.${matches[i]}`; }\n }\n pathString = matches.join('');\n\n // eslint-disable-next-line no-new-func\n return new Function('x', `return ${pathString};`) as (x: number) => number;\n}\n\n/**\n * A particle that follows a path defined by an algebraic expression, e.g. \"sin(x)\" or\n * \"5x + 3\".\n * To use this class, the behavior config must have a \"path\" string or function.\n *\n * A string should have \"x\" in it to represent movement (from the\n * speed settings of the behavior). It may have numbers, parentheses, the four basic\n * operations, and any Math functions or properties (without the preceding \"Math.\").\n * The overall movement of the particle and the expression value become x and y positions for\n * the particle, respectively. The final position is rotated by the spawn rotation/angle of\n * the particle.\n *\n * A function merely needs to accept the \"x\" argument and output the a corresponding \"y\" value.\n *\n * Some example paths:\n *\n * * `\"sin(x/10) * 20\"` A sine wave path.\n * * `\"cos(x/100) * 30\"` Particles curve counterclockwise (for medium speed/low lifetime particles)\n * * `\"pow(x/10, 2) / 2\"` Particles curve clockwise (remember, +y is down).\n * * `(x) => Math.floor(x) * 3` Supplying an existing function should look like this\n *\n * Example configuration:\n * ```javascript\n * {\n * \"type\": \"movePath\",\n * \"config\": {\n * \"path\": \"round(sin(x) * 2\",\n * \"speed\": {\n * \"list\": [{value: 10, time: 0}, {value: 100, time: 0.25}, {value: 0, time: 1}],\n * },\n * \"minMult\": 0.8\n * }\n *}\n */\nexport class PathBehavior implements IEmitterBehavior\n{\n public static type = 'movePath';\n public static editorConfig: BehaviorEditorConfig = null;\n\n // *MUST* happen after other behaviors do initialization so that we can read initial transformations\n public order = BehaviorOrder.Late;\n /**\n * The function representing the path the particle should take.\n */\n private path: (x: number) => number;\n private list: PropertyList;\n private minMult: number;\n constructor(config: {\n /**\n * Algebraic expression describing the movement of the particle.\n */\n path: string|((x: number) => number);\n /**\n * Speed of the particles in world units/second. This affects the x value in the path.\n * Unlike normal speed movement, this can have negative values.\n */\n speed: ValueList;\n /**\n * A value between minimum speed multipler and 1 is randomly generated and multiplied\n * with each speed value to generate the actual speed for each particle.\n */\n minMult: number;\n })\n {\n if (config.path)\n {\n if (typeof config.path === 'function')\n {\n this.path = config.path;\n }\n else\n {\n try\n {\n this.path = parsePath(config.path);\n }\n catch (e)\n {\n if (verbose)\n {\n console.error('PathParticle: error in parsing path expression', e);\n }\n this.path = null;\n }\n }\n }\n else\n {\n if (verbose)\n {\n console.error('PathParticle requires a path value in its config!');\n }\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n this.path = (x) => x;\n }\n this.list = new PropertyList(false);\n this.list.reset(PropertyNode.createList(config.speed));\n this.minMult = config.minMult ?? 1;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n /*\n * The initial rotation in degrees of the particle, because the direction of the path\n * is based on that.\n */\n next.config.initRotation = next.rotation;\n /* The initial position of the particle, as all path movement is added to that. */\n if (!next.config.initPosition)\n {\n next.config.initPosition = new Point(next.x, next.y);\n }\n else\n {\n (next.config.initPosition as Point).copyFrom(next.position);\n }\n /* Total single directional movement, due to speed. */\n next.config.movement = 0;\n\n // also do speed multiplier, since this includes basic speed movement\n const mult = (Math.random() * (1 - this.minMult)) + this.minMult;\n\n next.config.speedMult = mult;\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n // increase linear movement based on speed\n const speed = this.list.interpolate(particle.agePercent) * particle.config.speedMult;\n\n particle.config.movement += speed * deltaSec;\n // set up the helper point for rotation\n helperPoint.x = particle.config.movement;\n helperPoint.y = this.path(helperPoint.x);\n rotatePoint(particle.config.initRotation, helperPoint);\n particle.position.x = particle.config.initPosition.x + helperPoint.x;\n particle.position.y = particle.config.initPosition.y + helperPoint.y;\n }\n}\n","import { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Spawn behavior that sends particles out from a single point at the emitter's position.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'spawnPoint',\n * config: {}\n * }\n * ```\n */\nexport class PointSpawnBehavior implements IEmitterBehavior\n{\n public static type = 'spawnPoint';\n public static editorConfig: BehaviorEditorConfig = null;\n\n order = BehaviorOrder.Spawn;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n initParticles(_first: Particle): void\n {\n // really just a no-op\n }\n}\n","import { Texture } from '@pixi/core';\nimport { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { GetTextureFromString } from '../ParticleUtils';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Texture behavior that assigns a random texture to each particle from its list.\n * String values will be converted to textures with {@link ParticleUtils.GetTextureFromString}.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'textureRandom',\n * config: {\n * textures: [\"myTex1Id\", \"myTex2Id\", \"myTex3Id\", \"myTex4Id\"],\n * }\n * }\n * ```\n */\nexport class RandomTextureBehavior implements IEmitterBehavior\n{\n public static type = 'textureRandom';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private textures: Texture[];\n constructor(config: {\n /**\n * Images to use for each particle, randomly chosen from the list.\n */\n textures: (Texture|string)[];\n })\n {\n this.textures = config.textures.map((tex) => (typeof tex === 'string' ? GetTextureFromString(tex) : tex));\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const index = Math.floor(Math.random() * this.textures.length);\n\n next.texture = this.textures[index];\n\n next = next.next;\n }\n }\n}\n","import { Particle } from '../Particle';\nimport { DEG_TO_RADS } from '../ParticleUtils';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Rotation behavior that handles starting rotation, rotation speed, and rotational acceleration.\n *\n * Example configuration:\n * ```javascript\n * {\n * \"type\": \"rotation\",\n * \"config\": {\n * \"minStart\": 0,\n * \"maxStart\": 180,\n * \"minSpeed\": 30,\n * \"maxSpeed\": 45,\n * \"accel\": 20\n * }\n *}\n * ```\n */\nexport class RotationBehavior implements IEmitterBehavior\n{\n public static type = 'rotation';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private minStart: number;\n private maxStart: number;\n private minSpeed: number;\n private maxSpeed: number;\n private accel: number;\n constructor(config: {\n /**\n * Minimum starting rotation of the particles, in degrees. 0 is facing right, 90 is upwards.\n */\n minStart: number;\n /**\n * Maximum starting rotation of the particles, in degrees. 0 is facing right, 90 is upwards.\n */\n maxStart: number;\n /**\n * Minimum rotation speed of the particles, in degrees/second. Positive is counter-clockwise.\n */\n minSpeed: number;\n /**\n * Maximum rotation speed of the particles, in degrees/second. Positive is counter-clockwise.\n */\n maxSpeed: number;\n /**\n * Constant rotational acceleration of the particles, in degrees/second/second.\n */\n accel: number;\n })\n {\n this.minStart = config.minStart * DEG_TO_RADS;\n this.maxStart = config.maxStart * DEG_TO_RADS;\n this.minSpeed = config.minSpeed * DEG_TO_RADS;\n this.maxSpeed = config.maxSpeed * DEG_TO_RADS;\n this.accel = config.accel * DEG_TO_RADS;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n if (this.minStart === this.maxStart)\n {\n next.rotation += this.maxStart;\n }\n else\n {\n next.rotation += (Math.random() * (this.maxStart - this.minStart)) + this.minStart;\n }\n next.config.rotSpeed = (Math.random() * (this.maxSpeed - this.minSpeed)) + this.minSpeed;\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n if (this.accel)\n {\n const oldSpeed = particle.config.rotSpeed;\n\n particle.config.rotSpeed += this.accel * deltaSec;\n particle.rotation += (particle.config.rotSpeed + oldSpeed) / 2 * deltaSec;\n }\n else\n {\n particle.rotation += particle.config.rotSpeed * deltaSec;\n }\n }\n}\n\n/**\n * A Rotation behavior that handles starting rotation.\n *\n * Example configuration:\n * ```javascript\n * {\n * \"type\": \"rotationStatic\",\n * \"config\": {\n * \"min\": 0,\n * \"max\": 180,\n * }\n *}\n * ```\n */\nexport class StaticRotationBehavior implements IEmitterBehavior\n{\n public static type = 'rotationStatic';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private min: number;\n private max: number;\n constructor(config: {\n /**\n * Minimum starting rotation of the particles, in degrees. 0 is facing right, 90 is upwards.\n */\n min: number;\n /**\n * Maximum starting rotation of the particles, in degrees. 0 is facing right, 90 is upwards.\n */\n max: number;\n })\n {\n this.min = config.min * DEG_TO_RADS;\n this.max = config.max * DEG_TO_RADS;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n if (this.min === this.max)\n {\n next.rotation += this.max;\n }\n else\n {\n next.rotation += (Math.random() * (this.max - this.min)) + this.min;\n }\n\n next = next.next;\n }\n }\n}\n\n/**\n * A Rotation behavior that blocks all rotation caused by spawn settings,\n * by resetting it to the specified rotation (or 0).\n *\n * Example configuration:\n * ```javascript\n * {\n * \"type\": \"noRotation\",\n * \"config\": {\n * \"rotation\": 0\n * }\n *}\n * ```\n */\nexport class NoRotationBehavior implements IEmitterBehavior\n{\n public static type = 'noRotation';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Late + 1;\n\n private rotation: number;\n constructor(config: {\n /**\n * Locked rotation of the particles, in degrees. 0 is facing right, 90 is upwards.\n */\n rotation?: number;\n })\n {\n this.rotation = (config.rotation || 0) * DEG_TO_RADS;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.rotation = this.rotation;\n\n next = next.next;\n }\n }\n}\n","import { Particle } from '../Particle';\nimport { PropertyList } from '../PropertyList';\nimport { PropertyNode, ValueList } from '../PropertyNode';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Scale behavior that applies an interpolated or stepped list of values to the particle's x & y scale.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'scale',\n * config: {\n * scale: {\n * list: [{value: 0, time: 0}, {value: 1, time: 0.25}, {value: 0, time: 1}],\n * isStepped: true\n * },\n * minMult: 0.5\n * }\n * }\n * ```\n */\nexport class ScaleBehavior implements IEmitterBehavior\n{\n public static type = 'scale';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private list: PropertyList;\n private minMult: number;\n constructor(config: {\n /**\n * Scale of the particles, with a minimum value of 0\n */\n scale: ValueList;\n /**\n * A value between minimum scale multipler and 1 is randomly\n * generated and multiplied with each scale value to provide the actual scale for each particle.\n */\n minMult: number;\n })\n {\n this.list = new PropertyList(false);\n this.list.reset(PropertyNode.createList(config.scale));\n this.minMult = config.minMult ?? 1;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const mult = (Math.random() * (1 - this.minMult)) + this.minMult;\n\n next.config.scaleMult = mult;\n next.scale.x = next.scale.y = this.list.first.value * mult;\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle): void\n {\n particle.scale.x = particle.scale.y = this.list.interpolate(particle.agePercent) * particle.config.scaleMult;\n }\n}\n\n/**\n * A Scale behavior that applies a randomly picked value to the particle's x & y scale at initialization.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'scaleStatic',\n * config: {\n * min: 0.25,\n * max: 0.75,\n * }\n * }\n * ```\n */\nexport class StaticScaleBehavior implements IEmitterBehavior\n{\n public static type = 'scaleStatic';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private min: number;\n private max: number;\n constructor(config: {\n /**\n * Minimum scale of the particles, with a minimum value of 0\n */\n min: number;\n /**\n * Maximum scale of the particles, with a minimum value of 0\n */\n max: number;\n })\n {\n this.min = config.min;\n this.max = config.max;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const scale = (Math.random() * (this.max - this.min)) + this.min;\n\n next.scale.x = next.scale.y = scale;\n\n next = next.next;\n }\n }\n}\n","import { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { SpawnShape, SpawnShapeClass } from './shapes/SpawnShape';\nimport { PolygonalChain } from './shapes/PolygonalChain';\nimport { Rectangle } from './shapes/Rectangle';\nimport { Torus } from './shapes/Torus';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Spawn behavior that places (and optionally rotates) particles according to a\n * specified shape. Additional shapes can be registered with {@link registerShape | SpawnShape.registerShape()}.\n * Additional shapes must implement the {@link SpawnShape} interface, and their class must match the\n * {@link SpawnShapeClass} interface.\n * Shapes included by default are:\n * * {@link Rectangle}\n * * {@link Torus}\n * * {@link PolygonalChain}\n *\n * Example config:\n * ```javascript\n * {\n * type: 'spawnShape',\n * config: {\n * type: 'rect',\n * data: {\n * x: 0,\n * y: 0,\n * width: 20,\n * height: 300,\n * }\n * }\n * }\n * ```\n */\nexport class ShapeSpawnBehavior implements IEmitterBehavior\n{\n public static type = 'spawnShape';\n public static editorConfig: BehaviorEditorConfig = null;\n\n /**\n * Dictionary of all registered shape classes.\n */\n private static shapes: {[key: string]: SpawnShapeClass} = {};\n\n /**\n * Registers a shape to be used by the ShapeSpawn behavior.\n * @param constructor The shape class constructor to use, with a static `type` property to reference it by.\n * @param typeOverride An optional type override, primarily for registering a shape under multiple names.\n */\n public static registerShape(constructor: SpawnShapeClass, typeOverride?: string): void\n {\n ShapeSpawnBehavior.shapes[typeOverride || constructor.type] = constructor;\n }\n\n order = BehaviorOrder.Spawn;\n private shape: SpawnShape;\n\n constructor(config: {\n /**\n * Type of the shape to spawn\n */\n type: string;\n /**\n * Configuration data for the spawn shape.\n */\n data: any;\n })\n {\n const ShapeClass = ShapeSpawnBehavior.shapes[config.type];\n\n if (!ShapeClass)\n {\n throw new Error(`No shape found with type '${config.type}'`);\n }\n this.shape = new ShapeClass(config.data);\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n this.shape.getRandPos(next);\n next = next.next;\n }\n }\n}\n\nShapeSpawnBehavior.registerShape(PolygonalChain);\nShapeSpawnBehavior.registerShape(Rectangle);\nShapeSpawnBehavior.registerShape(Torus);\nShapeSpawnBehavior.registerShape(Torus, 'circle');\n","import { Texture } from '@pixi/core';\nimport { Particle } from '../Particle';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { GetTextureFromString } from '../ParticleUtils';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Textuure behavior that assigns a single texture to each particle.\n * String values will be converted to textures with {@link ParticleUtils.GetTextureFromString}.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'textureSingle',\n * config: {\n * texture: Texture.from('myTexId'),\n * }\n * }\n * ```\n */\nexport class SingleTextureBehavior implements IEmitterBehavior\n{\n public static type = 'textureSingle';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Normal;\n private texture: Texture;\n constructor(config: {\n /**\n * Image to use for each particle.\n */\n texture: Texture|string;\n })\n {\n this.texture = typeof config.texture === 'string' ? GetTextureFromString(config.texture) : config.texture;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n next.texture = this.texture;\n\n next = next.next;\n }\n }\n}\n","import { Point } from '@pixi/math';\nimport { Particle } from '../Particle';\nimport { rotatePoint, normalize, scaleBy } from '../ParticleUtils';\nimport { PropertyList } from '../PropertyList';\nimport { PropertyNode, ValueList } from '../PropertyNode';\nimport { IEmitterBehavior, BehaviorOrder } from './Behaviors';\nimport { BehaviorEditorConfig } from './editor/Types';\n\n/**\n * A Movement behavior that uses an interpolated or stepped list of values for a particles speed at any given moment.\n * Movement direction is controlled by the particle's starting rotation.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'moveSpeed',\n * config: {\n * speed: {\n * list: [{value: 10, time: 0}, {value: 100, time: 0.25}, {value: 0, time: 1}],\n * },\n * minMult: 0.8\n * }\n * }\n * ```\n */\nexport class SpeedBehavior implements IEmitterBehavior\n{\n public static type = 'moveSpeed';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Late;\n private list: PropertyList;\n private minMult: number;\n constructor(config: {\n /**\n * Speed of the particles in world units/second, with a minimum value of 0\n */\n speed: ValueList;\n /**\n * A value between minimum speed multipler and 1 is randomly\n * generated and multiplied with each speed value to generate the actual speed for each particle.\n */\n minMult: number;\n })\n {\n this.list = new PropertyList(false);\n this.list.reset(PropertyNode.createList(config.speed));\n this.minMult = config.minMult ?? 1;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const mult = (Math.random() * (1 - this.minMult)) + this.minMult;\n\n next.config.speedMult = mult;\n if (!next.config.velocity)\n {\n next.config.velocity = new Point(this.list.first.value * mult, 0);\n }\n else\n {\n (next.config.velocity as Point).set(this.list.first.value * mult, 0);\n }\n\n rotatePoint(next.rotation, next.config.velocity);\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n const speed = this.list.interpolate(particle.agePercent) * particle.config.speedMult;\n const vel = particle.config.velocity;\n\n normalize(vel);\n scaleBy(vel, speed);\n particle.x += vel.x * deltaSec;\n particle.y += vel.y * deltaSec;\n }\n}\n\n/**\n * A Movement behavior that uses a randomly picked constant speed throughout a particle's lifetime.\n * Movement direction is controlled by the particle's starting rotation.\n *\n * Example config:\n * ```javascript\n * {\n * type: 'moveSpeedStatic',\n * config: {\n * min: 100,\n * max: 150\n * }\n * }\n * ```\n */\nexport class StaticSpeedBehavior implements IEmitterBehavior\n{\n public static type = 'moveSpeedStatic';\n public static editorConfig: BehaviorEditorConfig = null;\n\n public order = BehaviorOrder.Late;\n private min: number;\n private max: number;\n constructor(config: {\n /**\n * Minimum speed when initializing the particle.\n */\n min: number;\n /**\n * Maximum speed when initializing the particle.\n */\n max: number;\n })\n {\n this.min = config.min;\n this.max = config.max;\n }\n\n initParticles(first: Particle): void\n {\n let next = first;\n\n while (next)\n {\n const speed = (Math.random() * (this.max - this.min)) + this.min;\n\n if (!next.config.velocity)\n {\n next.config.velocity = new Point(speed, 0);\n }\n else\n {\n (next.config.velocity as Point).set(speed, 0);\n }\n\n rotatePoint(next.rotation, next.config.velocity);\n\n next = next.next;\n }\n }\n\n updateParticle(particle: Particle, deltaSec: number): void\n {\n const velocity = particle.config.velocity;\n\n particle.x += velocity.x * deltaSec;\n particle.y += velocity.y * deltaSec;\n }\n}\n","import { Container, DisplayObject } from '@pixi/display';\nimport { Renderer, MaskData } from '@pixi/core';\nimport { Rectangle } from '@pixi/math';\n\n/** Interface for a child of a LinkedListContainer (has the prev/next properties added) */\nexport interface LinkedListChild extends DisplayObject\n{\n nextChild: LinkedListChild|null;\n prevChild: LinkedListChild|null;\n}\n\n/**\n * A semi-experimental Container that uses a doubly linked list to manage children instead of an\n * array. This means that adding/removing children often is not the same performance hit that\n * it would to be continually pushing/splicing.\n * However, this is primarily intended to be used for heavy particle usage, and may not handle\n * edge cases well if used as a complete Container replacement.\n */\nexport class LinkedListContainer extends Container\n{\n private _firstChild: LinkedListChild|null = null;\n private _lastChild: LinkedListChild|null = null;\n private _childCount = 0;\n\n public get firstChild(): LinkedListChild\n {\n return this._firstChild;\n }\n\n public get lastChild(): LinkedListChild\n {\n return this._lastChild;\n }\n\n public get childCount(): number\n {\n return this._childCount;\n }\n\n public addChild(...children: T): T[0]\n {\n // if there is only one argument we can bypass looping through the them\n if (children.length > 1)\n {\n // loop through the array and add all children\n for (let i = 0; i < children.length; i++)\n {\n // eslint-disable-next-line prefer-rest-params\n this.addChild(children[i]);\n }\n }\n else\n {\n const child = children[0] as LinkedListChild;\n // if the child has a parent then lets remove it as PixiJS objects can only exist in one place\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n child.transform._parentID = -1;\n\n // add to list if we have a list\n if (this._lastChild)\n {\n this._lastChild.nextChild = child;\n child.prevChild = this._lastChild;\n this._lastChild = child;\n }\n // otherwise initialize the list\n else\n {\n this._firstChild = this._lastChild = child;\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n }\n\n return children[0];\n }\n\n public addChildAt(child: T, index: number): T\n {\n if (index < 0 || index > this._childCount)\n {\n throw new Error(`addChildAt: The index ${index} supplied is out of bounds ${this._childCount}`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n child.transform._parentID = -1;\n\n const c = (child as any) as LinkedListChild;\n\n // if no children, do basic initialization\n if (!this._firstChild)\n {\n this._firstChild = this._lastChild = c;\n }\n // add at beginning (back)\n else if (index === 0)\n {\n this._firstChild.prevChild = c;\n c.nextChild = this._firstChild;\n this._firstChild = c;\n }\n // add at end (front)\n else if (index === this._childCount)\n {\n this._lastChild.nextChild = c;\n c.prevChild = this._lastChild;\n this._lastChild = c;\n }\n // otherwise we have to start counting through the children to find the right one\n // - SLOW, only provided to fully support the possibility of use\n else\n {\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n // insert before the target that we found at the specified index\n target.prevChild.nextChild = c;\n c.prevChild = target.prevChild;\n c.nextChild = target;\n target.prevChild = c;\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange(index);\n child.emit('added', this);\n this.emit('childAdded', child, this, index);\n\n return child;\n }\n\n /**\n * Adds a child to the container to be rendered below another child.\n *\n * @param child The child to add\n * @param relative - The current child to add the new child relative to.\n * @return The child that was added.\n */\n public addChildBelow(child: T, relative: DisplayObject): T\n {\n if (relative.parent !== this)\n {\n throw new Error(`addChildBelow: The relative target must be a child of this parent`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n child.transform._parentID = -1;\n\n // insert before the target that we were given\n (relative as LinkedListChild).prevChild.nextChild = (child as any as LinkedListChild);\n (child as any as LinkedListChild).prevChild = (relative as LinkedListChild).prevChild;\n (child as any as LinkedListChild).nextChild = (relative as LinkedListChild);\n (relative as LinkedListChild).prevChild = (child as any as LinkedListChild);\n if (this._firstChild === relative)\n {\n this._firstChild = (child as any as LinkedListChild);\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n\n return child;\n }\n\n /**\n * Adds a child to the container to be rendered above another child.\n *\n * @param child The child to add\n * @param relative - The current child to add the new child relative to.\n * @return The child that was added.\n */\n public addChildAbove(child: T, relative: DisplayObject): T\n {\n if (relative.parent !== this)\n {\n throw new Error(`addChildBelow: The relative target must be a child of this parent`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n child.transform._parentID = -1;\n\n // insert after the target that we were given\n (relative as LinkedListChild).nextChild.prevChild = (child as any as LinkedListChild);\n (child as any as LinkedListChild).nextChild = (relative as LinkedListChild).nextChild;\n (child as any as LinkedListChild).prevChild = (relative as LinkedListChild);\n (relative as LinkedListChild).nextChild = (child as any as LinkedListChild);\n if (this._lastChild === relative)\n {\n this._lastChild = (child as any as LinkedListChild);\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n\n return child;\n }\n\n public swapChildren(child: DisplayObject, child2: DisplayObject): void\n {\n if (child === child2 || child.parent !== this || child2.parent !== this)\n {\n return;\n }\n\n const { prevChild, nextChild } = (child as LinkedListChild);\n\n (child as LinkedListChild).prevChild = (child2 as LinkedListChild).prevChild;\n (child as LinkedListChild).nextChild = (child2 as LinkedListChild).nextChild;\n (child2 as LinkedListChild).prevChild = prevChild;\n (child2 as LinkedListChild).nextChild = nextChild;\n\n if (this._firstChild === child)\n {\n this._firstChild = child2 as LinkedListChild;\n }\n else if (this._firstChild === child2)\n {\n this._firstChild = child as LinkedListChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child2 as LinkedListChild;\n }\n else if (this._lastChild === child2)\n {\n this._lastChild = child as LinkedListChild;\n }\n\n this.onChildrenChange();\n }\n\n public getChildIndex(child: DisplayObject): number\n {\n let index = 0;\n let test = this._firstChild;\n\n while (test)\n {\n if (test === child)\n {\n break;\n }\n test = test.nextChild;\n ++index;\n }\n if (!test)\n {\n throw new Error('The supplied DisplayObject must be a child of the caller');\n }\n\n return index;\n }\n\n setChildIndex(child: DisplayObject, index: number): void\n {\n if (index < 0 || index >= this._childCount)\n {\n throw new Error(`The index ${index} supplied is out of bounds ${this._childCount}`);\n }\n if (child.parent !== this)\n {\n throw new Error('The supplied DisplayObject must be a child of the caller');\n }\n\n // remove child\n if ((child as LinkedListChild).nextChild)\n {\n (child as LinkedListChild).nextChild.prevChild = (child as LinkedListChild).prevChild;\n }\n if ((child as LinkedListChild).prevChild)\n {\n (child as LinkedListChild).prevChild.nextChild = (child as LinkedListChild).nextChild;\n }\n if (this._firstChild === (child as LinkedListChild))\n {\n this._firstChild = (child as LinkedListChild).nextChild;\n }\n if (this._lastChild === (child as LinkedListChild))\n {\n this._lastChild = (child as LinkedListChild).prevChild;\n }\n (child as LinkedListChild).nextChild = null;\n (child as LinkedListChild).prevChild = null;\n\n // do addChildAt\n if (!this._firstChild)\n {\n this._firstChild = this._lastChild = (child as LinkedListChild);\n }\n else if (index === 0)\n {\n this._firstChild.prevChild = (child as LinkedListChild);\n (child as LinkedListChild).nextChild = this._firstChild;\n this._firstChild = (child as LinkedListChild);\n }\n else if (index === this._childCount)\n {\n this._lastChild.nextChild = (child as LinkedListChild);\n (child as LinkedListChild).prevChild = this._lastChild;\n this._lastChild = (child as LinkedListChild);\n }\n else\n {\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n target.prevChild.nextChild = (child as LinkedListChild);\n (child as LinkedListChild).prevChild = target.prevChild;\n (child as LinkedListChild).nextChild = target;\n target.prevChild = (child as LinkedListChild);\n }\n\n this.onChildrenChange(index);\n }\n\n public removeChild(...children: T): T[0]\n {\n // if there is only one argument we can bypass looping through the them\n if (children.length > 1)\n {\n // loop through the arguments property and remove all children\n for (let i = 0; i < children.length; i++)\n {\n this.removeChild(children[i]);\n }\n }\n else\n {\n const child = children[0] as LinkedListChild;\n\n // bail if not actually our child\n if (child.parent !== this) return null;\n\n child.parent = null;\n // ensure child transform will be recalculated\n child.transform._parentID = -1;\n\n // swap out child references\n if (child.nextChild)\n {\n child.nextChild.prevChild = child.prevChild;\n }\n if (child.prevChild)\n {\n child.prevChild.nextChild = child.nextChild;\n }\n if (this._firstChild === child)\n {\n this._firstChild = child.nextChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child.prevChild;\n }\n // clear sibling references\n child.nextChild = null;\n child.prevChild = null;\n\n // update child count\n --this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n child.emit('removed', this);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.emit('childRemoved', child, this);\n }\n\n return children[0];\n }\n\n public getChildAt(index: number): DisplayObject\n {\n if (index < 0 || index >= this._childCount)\n {\n throw new Error(`getChildAt: Index (${index}) does not exist.`);\n }\n\n if (index === 0)\n {\n return this._firstChild;\n }\n // add at end (front)\n else if (index === this._childCount)\n {\n return this._lastChild;\n }\n // otherwise we have to start counting through the children to find the right one\n // - SLOW, only provided to fully support the possibility of use\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n\n return target;\n }\n\n public removeChildAt(index: number): DisplayObject\n {\n const child = this.getChildAt(index) as LinkedListChild;\n\n // ensure child transform will be recalculated..\n child.parent = null;\n child.transform._parentID = -1;\n // swap out child references\n if (child.nextChild)\n {\n child.nextChild.prevChild = child.prevChild;\n }\n if (child.prevChild)\n {\n child.prevChild.nextChild = child.nextChild;\n }\n if (this._firstChild === child)\n {\n this._firstChild = child.nextChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child.prevChild;\n }\n // clear sibling references\n child.nextChild = null;\n child.prevChild = null;\n\n // update child count\n --this._childCount;\n\n // ensure bounds will be recalculated\n this._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange(index);\n child.emit('removed', this);\n this.emit('childRemoved', child, this, index);\n\n return child;\n }\n\n public removeChildren(beginIndex = 0, endIndex = this._childCount): DisplayObject[]\n {\n const begin = beginIndex;\n\n // because Container.destroy() has removeChildren(0, this.children.count), assume that an end index of 0\n // should actually be _childCount.\n if (endIndex === 0 && this._childCount > 0)\n {\n endIndex = this._childCount;\n }\n const end = endIndex;\n const range = end - begin;\n\n if (range > 0 && range <= end)\n {\n const removed: LinkedListChild[] = [];\n let child = this._firstChild;\n\n for (let i = 0; i <= end && child; ++i, child = child.nextChild)\n {\n if (i >= begin)\n {\n removed.push(child);\n }\n }\n\n // child before removed section\n const prevChild = removed[0].prevChild;\n // child after removed section\n const nextChild = removed[removed.length - 1].nextChild;\n\n if (!nextChild)\n {\n // if we removed the last child, then the new last child is the one before\n // the removed section\n this._lastChild = prevChild;\n }\n else\n {\n // otherwise, stitch the child before the section to the child after\n nextChild.prevChild = prevChild;\n }\n if (!prevChild)\n {\n // if we removed the first child, then the new first child is the one after\n // the removed section\n this._firstChild = nextChild;\n }\n else\n {\n // otherwise stich the child after the section to the one before\n prevChild.nextChild = nextChild;\n }\n\n for (let i = 0; i < removed.length; ++i)\n {\n // clear parenting and sibling references for all removed children\n removed[i].parent = null;\n if (removed[i].transform)\n {\n removed[i].transform._parentID = -1;\n }\n removed[i].nextChild = null;\n removed[i].prevChild = null;\n }\n\n this._boundsID++;\n\n this.onChildrenChange(beginIndex);\n\n for (let i = 0; i < removed.length; ++i)\n {\n removed[i].emit('removed', this);\n this.emit('childRemoved', removed[i], this, i);\n }\n\n return removed;\n }\n else if (range === 0 && this._childCount === 0)\n {\n return [];\n }\n\n throw new RangeError('removeChildren: numeric values are outside the acceptable range.');\n }\n\n /**\n * Updates the transform on all children of this container for rendering.\n * Copied from and overrides PixiJS v5 method (v4 method is identical)\n */\n updateTransform(): void\n {\n this._boundsID++;\n\n this.transform.updateTransform(this.parent.transform);\n\n // TODO: check render flags, how to process stuff here\n this.worldAlpha = this.alpha * this.parent.worldAlpha;\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (child.visible)\n {\n child.updateTransform();\n }\n }\n }\n\n /**\n * Recalculates the bounds of the container.\n * Copied from and overrides PixiJS v5 method (v4 method is identical)\n */\n calculateBounds(): void\n {\n this._bounds.clear();\n\n this._calculateBounds();\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (!child.visible || !child.renderable)\n {\n continue;\n }\n\n child.calculateBounds();\n\n // TODO: filter+mask, need to mask both somehow\n if (child._mask)\n {\n const maskObject = ((child._mask as MaskData).maskObject || child._mask) as Container;\n\n maskObject.calculateBounds();\n this._bounds.addBoundsMask(child._bounds, maskObject._bounds);\n }\n else if (child.filterArea)\n {\n this._bounds.addBoundsArea(child._bounds, child.filterArea);\n }\n else\n {\n this._bounds.addBounds(child._bounds);\n }\n }\n\n this._bounds.updateID = this._boundsID;\n }\n\n /**\n * Retrieves the local bounds of the displayObject as a rectangle object. Copied from and overrides PixiJS v5 method\n */\n public getLocalBounds(rect?: Rectangle, skipChildrenUpdate = false): Rectangle\n {\n // skip Container's getLocalBounds, go directly to DisplayObject\n const result = DisplayObject.prototype.getLocalBounds.call(this, rect);\n\n if (!skipChildrenUpdate)\n {\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (child.visible)\n {\n child.updateTransform();\n }\n }\n }\n\n return result;\n }\n\n /**\n * Renders the object using the WebGL renderer. Copied from and overrides PixiJS v5 method\n */\n render(renderer: Renderer): void\n {\n // if the object is not visible or the alpha is 0 then no need to render this element\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n // do a quick check to see if this element has a mask or a filter.\n if (this._mask || (this.filters && this.filters.length))\n {\n this.renderAdvanced(renderer);\n }\n else\n {\n this._render(renderer);\n\n let child;\n let next;\n\n // simple render children!\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n child.render(renderer);\n }\n }\n }\n\n /**\n * Render the object using the WebGL renderer and advanced features. Copied from and overrides PixiJS v5 method\n */\n protected renderAdvanced(renderer: Renderer): void\n {\n renderer.batch.flush();\n\n const filters = this.filters;\n const mask = this._mask;\n\n // _enabledFilters note: As of development, _enabledFilters is not documented in pixi.js\n // types but is in code of current release (5.2.4).\n\n // push filter first as we need to ensure the stencil buffer is correct for any masking\n if (filters)\n {\n if (!this._enabledFilters)\n {\n this._enabledFilters = [];\n }\n\n this._enabledFilters.length = 0;\n\n for (let i = 0; i < filters.length; i++)\n {\n if (filters[i].enabled)\n {\n this._enabledFilters.push(filters[i]);\n }\n }\n\n if (this._enabledFilters.length)\n {\n renderer.filter.push(this, this._enabledFilters);\n }\n }\n\n if (mask)\n {\n renderer.mask.push(this, this._mask);\n }\n\n // add this object to the batch, only rendered if it has a texture.\n this._render(renderer);\n\n let child;\n let next;\n\n // now loop through the children and make sure they get rendered\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n child.render(renderer);\n }\n\n renderer.batch.flush();\n\n if (mask)\n {\n renderer.mask.pop(this);\n }\n\n if (filters && this._enabledFilters && this._enabledFilters.length)\n {\n renderer.filter.pop();\n }\n }\n\n /**\n * Renders the object using the Canvas renderer. Copied from and overrides PixiJS Canvas mixin in V5 and V6.\n */\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n renderCanvas(renderer: any): void\n {\n // if not visible or the alpha is 0 then no need to render this\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n if (this._mask)\n {\n renderer.maskManager.pushMask(this._mask);\n }\n\n (this as any)._renderCanvas(renderer);\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n (child as any).renderCanvas(renderer);\n }\n\n if (this._mask)\n {\n renderer.maskManager.popMask(renderer);\n }\n }\n}\n","import { Emitter } from './Emitter';\nimport * as behaviors from './behaviors';\n\nEmitter.registerBehavior(behaviors.AccelerationBehavior);\nEmitter.registerBehavior(behaviors.AlphaBehavior);\nEmitter.registerBehavior(behaviors.StaticAlphaBehavior);\nEmitter.registerBehavior(behaviors.RandomAnimatedTextureBehavior);\nEmitter.registerBehavior(behaviors.SingleAnimatedTextureBehavior);\nEmitter.registerBehavior(behaviors.BlendModeBehavior);\nEmitter.registerBehavior(behaviors.BurstSpawnBehavior);\nEmitter.registerBehavior(behaviors.ColorBehavior);\nEmitter.registerBehavior(behaviors.StaticColorBehavior);\nEmitter.registerBehavior(behaviors.OrderedTextureBehavior);\nEmitter.registerBehavior(behaviors.PathBehavior);\nEmitter.registerBehavior(behaviors.PointSpawnBehavior);\nEmitter.registerBehavior(behaviors.RandomTextureBehavior);\nEmitter.registerBehavior(behaviors.RotationBehavior);\nEmitter.registerBehavior(behaviors.StaticRotationBehavior);\nEmitter.registerBehavior(behaviors.NoRotationBehavior);\nEmitter.registerBehavior(behaviors.ScaleBehavior);\nEmitter.registerBehavior(behaviors.StaticScaleBehavior);\nEmitter.registerBehavior(behaviors.ShapeSpawnBehavior);\nEmitter.registerBehavior(behaviors.SingleTextureBehavior);\nEmitter.registerBehavior(behaviors.SpeedBehavior);\nEmitter.registerBehavior(behaviors.StaticSpeedBehavior);\n\nexport * as behaviors from './behaviors';\nexport * as ParticleUtils from './ParticleUtils';\nexport * from './Particle';\nexport * from './Emitter';\nexport * from './EmitterConfig';\nexport * from './PropertyList';\nexport * from './PropertyNode';\nexport * from './LinkedListContainer';\n","/* eslint-disable no-lonely-if */\nimport { EaseSegment, SimpleEase } from './ParticleUtils';\nimport { ValueList } from './PropertyNode';\nimport { IPointData } from '@pixi/math';\n\n/**\n * Full Emitter configuration for initializing an Emitter instance.\n */\nexport interface EmitterConfigV3\n{\n /**\n * Random number configuration for picking the lifetime for each particle..\n */\n lifetime: RandNumber;\n /**\n * Easing to be applied to all interpolated or stepped values across the particle lifetime.\n */\n ease?: SimpleEase | EaseSegment[];\n /**\n * How many particles to spawn at once, each time that it is determined that particles should be spawned.\n * If omitted, only one particle will spawn at a time.\n */\n particlesPerWave?: number;\n /**\n * How often to spawn particles. This is a value in seconds, so a value of 0.5 would be twice a second.\n */\n frequency: number;\n /**\n * Defines a chance to not spawn particles. Values lower than 1 mean particles may not be spawned each time.\n * If omitted, particles will always spawn.\n */\n spawnChance?: number;\n /**\n * How long to run the Emitter before it stops spawning particles. If omitted, runs forever (or until told to stop\n * manually).\n */\n emitterLifetime?: number;\n /**\n * Maximum number of particles that can be alive at any given time for this emitter.\n */\n maxParticles?: number;\n /**\n * If newly spawned particles should be added to the back of the parent container (to make them less conspicuous\n * as they pop in). If omitted, particles will be added to the top of the container.\n */\n addAtBack?: boolean;\n /**\n * Default position to spawn particles from inside the parent container.\n */\n pos: { x: number; y: number };\n /**\n * If the emitter should start out emitting particles. If omitted, it will be treated as `true` and will emit particles\n * immediately.\n */\n emit?: boolean;\n /**\n * If the Emitter should hook into PixiJS's shared ticker. If this is false or emitted, you will be responsible for\n * connecting it to update ticks.\n */\n autoUpdate?: boolean;\n\n /**\n * The list of behaviors to apply to this emitter. See the behaviors namespace for\n * a list of built in behaviors. Custom behaviors may be registered with {@link Emitter.registerBehavior}.\n */\n behaviors: BehaviorEntry[];\n}\n\n/**\n * See {@link EmitterConfigV3.behaviors}\n */\nexport interface BehaviorEntry\n{\n /**\n * The behavior type, as defined as the static `type` property of a behavior class.\n */\n type: string;\n /**\n * Configuration data specific to that behavior.\n */\n config: any;\n}\n\n/**\n * Configuration for how to pick a random number (inclusive).\n */\nexport interface RandNumber\n{\n /**\n * Maximum pickable value.\n */\n max: number;\n /**\n * Minimum pickable value.\n */\n min: number;\n}\n\n/**\n * Converts emitter configuration from pre-5.0.0 library values into the current version.\n *\n * Example usage:\n * ```javascript\n * const emitter = new Emitter(myContainer, upgradeConfig(myOldConfig, [myTexture, myOtherTexture]));\n * ```\n * @param config The old emitter config to upgrade.\n * @param art The old art values as would have been passed into the Emitter constructor or `Emitter.init()`\n */\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function upgradeConfig(config: EmitterConfigV2|EmitterConfigV1, art: any): EmitterConfigV3\n{\n // just ensure we aren't given any V3 config data\n if ('behaviors' in config)\n {\n return config as EmitterConfigV3;\n }\n\n const out: EmitterConfigV3 = {\n lifetime: config.lifetime,\n ease: config.ease,\n particlesPerWave: config.particlesPerWave,\n frequency: config.frequency,\n spawnChance: config.spawnChance,\n emitterLifetime: config.emitterLifetime,\n maxParticles: config.maxParticles,\n addAtBack: config.addAtBack,\n pos: config.pos,\n emit: config.emit,\n autoUpdate: config.autoUpdate,\n behaviors: [],\n };\n\n // set up the alpha\n if (config.alpha)\n {\n if ('start' in config.alpha)\n {\n if (config.alpha.start === config.alpha.end)\n {\n if (config.alpha.start !== 1)\n {\n out.behaviors.push({\n type: 'alphaStatic',\n config: { alpha: config.alpha.start },\n });\n }\n }\n else\n {\n const list: ValueList = {\n list: [\n { time: 0, value: config.alpha.start },\n { time: 1, value: config.alpha.end },\n ],\n };\n\n out.behaviors.push({\n type: 'alpha',\n config: { alpha: list },\n });\n }\n }\n else if (config.alpha.list.length === 1)\n {\n if (config.alpha.list[0].value !== 1)\n {\n out.behaviors.push({\n type: 'alphaStatic',\n config: { alpha: config.alpha.list[0].value },\n });\n }\n }\n else\n {\n out.behaviors.push({\n type: 'alpha',\n config: { alpha: config.alpha },\n });\n }\n }\n\n // acceleration movement\n if (config.acceleration && (config.acceleration.x || config.acceleration.y))\n {\n let minStart: number;\n let maxStart: number;\n\n if ('start' in config.speed)\n {\n minStart = config.speed.start * (config.speed.minimumSpeedMultiplier ?? 1);\n maxStart = config.speed.start;\n }\n else\n {\n minStart = config.speed.list[0].value * ((config as EmitterConfigV2).minimumSpeedMultiplier ?? 1);\n maxStart = config.speed.list[0].value;\n }\n\n out.behaviors.push({\n type: 'moveAcceleration',\n config: {\n accel: config.acceleration,\n minStart,\n maxStart,\n rotate: !config.noRotation,\n maxSpeed: config.maxSpeed,\n },\n });\n }\n // path movement\n else if (config.extraData?.path)\n {\n let list: ValueList;\n let mult: number;\n\n if ('start' in config.speed)\n {\n mult = config.speed.minimumSpeedMultiplier ?? 1;\n if (config.speed.start === config.speed.end)\n {\n list = {\n list: [{ time: 0, value: config.speed.start }],\n };\n }\n else\n {\n list = {\n list: [\n { time: 0, value: config.speed.start },\n { time: 1, value: config.speed.end },\n ],\n };\n }\n }\n else\n {\n list = config.speed;\n mult = ((config as EmitterConfigV2).minimumSpeedMultiplier ?? 1);\n }\n\n out.behaviors.push({\n type: 'movePath',\n config: {\n path: config.extraData.path,\n speed: list,\n minMult: mult,\n },\n });\n }\n // normal speed movement\n else\n {\n if (config.speed)\n {\n if ('start' in config.speed)\n {\n if (config.speed.start === config.speed.end)\n {\n out.behaviors.push({\n type: 'moveSpeedStatic',\n config: {\n min: config.speed.start * (config.speed.minimumSpeedMultiplier ?? 1),\n max: config.speed.start,\n },\n });\n }\n else\n {\n const list: ValueList = {\n list: [\n { time: 0, value: config.speed.start },\n { time: 1, value: config.speed.end },\n ],\n };\n\n out.behaviors.push({\n type: 'moveSpeed',\n config: { speed: list, minMult: config.speed.minimumSpeedMultiplier },\n });\n }\n }\n else if (config.speed.list.length === 1)\n {\n out.behaviors.push({\n type: 'moveSpeedStatic',\n config: {\n min: config.speed.list[0].value * ((config as EmitterConfigV2).minimumSpeedMultiplier ?? 1),\n max: config.speed.list[0].value,\n },\n });\n }\n else\n {\n out.behaviors.push({\n type: 'moveSpeed',\n config: { speed: config.speed, minMult: ((config as EmitterConfigV2).minimumSpeedMultiplier ?? 1) },\n });\n }\n }\n }\n\n // scale\n if (config.scale)\n {\n if ('start' in config.scale)\n {\n const mult = config.scale.minimumScaleMultiplier ?? 1;\n\n if (config.scale.start === config.scale.end)\n {\n out.behaviors.push({\n type: 'scaleStatic',\n config: {\n min: config.scale.start * mult,\n max: config.scale.start,\n },\n });\n }\n else\n {\n const list: ValueList = {\n list: [\n { time: 0, value: config.scale.start },\n { time: 1, value: config.scale.end },\n ],\n };\n\n out.behaviors.push({\n type: 'scale',\n config: { scale: list, minMult: mult },\n });\n }\n }\n else if (config.scale.list.length === 1)\n {\n const mult = (config as EmitterConfigV2).minimumScaleMultiplier ?? 1;\n const scale = config.scale.list[0].value;\n\n out.behaviors.push({\n type: 'scaleStatic',\n config: { min: scale * mult, max: scale },\n });\n }\n else\n {\n out.behaviors.push({\n type: 'scale',\n config: { scale: config.scale, minMult: (config as EmitterConfigV2).minimumScaleMultiplier ?? 1 },\n });\n }\n }\n\n // color\n if (config.color)\n {\n if ('start' in config.color)\n {\n if (config.color.start === config.color.end)\n {\n if (config.color.start !== 'ffffff')\n {\n out.behaviors.push({\n type: 'colorStatic',\n config: { color: config.color.start },\n });\n }\n }\n else\n {\n const list: ValueList = {\n list: [\n { time: 0, value: config.color.start },\n { time: 1, value: config.color.end },\n ],\n };\n\n out.behaviors.push({\n type: 'color',\n config: { color: list },\n });\n }\n }\n else if (config.color.list.length === 1)\n {\n if (config.color.list[0].value !== 'ffffff')\n {\n out.behaviors.push({\n type: 'colorStatic',\n config: { color: config.color.list[0].value },\n });\n }\n }\n else\n {\n out.behaviors.push({\n type: 'color',\n config: { color: config.color },\n });\n }\n }\n\n // rotation\n if (config.rotationAcceleration || config.rotationSpeed?.min || config.rotationSpeed?.max)\n {\n out.behaviors.push({\n type: 'rotation',\n config: {\n accel: config.rotationAcceleration || 0,\n minSpeed: config.rotationSpeed?.min || 0,\n maxSpeed: config.rotationSpeed?.max || 0,\n minStart: config.startRotation?.min || 0,\n maxStart: config.startRotation?.max || 0,\n },\n });\n }\n else if (config.startRotation?.min || config.startRotation?.max)\n {\n out.behaviors.push({\n type: 'rotationStatic',\n config: {\n min: config.startRotation?.min || 0,\n max: config.startRotation?.max || 0,\n },\n });\n }\n if (config.noRotation)\n {\n out.behaviors.push({\n type: 'noRotation',\n config: {},\n });\n }\n\n // blend mode\n if (config.blendMode && config.blendMode !== 'normal')\n {\n out.behaviors.push({\n type: 'blendMode',\n config: {\n blendMode: config.blendMode,\n },\n });\n }\n\n // animated\n if (Array.isArray(art) && typeof art[0] !== 'string' && 'framerate' in art[0])\n {\n for (let i = 0; i < art.length; ++i)\n {\n if (art[i].framerate === 'matchLife')\n {\n art[i].framerate = -1;\n }\n }\n out.behaviors.push({\n type: 'animatedRandom',\n config: {\n anims: art,\n },\n });\n }\n else if (typeof art !== 'string' && 'framerate' in art)\n {\n if (art.framerate === 'matchLife')\n {\n art.framerate = -1;\n }\n out.behaviors.push({\n type: 'animatedSingle',\n config: {\n anim: art,\n },\n });\n }\n // ordered art\n else if (config.orderedArt && Array.isArray(art))\n {\n out.behaviors.push({\n type: 'textureOrdered',\n config: {\n textures: art,\n },\n });\n }\n // random texture\n else if (Array.isArray(art))\n {\n out.behaviors.push({\n type: 'textureRandom',\n config: {\n textures: art,\n },\n });\n }\n // single texture\n else\n {\n out.behaviors.push({\n type: 'textureSingle',\n config: {\n texture: art,\n },\n });\n }\n\n // spawn burst\n if (config.spawnType === 'burst')\n {\n out.behaviors.push({\n type: 'spawnBurst',\n config: {\n start: config.angleStart || 0,\n spacing: config.particleSpacing,\n // older formats bursted from a single point\n distance: 0,\n },\n });\n }\n // spawn point\n else if (config.spawnType === 'point')\n {\n out.behaviors.push({\n type: 'spawnPoint',\n config: {},\n });\n }\n // spawn shape\n else\n {\n let shape: any;\n\n if (config.spawnType === 'ring')\n {\n shape = {\n type: 'torus',\n data: {\n x: config.spawnCircle.x,\n y: config.spawnCircle.y,\n radius: config.spawnCircle.r,\n innerRadius: config.spawnCircle.minR,\n affectRotation: true,\n },\n };\n }\n else if (config.spawnType === 'circle')\n {\n shape = {\n type: 'torus',\n data: {\n x: config.spawnCircle.x,\n y: config.spawnCircle.y,\n radius: config.spawnCircle.r,\n innerRadius: 0,\n affectRotation: false,\n },\n };\n }\n else if (config.spawnType === 'rect')\n {\n shape = {\n type: 'rect',\n data: config.spawnRect,\n };\n }\n else if (config.spawnType === 'polygonalChain')\n {\n shape = {\n type: 'polygonalChain',\n data: config.spawnPolygon,\n };\n }\n\n if (shape)\n {\n out.behaviors.push({\n type: 'spawnShape',\n config: shape,\n });\n }\n }\n\n return out;\n}\n\n/**\n * The obsolete emitter configuration format from version 3.0.0 of the library.\n * This type information is kept to make it easy to upgrade, but otherwise\n * configuration should be made as {@link EmitterConfigV3}.\n */\nexport interface EmitterConfigV2 {\n alpha?: ValueList;\n speed?: ValueList;\n minimumSpeedMultiplier?: number;\n maxSpeed?: number;\n acceleration?: {x: number; y: number};\n scale?: ValueList;\n minimumScaleMultiplier?: number;\n color?: ValueList;\n startRotation?: RandNumber;\n noRotation?: boolean;\n rotationSpeed?: RandNumber;\n rotationAcceleration?: number;\n lifetime: RandNumber;\n blendMode?: string;\n ease?: SimpleEase | EaseSegment[];\n extraData?: any;\n particlesPerWave?: number;\n /**\n * Really \"rect\"|\"circle\"|\"ring\"|\"burst\"|\"point\"|\"polygonalChain\", but that\n * tends to be too strict for random object creation.\n */\n spawnType?: string;\n spawnRect?: {x: number; y: number; w: number; h: number};\n spawnCircle?: {x: number; y: number; r: number; minR?: number};\n particleSpacing?: number;\n angleStart?: number;\n spawnPolygon?: IPointData[] | IPointData[][];\n frequency: number;\n spawnChance?: number;\n emitterLifetime?: number;\n maxParticles?: number;\n addAtBack?: boolean;\n pos: {x: number; y: number};\n emit?: boolean;\n autoUpdate?: boolean;\n orderedArt?: boolean;\n}\n\nexport interface BasicTweenable {\n start: T;\n end: T;\n}\n\n/**\n * The obsolete emitter configuration format of the initial library release.\n * This type information is kept to maintain compatibility with the older particle tool, but otherwise\n * configuration should be made as {@link EmitterConfigV3}.\n */\nexport interface EmitterConfigV1 {\n alpha?: BasicTweenable;\n speed?: BasicTweenable & {minimumSpeedMultiplier?: number};\n maxSpeed?: number;\n acceleration?: {x: number; y: number};\n scale?: BasicTweenable & {minimumScaleMultiplier?: number};\n color?: BasicTweenable;\n startRotation?: RandNumber;\n noRotation?: boolean;\n rotationSpeed?: RandNumber;\n rotationAcceleration?: number;\n lifetime: RandNumber;\n blendMode?: string;\n ease?: SimpleEase | EaseSegment[];\n extraData?: any;\n particlesPerWave?: number;\n /**\n * Really \"rect\"|\"circle\"|\"ring\"|\"burst\"|\"point\"|\"polygonalChain\", but that\n * tends to be too strict for random object creation.\n */\n spawnType?: string;\n spawnRect?: {x: number; y: number; w: number; h: number};\n spawnCircle?: {x: number; y: number; r: number; minR?: number};\n particleSpacing?: number;\n angleStart?: number;\n spawnPolygon?: IPointData[] | IPointData[][];\n frequency: number;\n spawnChance?: number;\n emitterLifetime?: number;\n maxParticles?: number;\n addAtBack?: boolean;\n pos: {x: number; y: number};\n emit?: boolean;\n autoUpdate?: boolean;\n orderedArt?: boolean;\n}\n"],"mappings":"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","ignoreList":[]}