pixi-particle-system 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Emitter.d.ts +285 -0
- package/dist/Emitter.d.ts.map +1 -0
- package/dist/EmitterConfig.d.ts +79 -0
- package/dist/EmitterConfig.d.ts.map +1 -0
- package/dist/behavior/EmitterBehavior.d.ts +79 -0
- package/dist/behavior/EmitterBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/AlphaBehavior.d.ts +98 -0
- package/dist/behavior/built-in/AlphaBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/ColorBehavior.d.ts +98 -0
- package/dist/behavior/built-in/ColorBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/MovementBehavior.d.ts +184 -0
- package/dist/behavior/built-in/MovementBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/RotationBehavior.d.ts +132 -0
- package/dist/behavior/built-in/RotationBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/ScaleBehavior.d.ts +114 -0
- package/dist/behavior/built-in/ScaleBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/SpawnBehavior.d.ts +191 -0
- package/dist/behavior/built-in/SpawnBehavior.d.ts.map +1 -0
- package/dist/behavior/built-in/TextureBehavior.d.ts +77 -0
- package/dist/behavior/built-in/TextureBehavior.d.ts.map +1 -0
- package/dist/behavior/index.d.ts +9 -0
- package/dist/behavior/index.d.ts.map +1 -0
- package/dist/data/easing/Ease.d.ts +57 -0
- package/dist/data/easing/Ease.d.ts.map +1 -0
- package/dist/data/easing/eases/BackEase.d.ts +49 -0
- package/dist/data/easing/eases/BackEase.d.ts.map +1 -0
- package/dist/data/easing/eases/BounceEase.d.ts +47 -0
- package/dist/data/easing/eases/BounceEase.d.ts.map +1 -0
- package/dist/data/easing/eases/CircleEase.d.ts +50 -0
- package/dist/data/easing/eases/CircleEase.d.ts.map +1 -0
- package/dist/data/easing/eases/ElasticEase.d.ts +47 -0
- package/dist/data/easing/eases/ElasticEase.d.ts.map +1 -0
- package/dist/data/easing/eases/PowerEase.d.ts +192 -0
- package/dist/data/easing/eases/PowerEase.d.ts.map +1 -0
- package/dist/data/easing/eases/SineEase.d.ts +48 -0
- package/dist/data/easing/eases/SineEase.d.ts.map +1 -0
- package/dist/data/index.d.ts +5 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/list/ColorList.d.ts +18 -0
- package/dist/data/list/ColorList.d.ts.map +1 -0
- package/dist/data/list/List.d.ts +81 -0
- package/dist/data/list/List.d.ts.map +1 -0
- package/dist/data/list/NumberList.d.ts +17 -0
- package/dist/data/list/NumberList.d.ts.map +1 -0
- package/dist/error/EmitterError.d.ts +12 -0
- package/dist/error/EmitterError.d.ts.map +1 -0
- package/dist/error/index.d.ts +2 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1657 -0
- package/dist/index.js.map +1 -0
- package/dist/particle/EmitterParticle.d.ts +127 -0
- package/dist/particle/EmitterParticle.d.ts.map +1 -0
- package/dist/particle/index.d.ts +2 -0
- package/dist/particle/index.d.ts.map +1 -0
- package/dist/util/ColorUtil.d.ts +31 -0
- package/dist/util/ColorUtil.d.ts.map +1 -0
- package/dist/util/Types.d.ts +91 -0
- package/dist/util/Types.d.ts.map +1 -0
- package/dist/util/index.d.ts +3 -0
- package/dist/util/index.d.ts.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/error/EmitterError.ts","../src/data/easing/eases/BackEase.ts","../src/data/easing/eases/BounceEase.ts","../src/data/easing/eases/CircleEase.ts","../src/data/easing/eases/ElasticEase.ts","../src/data/easing/eases/PowerEase.ts","../src/data/easing/eases/SineEase.ts","../src/data/easing/Ease.ts","../src/data/list/List.ts","../src/data/list/NumberList.ts","../src/behavior/EmitterBehavior.ts","../src/behavior/built-in/AlphaBehavior.ts","../src/util/ColorUtil.ts","../src/data/list/ColorList.ts","../src/behavior/built-in/ColorBehavior.ts","../src/behavior/built-in/MovementBehavior.ts","../src/behavior/built-in/RotationBehavior.ts","../src/behavior/built-in/ScaleBehavior.ts","../src/behavior/built-in/SpawnBehavior.ts","../src/behavior/built-in/TextureBehavior.ts","../src/particle/EmitterParticle.ts","../src/Emitter.ts"],"sourcesContent":["/**\n * Error class representing emitter-related errors.\n * @group Error\n */\nexport class EmitterError extends Error {\n /**\n * Creates a new EmitterError instance.\n * @param message Error message.\n */\n constructor(message: string) {\n super(`EmitterError: ${message}`);\n this.name = \"EmitterError\";\n }\n}\n","const k = 1.70158;\nconst k2 = k * 1.525;\n\n/**\n * Back ease-in function.\n *\n * Starts by moving slightly backward, then accelerates forward.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * backIn(0); // 0\n * backIn(0.5); // ~-0.0877\n * backIn(1); // 1\n * ```\n * @group Easing/Back/\n */\nexport function backIn(v: number): number {\n return v * v * (v * (k + 1) - k);\n}\n\n/**\n * Back ease-out function.\n *\n * Starts quickly and overshoots slightly past the end before settling.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * backOut(0); // 0\n * backOut(0.5); // ~1.0877\n * backOut(1); // 1\n * ```\n * @group Easing/Back/\n */\nexport function backOut(v: number): number {\n const m = v - 1;\n\n return 1 + m * m * (m * (k + 1) + k);\n}\n\n/**\n * Back ease-in-out function.\n *\n * Combines ease-in and ease-out with a slight overshoot at both ends.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * backInOut(0); // 0\n * backInOut(0.5); // 0.5\n * backInOut(1); // 1\n * ```\n * @group Easing/Back/\n */\nexport function backInOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) return v * t * (t * (k2 + 1) - k2);\n\n return 1 + 2 * m * m * (2 * m * (k2 + 1) + k2);\n}\n","const bounceCoefficient = 7.5625;\nconst bounceDivisor = 2.75;\n\nconst threshold1 = 1 / bounceDivisor;\nconst threshold2 = 2 / bounceDivisor;\nconst threshold3 = 2.5 / bounceDivisor;\n\nconst offset1 = 1.5 / bounceDivisor;\nconst offset2 = 2.25 / bounceDivisor;\nconst offset3 = 2.625 / bounceDivisor;\n\n/**\n * Bounce ease-in function.\n *\n * Starts with small bounces and builds to larger bounces toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * bounceIn(0); // 0\n * bounceIn(1); // 1\n * ```\n * @group Easing/Bounce/\n */\nexport function bounceIn(v: number): number {\n return 1 - bounceOut(1 - v);\n}\n\n/**\n * Bounce ease-out function.\n *\n * Starts quickly, then bounces (overshooting and settling) toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * bounceOut(0); // 0\n * bounceOut(1); // 1\n * ```\n * @group Easing/Bounce/\n */\nexport function bounceOut(v: number): number {\n let t = 0;\n\n if (v < threshold1) {\n return bounceCoefficient * v * v;\n } else if (v < threshold2) {\n t = v - offset1;\n return bounceCoefficient * t * t + 0.75;\n } else if (v < threshold3) {\n t = v - offset2;\n return bounceCoefficient * t * t + 0.9375;\n } else {\n t = v - offset3;\n return bounceCoefficient * t * t + 0.984375;\n }\n}\n\n/**\n * Bounce ease-in-out function.\n *\n * Combines bounce ease-in and ease-out: bounces at the start and at the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * bounceInOut(0); // 0\n * bounceInOut(0.5); // 0.5\n * bounceInOut(1); // 1\n * ```\n * @group Easing/Bounce/\n */\nexport function bounceInOut(v: number): number {\n const t = v * 2;\n\n if (t < 1) return 0.5 - 0.5 * bounceOut(1 - t);\n else return 0.5 + 0.5 * bounceOut(t - 1);\n}\n","/**\n * Circular ease-in function.\n *\n * Starts slowly and accelerates toward the end following a circular curve.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * circleIn(0); // 0\n * circleIn(0.5); // ~0.134\n * circleIn(1); // 1\n * ```\n * @group Easing/Circle/\n */\nexport function circleIn(v: number): number {\n return 1 - Math.sqrt(1 - v * v);\n}\n\n/**\n * Circular ease-out function.\n *\n * Starts quickly and decelerates toward the end following a circular curve.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * circleOut(0); // 0\n * circleOut(0.5); // ~0.866\n * circleOut(1); // 1\n * ```\n * @group Easing/Circle/\n */\nexport function circleOut(v: number): number {\n const m = v - 1;\n\n return Math.sqrt(1 - m * m);\n}\n\n/**\n * Circular ease-in-out function.\n *\n * Accelerates during the first half, then decelerates during the second half,\n * following a circular curve.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * circleInOut(0); // 0\n * circleInOut(0.5); // 0.5\n * circleInOut(1); // 1\n * ```\n * @group Easing/Circle/\n */\nexport function circleInOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) return (1 - Math.sqrt(1 - t * t)) * 0.5;\n\n return (Math.sqrt(1 - 4 * m * m) + 1) * 0.5;\n}\n","const elasticC = Math.PI / 6;\n\n/**\n * Elastic ease-in function.\n *\n * Starts slowly, then accelerates with an elastic (oscillating) motion.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * elasticIn(0); // 0\n * elasticIn(1); // 1\n * ```\n * @group Easing/Elastic/\n */\nexport function elasticIn(v: number): number {\n const m = v - 1;\n\n return -Math.pow(2, 10 * m) * Math.sin((m * 40 - 3) * elasticC);\n}\n\n/**\n * Elastic ease-out function.\n *\n * Starts quickly, then decelerates with an elastic (oscillating) overshoot.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * elasticOut(0); // 0\n * elasticOut(1); // 1\n * ```\n * @group Easing/Elastic/\n */\nexport function elasticOut(v: number): number {\n return 1 + Math.pow(2, 10 * -v) * Math.sin((-v * 40 - 3) * elasticC);\n}\n\n/**\n * Elastic ease-in-out function.\n *\n * Combines elastic ease-in and ease-out: oscillates at the start and at the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * elasticInOut(0); // 0\n * elasticInOut(0.5); // 0.5\n * elasticInOut(1); // 1\n * ```\n * @group Easing/Elastic/\n */\nexport function elasticInOut(v: number): number {\n const s = 2 * v - 1;\n const k = ((80 * s - 9) * Math.PI) / 18;\n\n if (s < 0) return -0.5 * Math.pow(2, 10 * s) * Math.sin(k);\n else return 1 + -0.5 * Math.pow(2, -10 * s) * Math.sin(k);\n}\n","/**\n * Quadratic ease-in function (power of 2).\n *\n * Starts slowly and accelerates toward the end by squaring the input value.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value `v²`.\n * @example\n * ```ts\n * power2In(0); // 0\n * power2In(0.5); // 0.25\n * power2In(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power2In(v: number): number {\n return v * v;\n}\n\n/**\n * Quadratic ease-out function (power of 2).\n *\n * Starts quickly and decelerates toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power2Out(0); // 0\n * power2Out(0.5); // 0.75\n * power2Out(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power2Out(v: number): number {\n const m = v - 1;\n\n return 1 - m * m;\n}\n\n/**\n * Quadratic ease-in-out function (power of 2).\n *\n * Accelerates during the first half, then decelerates during the second half.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power2InOut(0); // 0\n * power2InOut(0.5); // 0.5\n * power2InOut(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power2InOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) {\n return v * t;\n }\n\n return 1 - m * m * 2;\n}\n\n/**\n * Cubic ease-in function (power of 3).\n *\n * Starts slowly and accelerates toward the end by cubing the input value.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value `v³`.\n * @example\n * ```ts\n * power3In(0); // 0\n * power3In(0.5); // 0.125\n * power3In(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power3In(v: number): number {\n return v * v * v;\n}\n\n/**\n * Cubic ease-out function (power of 3).\n *\n * Starts quickly and decelerates toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power3Out(0); // 0\n * power3Out(0.5); // 0.875\n * power3Out(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power3Out(v: number): number {\n const m = v - 1;\n return 1 + m * m * m;\n}\n\n/**\n * Cubic ease-in-out function (power of 3).\n *\n * Accelerates during the first half, then decelerates during the second half.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power3InOut(0); // 0\n * power3InOut(0.5); // 0.5\n * power3InOut(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power3InOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) {\n return v * t * t;\n }\n\n return 1 - m * m * m * 4;\n}\n\n/**\n * Quartic ease-in function (power of 4).\n *\n * Starts slowly and accelerates toward the end by raising the input value to the 4th power.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value `v⁴`.\n * @example\n * ```ts\n * power4In(0); // 0\n * power4In(0.5); // 0.0625\n * power4In(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power4In(v: number): number {\n return v * v * v * v;\n}\n\n/**\n * Quartic ease-out function (power of 4).\n *\n * Starts quickly and decelerates toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power4Out(0); // 0\n * power4Out(0.5); // 0.9375\n * power4Out(1); // 1\n * ```\n */\nexport function power4Out(v: number): number {\n const m = v - 1;\n return 1 - m * m * m * m;\n}\n\n/**\n * Quartic ease-in-out function (power of 4).\n *\n * Accelerates during the first half, then decelerates during the second half.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power4InOut(0); // 0\n * power4InOut(0.5); // 0.5\n * power4InOut(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power4InOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) {\n return v * t * t * t;\n }\n\n return 1 - m * m * m * 8;\n}\n\n/**\n * Quintic ease-in function (power of 5).\n *\n * Starts slowly and accelerates toward the end by raising the input value to the 5th power.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value `v⁵`.\n * @example\n * ```ts\n * power5In(0); // 0\n * power5In(0.5); // 0.03125\n * power5In(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power5In(v: number): number {\n return v * v * v * v * v;\n}\n\n/**\n * Quintic ease-out function (power of 5).\n *\n * Starts quickly and decelerates toward the end.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power5Out(0); // 0\n * power5Out(0.5); // 0.96875\n * power5Out(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power5Out(v: number): number {\n const m = v - 1;\n\n return 1 + m * m * m * m * m;\n}\n\n/**\n * Quintic ease-in-out function (power of 5).\n *\n * Accelerates during the first half, then decelerates during the second half.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * power5InOut(0); // 0\n * power5InOut(0.5); // 0.5\n * power5InOut(1); // 1\n * ```\n * @group Easing/Power/\n */\nexport function power5InOut(v: number): number {\n const m = v - 1;\n const t = v * 2;\n\n if (t < 1) {\n return v * t * t * t * t;\n }\n\n return 1 - m * m * m * 16;\n}\n","/**\n * Sine ease-in function.\n *\n * Starts slowly and accelerates toward the end following a sine curve.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * sineIn(0); // 0\n * sineIn(0.5); // ~0.2929\n * sineIn(1); // 1\n * ```\n * @group Easing/Sine/\n */\nexport function sineIn(v: number): number {\n return 1 - Math.cos(v * Math.PI * 0.5);\n}\n\n/**\n * Sine ease-out function.\n *\n * Starts quickly and decelerates toward the end following a sine curve.\n * Typically used to ease normalized progress values in the range `[0, 1]`.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The eased value.\n * @example\n * ```ts\n * sineOut(0); // 0\n * sineOut(0.5); // ~0.7071\n * sineOut(1); // 1\n * ```\n * @group Easing/Sine/\n */\nexport function sineOut(v: number): number {\n return Math.sin(v * Math.PI * 0.5);\n}\n\n/**\n * Sine ease-in-out function.\n *\n * Computes a cosine curve over the input.\n * @param v - Normalized progress value (commonly `0` to `1`).\n * @returns The value `cos(v·π)`.\n * @example\n * ```ts\n * sineInOut(0); // 1\n * sineInOut(0.5); // 0\n * sineInOut(1); // -1\n * ```\n * @group Easing/Sine/\n */\nexport function sineInOut(v: number): number {\n return Math.cos(v * Math.PI);\n}\n","// ---\n// Easing functions are based on the amazing easing guide by Michael \"Code Poet\" Pohoreski (Michaelangel007).\n// Source: https://github.com/Michaelangel007/easing\n// ---\n\nimport { backIn, backInOut, backOut } from \"./eases/BackEase\";\nimport { bounceIn, bounceInOut, bounceOut } from \"./eases/BounceEase\";\nimport { circleIn, circleInOut, circleOut } from \"./eases/CircleEase\";\nimport { elasticIn, elasticInOut, elasticOut } from \"./eases/ElasticEase\";\nimport {\n power2In,\n power2InOut,\n power2Out,\n power3In,\n power3InOut,\n power3Out,\n power4In,\n power4InOut,\n power4Out,\n power5In,\n power5InOut,\n power5Out,\n} from \"./eases/PowerEase\";\nimport { sineIn, sineInOut, sineOut } from \"./eases/SineEase\";\n\n/**\n * Type describing an easing function.\n */\nexport type EaseFunction = (v: number) => number;\n\n// prettier-ignore\nconst easeToFunctionMap = {\n \"linear\": (v): number => v,\n\n // Power Easing\n \"power2.in\": power2In,\n \"power3.in\": power3In,\n \"power4.in\": power4In,\n \"power5.in\": power5In,\n\n \"power2.out\": power2Out,\n \"power3.out\": power3Out,\n \"power4.out\": power4Out,\n \"power5.out\": power5Out,\n\n \"power2.inout\": power2InOut,\n \"power3.inout\": power3InOut,\n \"power4.inout\": power4InOut,\n \"power5.inout\": power5InOut,\n\n // Back Easing\n \"back.in\" : backIn,\n \"back.out\" : backOut,\n \"back.inout\": backInOut,\n\n // Bounce Easing\n \"bounce.in\" : bounceIn,\n \"bounce.out\" : bounceOut,\n \"bounce.inout\": bounceInOut,\n\n // Circle Easing\n \"circle.in\" : circleIn,\n \"circle.out\" : circleOut,\n \"circle.inout\": circleInOut,\n\n // Elastic Easing\n \"elastic.in\" : elasticIn,\n \"elastic.out\" : elasticOut,\n \"elastic.inout\": elasticInOut,\n\n // Sine Eases\n \"sine.in\" : sineIn,\n \"sine.out\" : sineOut,\n \"sine.inout\": sineInOut\n} satisfies Record<string, EaseFunction>;\n\nObject.freeze(easeToFunctionMap);\n\n/**\n * Type describing all possible easing functions.\n *\n * To see the logic these eases have been based on, and learn more about\n * how each of the eases work, visit Micheal Pohoreski's guide over at\n * their Github: https://github.com/Michaelangel007/easing.\n * @group Easing/\n */\nexport type Ease = keyof typeof easeToFunctionMap;\n\n/**\n * Get an easing function from all available eases.\n * @param ease Ease to get.\n * @returns Easing function.\n */\nexport function getEaseFunction(ease: Ease): EaseFunction {\n return easeToFunctionMap[ease];\n}\n","import { EmitterError } from \"../../error\";\nimport { Ease, EaseFunction, getEaseFunction } from \"../easing/Ease\";\n\n/**\n * Default interpolate function that throws an error indicating it has not been set.\n * @throws {EmitterError} Indicates that the interpolate method has not been set.\n */\nexport function defaultInterpolateFunction<ValueType>(): ValueType {\n throw new EmitterError(\n \"Interpolate method not set! Did you forget to initialize the List?\",\n );\n}\n\n/**\n * Type defining a step in a list.\n */\nexport type ListStep<ValueType> = {\n value: ValueType;\n time: number;\n};\n\n/**\n * Type defining the data used to initialize a list.\n */\nexport type ListData<ValueType> = {\n list: ListStep<ValueType>[];\n ease?: Ease;\n isStepped?: boolean;\n};\n\n/**\n * Type defining a node in a linked list.\n */\nexport type ListNode<ValueType> = {\n value: ValueType;\n time: number;\n next: ListNode<ValueType> | null;\n};\n\n/**\n * Abstract base class for lists used in particle behaviors.\n * @template OutputValue Type of value produced by the list.\n * @template InputValue Type of value used to initialize the list.\n * @template ListDataType Type of data contained within the list nodes.\n * @group Data/List\n */\nexport abstract class List<\n OutputValue,\n InputValue = OutputValue,\n ListDataType = OutputValue,\n> {\n protected _first: ListNode<ListDataType> | null = null;\n\n protected _list: ListStep<InputValue>[] = [];\n protected _easeFunction: EaseFunction | null = null;\n protected _isStepped = false;\n\n /**\n * First node in the list.\n * @throws {EmitterError} If the list has not been initialized.\n */\n public get first(): ListNode<ListDataType> {\n if (this._first === null) {\n throw new EmitterError(\n \"List not initialized properly! First is null.\",\n );\n }\n\n return this._first;\n }\n\n /**\n * Gets the list steps.\n */\n public get list(): ListStep<InputValue>[] {\n return this._list;\n }\n\n /**\n * Indicates whether the list has been initialized.\n */\n public get isInitialized(): boolean {\n return this._first !== null;\n }\n\n /**\n * Indicates whether the list uses stepped interpolation.\n */\n public get isStepped(): boolean {\n return this._isStepped;\n }\n public set isStepped(value: boolean) {\n this._isStepped = value;\n }\n\n /**\n * Function to interpolate values from the list.\n * @throws {EmitterError} If the interpolate method has not been set.\n * @returns Interpolated value.\n */\n public interpolate: (time: number) => OutputValue = () =>\n defaultInterpolateFunction<OutputValue>();\n\n /**\n * Initializes the list from data.\n * @param data Data to initialize the list with.\n */\n public initialize(data: ListData<InputValue>): void {\n this.initializeList(data);\n\n this._list = data.list;\n this._isStepped = !!data.isStepped;\n\n if (data.ease) {\n this._easeFunction = getEaseFunction(data.ease);\n } else {\n this._easeFunction = null;\n }\n }\n\n /**\n * Resets the list to an uninitialized state.\n */\n public reset(): void {\n this._first = null;\n this._isStepped = false;\n this._easeFunction = null;\n\n this.interpolate = (): OutputValue =>\n defaultInterpolateFunction<OutputValue>();\n }\n\n /**\n * Initializes the list from data.\n * @param data Data to initialize the list with.\n */\n protected abstract initializeList(data: ListData<InputValue>): void;\n}\n","import { EmitterError } from \"../../error\";\nimport { List, ListData, ListNode } from \"./List\";\n\n/**\n * Calculates the simple interpolated value for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated value.\n */\nfunction simpleValue(this: List<number>, lerp: number): number {\n if (this.first === null || this.first.next === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First or first.next is null.\",\n );\n }\n\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n if (lerp <= 0) return this.first.value;\n if (lerp >= 1) return this.first.next.value;\n\n return (this.first.next.value - this.first.value) * lerp + this.first.value;\n}\n\n/**\n * Calculates the complex interpolated value for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated value.\n */\nfunction complexValue(this: List<number>, lerp: number): number {\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n\n if (current === null || current.next === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First or first.next is null.\",\n );\n }\n\n if (lerp <= current.time) return current.value;\n\n while (current.next && lerp > current.next.time) {\n current = current.next;\n }\n\n if (!current.next) return current.value;\n\n const next = current.next;\n const denom = next.time - current.time;\n\n if (denom === 0) return current.value;\n\n // Convert the lerp value to the segment range.\n const t = (lerp - current.time) / denom;\n return (next.value - current.value) * t + current.value;\n}\n\n/**\n * Calculates the stepped interpolated value for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated value.\n */\nfunction steppedValue(this: List<number>, lerp: number): number {\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n let current = this.first;\n\n if (current === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First is null.\",\n );\n }\n\n while (current.next && lerp >= current.next.time) {\n current = current.next;\n }\n\n return current.value;\n}\n\n/**\n * Implementation of a `List` specifically for managing number values.\n * @see {@link List} for the base `List` implementation.\n * @group Data/List/\n */\nexport class NumberList extends List<number> {\n /**\n * @inheritdoc\n */\n public initialize(data: ListData<number>): void {\n super.initialize(data);\n\n const isSimple = this.first.next && this.first.next.time >= 1;\n\n if (isSimple) {\n this.interpolate = simpleValue;\n return;\n }\n\n if (this._isStepped) {\n this.interpolate = steppedValue;\n return;\n }\n\n this.interpolate = complexValue;\n }\n\n /**\n * @inheritdoc\n */\n protected initializeList(data: ListData<number>): void {\n let node: ListNode<number> | null = null;\n let first: ListNode<number> | null = null;\n\n for (const datum of data.list) {\n const newNode: ListNode<number> = {\n value: datum.value,\n time: datum.time,\n next: null,\n };\n\n if (node) {\n node.next = newNode;\n node = newNode;\n }\n\n if (!first) {\n first = newNode;\n node = newNode;\n }\n }\n\n this._first = first;\n }\n}\n","import { Emitter } from \"../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../particle/EmitterParticle\";\nimport { BehaviorOrder } from \"../util/Types\";\n\n/**\n * Abstract base for all behavior to build upon.\n *\n * This class provides the foundational structure and methods that all\n * emitter behaviors must implement, ensuring consistency and interoperability.\n *\n * In addition to the core functionality, this class also defines interfaces\n * for behaviors that initialize particles ({@link InitBehavior}) and\n * those that update particles ({@link UpdateBehavior}) during the emitter's update cycle.\n * @template ConfigType Type describing the configuration object for this behavior.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/EmitterBehavior\n */\nexport abstract class EmitterBehavior<\n ConfigType,\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n> {\n /**\n * @hidden\n */\n protected readonly _emitter: Emitter<DataType, ParticleType>;\n\n /**\n * Creates a new instance of the behavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n this._emitter = emitter;\n }\n\n /**\n * Defines at which step of the update cycle the behavior is applied.\n *\n * - `initial`: Earliest step, useful when other behaviors depend on this behavior.\n * - `normal`: Default step for most behaviors.\n * - `late`: Latest step, useful for behaviors that should override others or depend on their properties.\n */\n public abstract get updateOrder(): BehaviorOrder;\n\n /**\n * Reset the behavior and apply the provided configuration.\n * @param config Behavior configuration.\n */\n public applyConfig(config: ConfigType): void {\n if (!config) return;\n\n this.reset();\n }\n\n /**\n * Retrieve the current behavior properties as a configuration object.\n * If the behavior is inactive, `undefined` is returned.\n * @returns Behavior configuration object or `undefined` if inactive.\n */\n public abstract getConfig(): ConfigType | undefined;\n\n /**\n * Reset the behavior to its default state.\n */\n protected abstract reset(): void;\n}\n\n/**\n * Interface defining behaviors which update particles when they are first created.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/EmitterBehavior/\n */\nexport interface InitBehavior<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n> extends EmitterBehavior<unknown, DataType, ParticleType> {\n /**\n * Initialize the particle.\n * @param particle Particle to initialize.\n */\n init(particle: ParticleType): void;\n}\n\n/**\n * Interface defining behaviors which update particles on each update cycle.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/EmitterBehavior/\n */\nexport interface UpdateBehavior<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n> extends EmitterBehavior<unknown, DataType, ParticleType> {\n /**\n * Updates the particle.\n * @param particle Particle to update.\n * @param deltaTime Time elapsed since the last update, in seconds.\n */\n update(particle: ParticleType, deltaTime: number): void;\n}\n","import { NumberList } from \"../../data/list/NumberList\";\nimport { Emitter } from \"../../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport {\n BehaviorOrder,\n BehaviorSingleListConfig,\n BehaviorStaticConfig,\n} from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the configuration for AlphaBehavior.\n */\nexport type AlphaBehaviorConfig =\n | BehaviorStaticConfig<number>\n | BehaviorSingleListConfig<number>;\n\n/**\n * Behavior used to control the transparency of particles over their lifetime.\n *\n * Behavior supports three modes, a `static` mode where a single value is applied to all particles,\n * a `list` mode where values are interpolated over the particle's lifetime based on a provided list,\n * and a `random` mode where a random value from the list is applied to the particle upon initialization.\n * @see {@link BehaviorStaticConfig} for static configuration options.\n * @see {@link BehaviorSingleListConfig} for list configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/AlphaBehavior\n * @example\n * ```ts\n * // Apply a static alpha value of 0.5 to all particles.\n * alphaBehavior.applyConfig({\n * value: 0.5\n * });\n *\n * // Interpolate particle alpha from 0.0 to 1.0 over lifetime.\n * alphaBehavior.applyConfig({\n * listData: [\n * { time: 0.0, value: 0.0 },\n * { time: 1.0, value: 1.0 }\n * ],\n * mode: \"list\"\n * });\n *\n * // Assign a random alpha value between 0.2 and 0.8.\n * alphaBehavior.applyConfig({\n * listData: [\n * { time: 0.0, value: 0.2 },\n * { time: 1.0, value: 0.8 }\n * ],\n * mode: \"random\"\n * });\n * ```\n */\nexport class AlphaBehavior<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<AlphaBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private readonly _list: NumberList;\n\n private _staticValue: number = 1.0;\n private _mode: \"static\" | \"list\" | \"random\" = \"static\";\n\n /**\n * Creates new instance of AlphaBehavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n super(emitter);\n\n this._list = new NumberList();\n }\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"normal\";\n }\n\n /**\n * Number list used to interpolate alpha values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get list(): NumberList {\n return this._list;\n }\n\n /**\n * Mode currently used by the behavior.\n */\n public get mode(): \"static\" | \"list\" | \"random\" {\n return this._mode;\n }\n public set mode(value: \"static\" | \"list\" | \"random\") {\n this._mode = value;\n\n if (value === \"random\" || value === \"static\") {\n this._emitter.removeFromActiveUpdateBehaviors(this);\n } else {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * Alpha value applied to all particles in `static` mode.\n */\n public get staticValue(): number {\n return this._staticValue;\n }\n public set staticValue(value: number) {\n this._staticValue = value;\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: AlphaBehaviorConfig): void {\n super.applyConfig(config);\n\n this._emitter.addToActiveInitBehaviors(this);\n\n if (\"value\" in config) {\n this._staticValue = config.value;\n this._mode = \"static\";\n this._list.reset();\n\n return;\n }\n\n this._mode = config.mode;\n this._list.initialize(config.listData);\n\n if (this._mode === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): AlphaBehaviorConfig | undefined {\n if (\n !this._emitter.isBehaviorInitActive(this) &&\n !this._emitter.isBehaviorUpdateActive(this)\n ) {\n return undefined;\n }\n\n if (this._mode === \"static\") {\n return {\n value: this._staticValue,\n mode: \"static\",\n };\n }\n\n return {\n mode: this._mode,\n listData: {\n list: this._list.list,\n isStepped: this._list.isStepped ? true : undefined,\n },\n };\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n if (this._mode === \"static\") {\n particle.alpha = this._staticValue;\n return;\n }\n\n if (this._mode === \"random\") {\n particle.alpha = this._list.interpolate(Math.random());\n return;\n }\n\n particle.alpha = this._list.interpolate(0);\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType): void {\n particle.alpha = this._list.interpolate(particle.data.agePercent);\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._staticValue = 1.0;\n this._mode = \"static\";\n\n this._emitter.removeFromActiveInitBehaviors(this);\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n}\n","import { RGBAColor } from \"./Types\";\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 * @returns The color in the form of `0xRRGGBB`\n */\nexport function convertRgbToUint(r: number, g: number, b: number): number {\n return (r << 16) | (g << 8) | b;\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 * @returns The object with r, g, and b properties, possibly with an a property.\n */\nexport function convertHexToRGB(color: string, output?: RGBAColor): RGBAColor {\n if (!output) {\n output = {} as RGBAColor;\n }\n\n if (color.charAt(0) === \"#\") {\n color = color.substr(1);\n } else if (color.indexOf(\"0x\") === 0) {\n color = color.substr(2);\n }\n\n let alpha;\n\n if (color.length === 8) {\n alpha = color.substr(0, 2);\n color = color.substr(2);\n }\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\n if (alpha) {\n output.a = parseInt(alpha, 16);\n }\n\n return output;\n}\n\n/**\n * Converts a uint color (0xRRGGBB) to a hex string (\"#RRGGBB\").\n * @param color The color in the form of `0xRRGGBB`\n * @returns The color as a hex string.\n */\nexport function convertUintToHex(color: number): string {\n return `#${color.toString(16).padStart(6, \"0\")}`;\n}\n\n/**\n * Converts a hex string (\"#RRGGBB\") to a uint color (0xRRGGBB).\n * @param color The color as a hex string.\n * @returns The color in the form of `0xRRGGBB`\n */\nexport function convertHexToUint(color: string): number {\n const rgb = convertHexToRGB(color);\n return convertRgbToUint(rgb.r, rgb.g, rgb.b);\n}\n","import { EmitterError } from \"../../error\";\nimport { convertHexToRGB, convertRgbToUint, RGBAColor } from \"../../util\";\nimport { List, ListData, ListNode } from \"./List\";\n\n/**\n * Calculates the simple interpolated color for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated color.\n */\nfunction simpleColor(this: List<RGBAColor>, lerp: number): number {\n if (this.first === null || this.first.next === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First or first.next is null.\",\n );\n }\n\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n if (lerp <= 0) {\n return convertRgbToUint(\n this.first.value.r,\n this.first.value.g,\n this.first.value.b,\n );\n }\n\n if (lerp >= 1) {\n return convertRgbToUint(\n this.first.next.value.r,\n this.first.next.value.g,\n this.first.next.value.b,\n );\n }\n\n const curVal = this.first.value;\n const nextVal = this.first.next.value;\n\n const r = Math.round((nextVal.r - curVal.r) * lerp + curVal.r);\n const g = Math.round((nextVal.g - curVal.g) * lerp + curVal.g);\n const b = Math.round((nextVal.b - curVal.b) * lerp + curVal.b);\n\n return convertRgbToUint(r, g, b);\n}\n\n/**\n * Calculates the complex interpolated color for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated color.\n */\nfunction complexColor(this: List<RGBAColor>, lerp: number): number {\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n // make sure we are on the right segment\n let current = this.first;\n\n if (current === null || current.next === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First or first.next is null.\",\n );\n }\n\n if (lerp <= current.time) {\n return convertRgbToUint(\n current.value.r,\n current.value.g,\n current.value.b,\n );\n }\n\n while (current.next && lerp > current.next.time) {\n current = current.next;\n }\n\n if (!current.next) {\n return convertRgbToUint(\n current.value.r,\n current.value.g,\n current.value.b,\n );\n }\n\n const next = current.next;\n const denom = next.time - current.time;\n\n if (denom === 0) {\n return convertRgbToUint(\n current.value.r,\n current.value.g,\n current.value.b,\n );\n }\n\n // Convert the lerp value to the segment range.\n const t = (lerp - current.time) / denom;\n\n const curVal = current.value;\n const nextVal = next.value;\n\n const r = Math.round((nextVal.r - curVal.r) * t + curVal.r);\n const g = Math.round((nextVal.g - curVal.g) * t + curVal.g);\n const b = Math.round((nextVal.b - curVal.b) * t + curVal.b);\n\n return convertRgbToUint(r, g, b);\n}\n\n/**\n * Calculates the stepped color for the list.\n * @param this The list instance.\n * @param lerp The lerp value.\n * @returns The interpolated color.\n */\nfunction steppedColor(this: List<RGBAColor>, lerp: number): number {\n if (this._easeFunction) lerp = this._easeFunction(lerp);\n\n let current = this.first;\n\n if (current === null || current.next === null) {\n throw new EmitterError(\n \"PropertyList not initialized properly! First or first.next is null.\",\n );\n }\n\n while (current.next && lerp >= current.next.time) {\n current = current.next;\n }\n const currentValue = current.value;\n\n return convertRgbToUint(currentValue.r, currentValue.g, currentValue.b);\n}\n\n/**\n * Implementation of `List` specifically for managing colors.\n * @see {@link List} for the base `List` implementation.\n * @group Data/List/\n */\nexport class ColorList extends List<number, string, RGBAColor> {\n /**\n * @inheritdoc\n */\n public initialize(data: ListData<string>): void {\n super.initialize(data);\n\n const isSimple = this.first.next && this.first.next.time >= 1;\n\n if (isSimple) {\n this.interpolate = simpleColor;\n return;\n }\n\n if (this._isStepped) {\n this.interpolate = steppedColor;\n return;\n }\n\n this.interpolate = complexColor;\n }\n\n /**\n * @inheritdoc\n */\n protected initializeList(data: ListData<string>): void {\n let node: ListNode<RGBAColor> | null = null;\n let first: ListNode<RGBAColor> | null = null;\n\n for (const datum of data.list) {\n const newNode: ListNode<RGBAColor> = {\n value: convertHexToRGB(datum.value),\n time: datum.time,\n next: null,\n };\n\n if (node) {\n node.next = newNode;\n node = newNode;\n }\n\n if (!first) {\n first = newNode;\n node = newNode;\n }\n }\n\n this._first = first;\n }\n}\n","import { ColorList } from \"../../data/list/ColorList\";\nimport { Emitter } from \"../../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport { convertHexToUint, convertUintToHex } from \"../../util\";\nimport {\n BehaviorOrder,\n BehaviorSingleListConfig,\n BehaviorStaticConfig,\n} from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the configuration for ColorBehavior.\n */\nexport type ColorBehaviorConfig =\n | BehaviorStaticConfig<string>\n | BehaviorSingleListConfig<string>;\n\n/**\n * Behavior used to control the color tint of particles over their lifetime.\n *\n * Behavior supports three modes, a `static` mode where a single value is applied to all particles,\n * a `list` mode where values are interpolated over the particle's lifetime based on a provided list,\n * and a `random` mode where a random value from the list is applied to the particle upon initialization.\n * @see {@link BehaviorStaticConfig} for static configuration options.\n * @see {@link BehaviorSingleListConfig} for list configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/ColorBehavior\n * @example\n * ```ts\n * // Apply a static tint to all particles.\n * alphaBehavior.applyConfig({\n * value: \"#ff00ff\"\n * });\n *\n * // Interpolate particle tint from white to black over lifetime.\n * alphaBehavior.applyConfig({\n * listData: [\n * { time: 0.0, value: \"#ffffff\" },\n * { time: 1.0, value: \"#000000\" }\n * ],\n * mode: \"list\"\n * });\n *\n * // Assign a random tint value between the two stops.\n * alphaBehavior.applyConfig({\n * listData: [\n * { time: 0.0, value: \"#ff00ff\" },\n * { time: 1.0, value: \"#00ff00\" }\n * ],\n * mode: \"random\"\n * });\n * ```\n */\nexport class ColorBehavior<\n DataType extends BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<ColorBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private readonly _list: ColorList;\n\n private _staticValue: number = 0xffffff;\n private _mode: \"static\" | \"list\" | \"random\" = \"static\";\n\n /**\n * Creates new instance of ColorBehavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n super(emitter);\n\n this._list = new ColorList();\n }\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"normal\";\n }\n\n /**\n * Color list used to interpolate tint values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get list(): ColorList {\n return this._list;\n }\n\n /**\n * Mode currently used by the behavior.\n */\n public get mode(): \"static\" | \"list\" | \"random\" {\n return this._mode;\n }\n public set mode(value: \"static\" | \"list\" | \"random\") {\n this._mode = value;\n\n if (value === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n } else {\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * Tint value applied to all particles in `static` mode.\n */\n public get staticValue(): string {\n return convertUintToHex(this._staticValue);\n }\n public set staticValue(value: string) {\n this._staticValue = convertHexToUint(value);\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: ColorBehaviorConfig): void {\n super.applyConfig(config);\n\n this._emitter.addToActiveInitBehaviors(this);\n\n if (\"value\" in config) {\n this._staticValue = convertHexToUint(config.value);\n this._mode = \"static\";\n this._list.reset();\n\n return;\n }\n\n this._mode = config.mode;\n this._list.initialize(config.listData);\n\n if (this._mode === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): ColorBehaviorConfig | undefined {\n if (\n !this._emitter.isBehaviorInitActive(this) &&\n !this._emitter.isBehaviorUpdateActive(this)\n ) {\n return undefined;\n }\n\n if (this._mode === \"static\") {\n return {\n value: convertUintToHex(this._staticValue),\n mode: \"static\",\n };\n }\n\n return {\n mode: this._mode,\n listData: {\n list: this._list.list,\n isStepped: this._list.isStepped ? true : undefined,\n },\n };\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n if (this._mode === \"static\") {\n particle.tint = this._staticValue;\n return;\n }\n\n if (this._mode === \"random\") {\n particle.tint = this._list.interpolate(Math.random());\n return;\n }\n\n particle.tint = this._list.interpolate(0);\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType): void {\n particle.tint = this._list.interpolate(particle.data.agePercent);\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._staticValue = 0xffffff;\n this._mode = \"static\";\n\n this._emitter.removeFromActiveInitBehaviors(this);\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n}\n","import { PointData } from \"pixi.js\";\nimport { ListData } from \"../../data/list/List\";\nimport { NumberList } from \"../../data/list/NumberList\";\nimport { Emitter } from \"../../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport { BehaviorOrder } from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the possible movement spaces.\n */\nexport type MovementSpace = \"local\" | \"global\";\n\n/**\n * Type defining the configuration for movement behavior using min/max speeds.\n * @group Behavior/MovementBehavior/\n */\nexport type MinMaxConfigType = {\n /**\n * Minimum movement speed for X and Y axes.\n */\n minMoveSpeed: PointData;\n /**\n * Maximum movement speed for X and Y axes.\n */\n maxMoveSpeed: PointData;\n /**\n * Movement mode. In `linear` mode particles move at a constant speed, while in\n * `acceleration` mode particles accelerate over time based on initial speed.\n */\n mode?: \"linear\" | \"acceleration\";\n\n /**\n * Space in which movement is applied. In `local` space, movement is relative to the particle's\n * initial direction, while in `global` space movement is applied relative to the container.\n */\n space?: MovementSpace;\n};\n\n/**\n * Type defining the configuration for movement behavior using lists.\n * @group Behavior/MovementBehavior/\n */\nexport type ListConfigType = {\n /**\n * X axis list data defining all properties required for list-based behavior.\n * @see {@link ListData}\n */\n xListData: ListData<number>;\n /**\n * Y axis list data defining all properties required for list-based behavior.\n * If not provided, `xListData` will be used for both axes.\n * @see {@link ListData}\n */\n yListData?: ListData<number>;\n /**\n * Movement mode. In `linear` mode particles move at a constant speed, while in\n * `acceleration` mode particles accelerate over time based on initial speed.\n */\n mode?: \"linear\" | \"acceleration\";\n /**\n * Space in which movement is applied. In `local` space, movement is relative to the particle's\n * initial direction, while in `global` space movement is applied relative to the container.\n */\n space?: MovementSpace;\n};\n\n/**\n * Type defining the configuration for MovementBehavior.\n */\nexport type MovementBehaviorConfig = MinMaxConfigType | ListConfigType;\n\n/**\n * Behavior used to control particle movement over their lifetime.\n *\n * This behavior supports two configuration modes, either by specifying minimum and maximum\n * movement speeds for the X and Y axes, or by providing list data to define movement values\n * over the particle's lifetime.\n * @see {@link MinMaxConfigType} for min/max speed configuration options.\n * @see {@link ListConfigType} for list-based configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/MovementBehavior\n * @example\n * ```ts\n * // Configure movement using min/max speeds.\n * movementBehavior.applyConfig({\n * minMoveSpeed: { x: -50, y: -100 },\n * maxMoveSpeed: { x: 50, y: 100 },\n * mode: \"linear\",\n * space: \"global\"\n * });\n *\n * // Configure movement using lists.\n * movementBehavior.applyConfig({\n * xListData: {\n * list: [\n * { time: 0.0, value: 0 },\n * { time: 1.0, value: 100 }\n * ]\n * },\n * yListData: {\n * list: [\n * { time: 0.0, value: 0 },\n * { time: 1.0, value: -100 }\n * ]\n * },\n * mode: \"acceleration\",\n * space: \"local\"\n * });\n * ```\n */\nexport class MovementBehavior<\n DataType extends BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<MovementBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private readonly _xList: NumberList;\n private readonly _yList: NumberList;\n\n private _mode: \"acceleration\" | \"linear\" = \"linear\";\n private _space: MovementSpace = \"local\";\n\n private _useList: boolean = false;\n\n private _minMoveSpeed: PointData = { x: 0, y: 0 };\n private _maxMoveSpeed: PointData = { x: 0, y: 0 };\n\n /**\n * Creates new instance of MovementBehavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n super(emitter);\n\n this._xList = new NumberList();\n this._yList = new NumberList();\n }\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"late\";\n }\n\n /**\n * Number list used to interpolate X-axis movement values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get xList(): NumberList {\n return this._xList;\n }\n\n /**\n * Number list used to interpolate Y-axis movement values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get yList(): NumberList {\n return this._yList;\n }\n\n /**\n * Space in which movement is applied.\n */\n public get space(): \"local\" | \"global\" {\n return this._space;\n }\n public set space(value: \"local\" | \"global\") {\n this._space = value;\n }\n\n /**\n * Movement mode currently used by the behavior.\n */\n public get mode(): \"acceleration\" | \"linear\" {\n return this._mode;\n }\n public set mode(value: \"acceleration\" | \"linear\") {\n this._mode = value;\n }\n\n /**\n * Whether to use list-based movement configuration.\n */\n public get useList(): boolean {\n return this._useList;\n }\n public set useList(value: boolean) {\n this._useList = value;\n }\n\n /**\n * Minimum movement speed (used when not using lists).\n */\n public get minMoveSpeed(): PointData {\n return this._minMoveSpeed;\n }\n public set minMoveSpeed(value: PointData) {\n this._minMoveSpeed.x = value.x;\n this._minMoveSpeed.y = value.y;\n }\n\n /**\n * Maximum movement speed (used when not using lists).\n */\n public get maxMoveSpeed(): PointData {\n return this._maxMoveSpeed;\n }\n public set maxMoveSpeed(value: PointData) {\n this._maxMoveSpeed.x = value.x;\n this._maxMoveSpeed.y = value.y;\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: MovementBehaviorConfig): void {\n super.applyConfig(config);\n\n if (\"minMoveSpeed\" in config && \"maxMoveSpeed\" in config) {\n this._minMoveSpeed = config.minMoveSpeed;\n this._maxMoveSpeed = config.maxMoveSpeed;\n this._useList = false;\n } else {\n this._xList.initialize(config.xListData);\n this._yList.initialize(config.yListData ?? config.xListData);\n this._useList = true;\n }\n\n this._mode = config.mode ?? \"linear\";\n this._space = config.space ?? \"global\";\n\n this._emitter.addToActiveInitBehaviors(this);\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): MovementBehaviorConfig | undefined {\n if (\n !this._emitter.isBehaviorInitActive(this) &&\n !this._emitter.isBehaviorUpdateActive(this)\n ) {\n return undefined;\n }\n\n if (this._useList) {\n return {\n xListData: {\n list: this._xList.list,\n isStepped: this._xList.isStepped ? true : undefined,\n },\n yListData: {\n list: this._yList.list,\n isStepped: this._xList.isStepped ? true : undefined,\n },\n mode: this._mode,\n space: this._space,\n };\n }\n\n return {\n minMoveSpeed: this._minMoveSpeed,\n maxMoveSpeed: this._maxMoveSpeed,\n mode: this._mode,\n space: this._space,\n };\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n const particleData = particle.data;\n\n let xVelocity: number;\n let yVelocity: number;\n\n if (this._useList) {\n xVelocity = this._xList.interpolate(0);\n yVelocity = this._yList.interpolate(0);\n } else {\n xVelocity =\n Math.random() * (this._maxMoveSpeed.x - this._minMoveSpeed.x) +\n this._minMoveSpeed.x;\n\n yVelocity =\n Math.random() * (this._maxMoveSpeed.y - this._minMoveSpeed.y) +\n this._minMoveSpeed.y;\n }\n\n // TODO: Make particles rotation aware.\n // TODO: Add logic to SpawnBehavior where direction vector can be set.\n\n if (this._space === \"local\") {\n const dirX = particleData.directionVectorX;\n const dirY = particleData.directionVectorY;\n const length = Math.sqrt(dirX * dirX + dirY * dirY);\n const forwardX = dirX / length;\n const forwardY = dirY / length;\n const perpX = -forwardY;\n const perpY = forwardX;\n\n const finalX = forwardX * yVelocity + perpX * xVelocity;\n const finalY = forwardY * yVelocity + perpY * xVelocity;\n\n particleData.accelerationX = finalX;\n particleData.accelerationY = finalY;\n\n particleData.velocityX = finalX;\n particleData.velocityY = finalY;\n return;\n }\n\n particleData.accelerationX = xVelocity;\n particleData.accelerationY = yVelocity;\n\n particleData.velocityX = xVelocity;\n particleData.velocityY = yVelocity;\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType, deltaTime: number): void {\n const particleData = particle.data;\n\n if (this._mode === \"acceleration\") {\n let xAcceleration: number;\n let yAcceleration: number;\n\n if (this._useList) {\n const xValue = this._xList.interpolate(particleData.agePercent);\n const yValue = this._yList.interpolate(particleData.agePercent);\n\n if (this._space === \"local\") {\n const dirX = particleData.directionVectorX;\n const dirY = particleData.directionVectorY;\n const length = Math.sqrt(dirX * dirX + dirY * dirY);\n const forwardX = dirX / length;\n const forwardY = dirY / length;\n const perpX = -forwardY;\n const perpY = forwardX;\n\n xAcceleration = forwardX * yValue + perpX * xValue;\n yAcceleration = forwardY * yValue + perpY * xValue;\n } else {\n xAcceleration = xValue;\n yAcceleration = yValue;\n }\n } else {\n xAcceleration = particleData.accelerationX;\n yAcceleration = particleData.accelerationY;\n }\n\n particleData.velocityX += xAcceleration * deltaTime;\n particleData.velocityY += yAcceleration * deltaTime;\n }\n\n particle.x += particleData.velocityX * deltaTime;\n particle.y += particleData.velocityY * deltaTime;\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._mode = \"linear\";\n this._space = \"global\";\n\n this._minMoveSpeed.x = 0;\n this._minMoveSpeed.y = 0;\n this._maxMoveSpeed.x = 0;\n this._maxMoveSpeed.y = 0;\n\n this._useList = false;\n }\n}\n","import { NumberList } from \"../../data/list/NumberList\";\nimport { Emitter } from \"../../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport {\n BehaviorOrder,\n BehaviorSingleListConfig,\n BehaviorStaticConfig,\n} from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the configuration for direction mode.\n * @group Behavior/RotationBehavior/\n */\nexport type DirectionConfigType = {\n /**\n * Particles will have their rotation set on initialization based on their movement direction.\n */\n mode: \"direction\";\n};\n\n/**\n * Type defining the configuration for acceleration mode.\n * @group Behavior/RotationBehavior/\n */\nexport type AccelerationConfigType = {\n /**\n * Initial rotation value for the particle.\n */\n startRotation: number;\n /**\n * Rotation acceleration applied over time.\n */\n acceleration: number;\n /**\n * Acceleration mode will rotate particles over time based on the acceleration value.\n */\n mode: \"acceleration\";\n};\n\n/**\n * Type defining the configuration for RotationBehavior.\n */\nexport type RotationBehaviorConfig =\n | DirectionConfigType\n | BehaviorStaticConfig<number>\n | BehaviorSingleListConfig<number>\n | AccelerationConfigType;\n\n/**\n * Behavior used to control the rotation of particles over their lifetime.\n *\n * Behavior supports four modes, a `static` mode where a single value is applied to all particles,\n * a `list` mode where values are interpolated over the particle's lifetime based on a provided list,\n * a `direction` mode where the rotation is set based on the particle's movement direction,\n * and an `acceleration` mode where the rotation changes over time based on an acceleration value.\n * @see {@link DirectionConfigType} for direction configuration options.\n * @see {@link AccelerationConfigType} for acceleration configuration options.\n * @see {@link BehaviorStaticConfig} for static configuration options.\n * @see {@link BehaviorSingleListConfig} for list configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/RotationBehavior\n * @example\n * ```ts\n * // Apply a static rotation of 45 degrees to all particles.\n * rotationBehavior.applyConfig({\n * value: Math.PI / 4\n * });\n *\n * // Interpolate particle rotation from 0 to 360 degrees over lifetime.\n * rotationBehavior.applyConfig({\n * listData: [\n * { time: 0.0, value: 0 },\n * { time: 1.0, value: Math.PI * 2 }\n * ],\n * mode: \"list\"\n * });\n * ```\n */\nexport class RotationBehavior<\n DataType extends BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<RotationBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private readonly _list: NumberList;\n\n private _mode: \"static\" | \"list\" | \"random\" | \"acceleration\" | \"direction\" =\n \"static\";\n\n private _staticValue: number = 0;\n private _startRotation: number = 0;\n private _acceleration: number = 0;\n\n /**\n * Creates a new RotationBehavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n super(emitter);\n\n this._list = new NumberList();\n }\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"normal\";\n }\n\n /**\n * Number list used to interpolate rotation values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get list(): NumberList {\n return this._list;\n }\n\n /**\n * Current mode used by the behavior.\n */\n public get mode():\n | \"static\"\n | \"list\"\n | \"random\"\n | \"acceleration\"\n | \"direction\" {\n return this._mode;\n }\n public set mode(value: \"static\" | \"list\" | \"acceleration\" | \"direction\") {\n this._mode = value;\n }\n\n /**\n * Static rotation value applied to all particles.\n */\n public get staticValue(): number {\n return this._staticValue;\n }\n public set staticValue(value: number) {\n this._staticValue = value;\n }\n\n /**\n * Rotation acceleration applied over time (used for acceleration mode).\n */\n public get acceleration(): number {\n return this._acceleration;\n }\n public set acceleration(value: number) {\n this._acceleration = value;\n }\n\n /**\n * Initial rotation value for the particle (used for acceleration mode).\n */\n public get startRotation(): number {\n return this._startRotation;\n }\n public set startRotation(value: number) {\n this._startRotation = value;\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: RotationBehaviorConfig): void {\n super.applyConfig(config);\n\n this._emitter.addToActiveInitBehaviors(this);\n\n if (config.mode === \"direction\") {\n this._mode = \"direction\";\n return;\n }\n\n if (config.mode === \"static\") {\n this._mode = \"static\";\n this._staticValue = config.value;\n this._list.reset();\n return;\n }\n\n if (config.mode === \"acceleration\") {\n this._mode = \"acceleration\";\n this._startRotation = config.startRotation;\n this._acceleration = config.acceleration;\n\n this._list.reset();\n this._emitter.addToActiveUpdateBehaviors(this);\n return;\n }\n\n this._mode = config.mode;\n this._list.initialize(config.listData);\n\n if (this._mode === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): RotationBehaviorConfig | undefined {\n if (\n !this._emitter.isBehaviorInitActive(this) &&\n !this._emitter.isBehaviorUpdateActive(this)\n ) {\n return undefined;\n }\n\n if (this._mode === \"direction\") {\n return { mode: \"direction\" };\n }\n\n if (this._mode === \"static\") {\n return {\n value: this._staticValue,\n mode: \"static\",\n };\n }\n\n if (this._mode === \"list\" || this._mode === \"random\") {\n return {\n mode: this._mode,\n listData: {\n list: this._list.list,\n isStepped: this._list.isStepped ? true : undefined,\n },\n };\n }\n\n return {\n startRotation: this._startRotation,\n acceleration: this._acceleration,\n mode: \"acceleration\",\n };\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n if (this._mode === \"list\") {\n particle.rotation = this._list.interpolate(0);\n return;\n }\n\n if (this._mode === \"random\") {\n particle.rotation = this._list.interpolate(Math.random());\n return;\n }\n\n if (this._mode === \"direction\") {\n particle.rotation = Math.atan2(\n particle.data.directionVectorY,\n particle.data.directionVectorX,\n );\n\n return;\n }\n\n if (this._mode === \"static\") {\n particle.rotation = this._staticValue;\n return;\n }\n\n particle.rotation = this._startRotation;\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType, deltaTime: number): void {\n if (this._mode === \"list\") {\n particle.rotation = this._list.interpolate(\n particle.data.agePercent,\n );\n return;\n }\n\n particle.rotation += this._acceleration * deltaTime;\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._staticValue = 0;\n this._mode = \"static\";\n\n this._emitter.removeFromActiveInitBehaviors(this);\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n}\n","import { PointData } from \"pixi.js\";\nimport { NumberList } from \"../../data/list/NumberList\";\nimport { Emitter } from \"../../Emitter\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport {\n BehaviorOrder,\n BehaviorStaticConfig,\n BehaviorXYListConfig,\n} from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the configuration for ScaleBehavior.\n */\nexport type ScaleBehaviorConfig =\n | BehaviorStaticConfig<PointData>\n | BehaviorXYListConfig<number>;\n\n/**\n * Behavior used to control the scale of particles over their lifetime.\n *\n * Behavior supports three modes, a `static` mode where a single value is applied to all particles,\n * a `list` mode where values are interpolated over the particle's lifetime based on provided lists,\n * and a `random` mode where random values from the lists are applied to the particle upon initialization.\n * @see {@link BehaviorStaticConfig} for static configuration options.\n * @see {@link BehaviorXYListConfig} for list configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/ScaleBehavior\n * @example\n * ```ts\n * // Apply a static scale of 2x on both axes to all particles.\n * scaleBehavior.applyConfig({\n * value: { x: 2, y: 2 }\n * });\n *\n * // Interpolate particle scale from 0.5x to 1.5x on X axis and 1.0x to 2.0x on Y axis over lifetime.\n * scaleBehavior.applyConfig({\n * xListData: [\n * { time: 0.0, value: 0.5 },\n * { time: 1.0, value: 1.5 }\n * ],\n * yListData: [\n * { time: 0.0, value: 1.0 },\n * { time: 1.0, value: 2.0 }\n * ],\n * mode: \"list\"\n * });\n *\n * // Assign a random scale between 1.0x and 3.0x on X axis and between 0.5x and 2.5x on Y axis.\n * scaleBehavior.applyConfig({\n * xListData: [\n * { time: 0.0, value: 1.0 },\n * { time: 1.0, value: 3.0 }\n * ],\n * yListData: [\n * { time: 0.0, value: 0.5 },\n * { time: 1.0, value: 2.5 }\n * ],\n * mode: \"random\"\n * });\n * ```\n */\nexport class ScaleBehavior<\n DataType extends BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<ScaleBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private readonly _xList: NumberList;\n private readonly _yList: NumberList;\n\n private _mode: \"static\" | \"list\" | \"random\" = \"static\";\n private _staticValue: PointData = { x: 1, y: 1 };\n\n /**\n * Creates a new ScaleBehavior.\n * @param emitter Emitter instance this behavior belongs to.\n */\n constructor(emitter: Emitter<DataType, ParticleType>) {\n super(emitter);\n\n this._xList = new NumberList();\n this._yList = new NumberList();\n }\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"normal\";\n }\n\n /**\n * Static scale value applied to all particles.\n */\n public get staticValue(): PointData {\n return this._staticValue;\n }\n\n /**\n * Number list used to interpolate X-axis scale values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get xList(): NumberList {\n return this._xList;\n }\n\n /**\n * Number list used to interpolate Y-axis scale values over particle lifetime.\n *\n * A behavior will always have a list, even when not using list-based configuration,\n * but the list might not be initialized and will be empty in that case.\n */\n public get yList(): NumberList {\n return this._yList;\n }\n\n /**\n * Current mode used by the behavior.\n */\n public get mode(): \"static\" | \"list\" | \"random\" {\n return this._mode;\n }\n public set mode(value: \"static\" | \"list\" | \"random\") {\n this._mode = value;\n\n if (this._mode === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n } else {\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: ScaleBehaviorConfig): void {\n super.applyConfig(config);\n\n this._emitter.addToActiveInitBehaviors(this);\n\n if (\"value\" in config) {\n this._mode = \"static\";\n this._staticValue = config.value;\n return;\n }\n\n this._mode = config.mode;\n this._xList.initialize(config.xListData);\n this._yList.initialize(\n config.yListData ? config.yListData : config.xListData,\n );\n\n if (this._mode === \"list\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): ScaleBehaviorConfig | undefined {\n if (\n !this._emitter.isBehaviorInitActive(this) &&\n !this._emitter.isBehaviorUpdateActive(this)\n ) {\n return undefined;\n }\n\n if (this._mode === \"static\") {\n return {\n value: this._staticValue,\n mode: \"static\",\n };\n }\n\n return {\n xListData: {\n list: this._xList.list,\n isStepped: this._xList.isStepped ? true : undefined,\n },\n yListData: {\n list: this._yList.list,\n isStepped: this._xList.isStepped ? true : undefined,\n },\n mode: this._mode,\n };\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n if (this._mode === \"static\") {\n particle.scaleX = this._staticValue.x;\n particle.scaleY = this._staticValue.y;\n return;\n }\n\n const i = this._mode === \"random\" ? Math.random() : 0;\n const xScale = this._xList.interpolate(i);\n const yScale = this._yList.interpolate(i);\n\n particle.scaleX = xScale;\n particle.scaleY = yScale;\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType): void {\n const xScale = this._xList.interpolate(particle.data.agePercent);\n const yScale = this._yList.interpolate(particle.data.agePercent);\n\n particle.scaleX = xScale;\n particle.scaleY = yScale;\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._mode = \"static\";\n this._staticValue.x = 1;\n this._staticValue.y = 1;\n\n this._emitter.removeFromActiveInitBehaviors(this);\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n}\n","import { PointData } from \"pixi.js\";\nimport { EmitterError } from \"../../error\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport { BehaviorOrder } from \"../../util/Types\";\nimport { EmitterBehavior, InitBehavior } from \"../EmitterBehavior\";\n\n/**\n * Type defining the possible spawn shapes for SpawnBehavior.\n *\n * - `point`: Particles spawn from a single point at the origin position.\n * - `line`: Particles spawn along a line centered at the origin position.\n * - `rectangle`: Particles spawn within a rectangle centered at the origin position.\n * - `circle`: Particles spawn within a circle centered at the origin position.\n * @group Behavior/SpawnBehavior/\n */\nexport type SpawnShape = \"point\" | \"line\" | \"rectangle\" | \"circle\";\n\n/**\n * Type defining the point spawn configuration.\n * @group Behavior/SpawnBehavior/\n */\nexport type PointConfig = {\n /**\n * Particles spawn from single point at the origin position.\n */\n shape: \"point\";\n};\n\n/**\n * Type defining the line spawn configuration.\n * @group Behavior/SpawnBehavior/\n */\nexport type LineConfig = {\n /**\n * Particles spawn along a line centered at the origin position.\n */\n shape: \"line\";\n /**\n * Length of the line along which particles will spawn.\n */\n length: number;\n};\n\n/**\n * Type defining the rectangle spawn configuration.\n * @group Behavior/SpawnBehavior/\n */\nexport type RectangleConfig = {\n /**\n * Particles spawn within a rectangle centered at the origin position.\n */\n shape: \"rectangle\";\n /**\n * Width of the rectangle.\n */\n width: number;\n /**\n * Height of the rectangle. If not provided, the height will be equal to the width.\n */\n height?: number;\n};\n\n/**\n * Type defining the circle spawn configuration.\n * @group Behavior/SpawnBehavior/\n */\nexport type CircleConfig = {\n /**\n * Particles spawn within a circle centered at the origin position.\n */\n shape: \"circle\";\n /**\n * Outer radius of the circle.\n */\n outerRadius: number;\n /**\n * Inner radius of the circle. If not provided, the inner radius will be 0.\n */\n innerRadius?: number;\n};\n\n/**\n * Type defining the configuration for SpawnBehavior.\n */\nexport type SpawnBehaviorConfig = {\n direction?: PointData;\n} & (PointConfig | LineConfig | RectangleConfig | CircleConfig);\n\n/**\n * Behavior used to control the spawning shape and initial direction of particles.\n *\n * Behavior supports four shapes, a `point` shape where particles spawn from a single point,\n * a `line` shape where particles spawn along a line,\n * a `rectangle` shape where particles spawn within a rectangle area,\n * and a `circle` shape where particles spawn within a circular area.\n * @see {@link SpawnBehaviorConfig} for configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/SpawnBehavior\n * @example\n * ```ts\n * // Spawn particles from a point with an initial upward direction.\n * spawnBehavior.applyConfig({\n * shape: \"point\",\n * direction: { x: 0, y: -1 }\n * });\n * ```\n * @example\n * ```ts\n * // Spawn particles along a horizontal line of\n * // length 200 with no initial direction.\n * spawnBehavior.applyConfig({\n * shape: \"line\",\n * length: 200,\n * direction: { x: 0, y: 0 }\n * });\n * ```\n * @example\n * ```ts\n * // Spawn particles within a rectangle of width 100 and\n * // height 50 with an initial rightward direction.\n * spawnBehavior.applyConfig({\n * shape: \"rectangle\",\n * width: 100,\n * height: 50,\n * direction: { x: 1, y: 0 }\n * });\n * ```\n * @example\n * ```ts\n * // Spawn particles within a circle of outer radius 75 and\n * // inner radius 25 with no initial direction.\n * spawnBehavior.applyConfig({\n * shape: \"circle\",\n * outerRadius: 75,\n * innerRadius: 25,\n * direction: { x: 0, y: 0 }\n * });\n * ```\n */\nexport class SpawnBehavior<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<SpawnBehaviorConfig, DataType, ParticleType>\n implements InitBehavior<DataType, ParticleType>\n{\n private _shape: \"point\" | \"line\" | \"rectangle\" | \"circle\" = \"point\";\n\n private _width: number = 0;\n private _height: number = 0;\n\n private _innerRadius: number = 0;\n private _outerRadius: number = 0;\n\n private _directionVector: PointData = { x: 0, y: 0 };\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"initial\";\n }\n\n /**\n * Initial direction vector for spawned particles.\n */\n public get direction(): PointData {\n return this._directionVector;\n }\n public set direction(value: PointData) {\n this._directionVector.x = value.x;\n this._directionVector.y = value.y;\n }\n\n /**\n * Current spawn shape used by the behavior.\n */\n public get shape(): SpawnShape {\n return this._shape;\n }\n public set shape(value: SpawnShape) {\n this._shape = value;\n }\n\n /**\n * Width of the spawn shape (for rectangle and line shapes).\n */\n public get width(): number {\n return this._width;\n }\n public set width(value: number) {\n this._width = value;\n }\n\n /**\n * Height of the spawn shape (for rectangle shape).\n */\n public get height(): number {\n return this._height;\n }\n public set height(value: number) {\n this._height = value;\n }\n\n /**\n * Inner radius of the spawn shape (for circle shape).\n */\n public get innerRadius(): number {\n return this._innerRadius;\n }\n public set innerRadius(value: number) {\n this._innerRadius = value;\n }\n\n /**\n * Outer radius of the spawn shape (for circle shape).\n */\n public get outerRadius(): number {\n return this._outerRadius;\n }\n public set outerRadius(value: number) {\n this._outerRadius = value;\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: SpawnBehaviorConfig): void {\n super.applyConfig(config);\n\n this._directionVector = config.direction ?? { x: 0, y: 0 };\n\n if (config.shape === \"point\") {\n this._shape = \"point\";\n return;\n }\n\n if (config.shape === \"line\") {\n this._shape = \"line\";\n this._width = config.length;\n return;\n }\n\n if (config.shape === \"rectangle\") {\n this._shape = \"rectangle\";\n this._width = config.width;\n this._height = config.height ?? config.width;\n return;\n }\n\n if (config.shape === \"circle\") {\n this._shape = \"circle\";\n this._outerRadius = config.outerRadius;\n this._innerRadius = config.innerRadius ?? 0;\n return;\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): SpawnBehaviorConfig {\n if (this._shape === \"point\") {\n return {\n shape: \"point\",\n direction: this._directionVector,\n };\n }\n\n if (this._shape === \"line\") {\n return {\n shape: \"line\",\n length: this._width,\n direction: this._directionVector,\n };\n }\n\n if (this._shape === \"rectangle\") {\n return {\n shape: \"rectangle\",\n width: this._width,\n height: this._height === this._width ? undefined : this._height,\n direction: this._directionVector,\n };\n }\n\n if (this._shape === \"circle\") {\n return {\n shape: \"circle\",\n outerRadius: this._outerRadius,\n innerRadius:\n this._innerRadius === this._outerRadius\n ? undefined\n : this._innerRadius,\n direction: this._directionVector,\n };\n }\n\n throw new EmitterError(\"Invalid spawn shape, cannot get config.\");\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n const particleData = particle.data;\n\n particleData.directionVectorX = this._directionVector.x;\n particleData.directionVectorY = this._directionVector.y;\n\n if (this._shape === \"point\") {\n particle.x = 0;\n particle.y = 0;\n return;\n }\n\n let x = 0;\n let y = 0;\n\n if (this._shape === \"rectangle\") {\n x = Math.random() * this._width - this._width * 0.5;\n y = Math.random() * this._height - this._height * 0.5;\n }\n\n if (this._shape === \"circle\") {\n const theta = Math.random() * 2 * Math.PI;\n\n const radius = Math.sqrt(\n this._innerRadius * this._innerRadius +\n (this._outerRadius * this._outerRadius -\n this._innerRadius * this._innerRadius) *\n Math.random(),\n );\n\n x = radius * Math.cos(theta);\n y = radius * Math.sin(theta);\n }\n\n if (this._shape === \"line\") {\n x = Math.random() * this._width - this._width * 0.5;\n y = 0;\n }\n\n particle.x = x;\n particle.y = y;\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._shape = \"point\";\n\n this._width = 0;\n this._height = 0;\n\n this._innerRadius = 0;\n this._outerRadius = 0;\n }\n}\n","import { Texture } from \"pixi.js\";\nimport { EmitterError } from \"../../error\";\nimport {\n BaseParticleData,\n IEmitterParticle,\n} from \"../../particle/EmitterParticle\";\nimport { BehaviorMode, BehaviorOrder } from \"../../util/Types\";\nimport {\n EmitterBehavior,\n InitBehavior,\n UpdateBehavior,\n} from \"../EmitterBehavior\";\n\n/**\n * Type defining the configuration mode for TextureBehavior.\n */\ntype TextureBehaviorMode = Extract<\n BehaviorMode,\n \"static\" | \"random\" | \"animated\"\n>;\n\n/**\n * Type defining the texture animation configuration for particles.\n * @group Behavior/TextureBehavior/\n */\nexport type TextureConfig = {\n textures: Texture[];\n framerate?: number;\n duration?: number;\n loop?: boolean;\n};\n\n/**\n * Type defining the configuration for TextureBehavior.\n * @group Behavior/TextureBehavior/\n */\nexport type TextureBehaviorConfig = {\n textureConfigs: TextureConfig[];\n mode: TextureBehaviorMode;\n};\n\n/**\n * Behavior used to control the texture of particles over their lifetime.\n *\n * Behavior supports three modes, a `static` mode where a single texture is applied to all particles,\n * a `random` mode where a random texture from the provided textures is applied to the particle upon initialization,\n * and an `animated` mode where textures are animated over the particle's lifetime based on the provided configuration.\n * @see {@link TextureBehaviorConfig} for configuration options.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Behavior/TextureBehavior\n * @example\n * ```ts\n * // Apply a static texture to all particles.\n * textureBehavior.applyConfig({\n * textureConfigs: [\n * { textures: [PIXI.Texture.from(\"particle.png\")] }\n * ],\n * mode: \"static\"\n * });\n * ```\n */\nexport class TextureBehavior<\n DataType extends BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n>\n extends EmitterBehavior<TextureBehaviorConfig, DataType, ParticleType>\n implements\n InitBehavior<DataType, ParticleType>,\n UpdateBehavior<DataType, ParticleType>\n{\n private _textureConfigs: TextureConfig[] = [];\n private _mode: TextureBehaviorMode = \"static\";\n\n /**\n * @inheritdoc\n */\n public get updateOrder(): BehaviorOrder {\n return \"initial\";\n }\n\n /**\n * @inheritdoc\n */\n public applyConfig(config: TextureBehaviorConfig): void {\n super.applyConfig(config);\n\n this._textureConfigs = config.textureConfigs;\n this._mode = config.mode;\n\n if (this._mode === \"animated\") {\n this._emitter.addToActiveUpdateBehaviors(this);\n }\n }\n\n /**\n * @inheritdoc\n */\n public getConfig(): TextureBehaviorConfig | undefined {\n // TODO: Need to figure out a neat way to handle texture configs.\n // TODO: Textures cannot be serialized, so this will be tricky.\n // TODO: Could maybe return just the mode and length, and replace textures with placeholders?\n return undefined;\n }\n\n /**\n * @inheritdoc\n */\n public init(particle: ParticleType): void {\n if (this._textureConfigs.length === 0) {\n particle.texture = Texture.WHITE;\n return;\n }\n\n const config =\n this._textureConfigs[\n Math.floor(Math.random() * this._textureConfigs.length)\n ];\n\n if (this._mode === \"static\") {\n particle.texture = config.textures[0];\n return;\n }\n\n if (this._mode === \"random\") {\n particle.texture =\n config.textures[\n Math.floor(Math.random() * config.textures.length)\n ];\n\n return;\n }\n\n const particleData = particle.data;\n\n particleData.textureConfig.textures = config.textures;\n particleData.textureConfig.elapsed = 0;\n\n if (!config.framerate || !config.duration) {\n particleData.textureConfig.duration = particle.data.maxLifetime;\n particleData.textureConfig.framerate =\n config.textures.length / particle.data.maxLifetime;\n } else {\n particleData.textureConfig.framerate = config.framerate;\n particleData.textureConfig.duration = config.duration;\n }\n\n const texture = config.textures[0];\n particle.texture = texture;\n }\n\n /**\n * @inheritdoc\n */\n public update(particle: ParticleType, deltaTime: number): void {\n const config = particle.data.textureConfig;\n config.elapsed += deltaTime;\n\n if (config.elapsed >= config.duration) {\n if (config.loop) {\n config.elapsed = config.elapsed % config.duration;\n } else {\n config.elapsed = config.duration - 0.000001;\n }\n }\n\n const frameIndex = (config.elapsed * config.framerate + 0.0000001) | 0;\n particle.texture = config.textures[frameIndex];\n\n if (particle.texture === undefined) {\n throw new EmitterError(\n `Texture undefined in TextureBehavior update ${frameIndex}`,\n );\n }\n }\n\n /**\n * @inheritdoc\n */\n protected reset(): void {\n this._textureConfigs.length = 0;\n this._mode = \"static\";\n\n this._emitter.removeFromActiveUpdateBehaviors(this);\n }\n}\n","import { Particle, Texture } from \"pixi.js\";\n\n/**\n * Base data structure for emitter particles.\n * @group EmitterParticle/\n */\nexport type BaseParticleData = {\n /**\n * Maximum lifetime of the particle in milliseconds.\n */\n maxLifetime: number;\n /**\n * Current age of the particle in milliseconds.\n */\n age: number;\n /**\n * Age percent of the particle's lifetime (0.0 to 1.0).\n */\n agePercent: number;\n /**\n * One over the lifetime of the particle (1.0 / maxLifetime).\n */\n oneOverLifetime: number;\n\n /**\n * Direction vector components of the particle.\n */\n directionVectorX: number;\n /**\n * Direction vector Y component of the particle.\n */\n directionVectorY: number;\n\n /**\n * Acceleration components of the particle.\n */\n accelerationX: number;\n /**\n * Acceleration Y component of the particle.\n */\n accelerationY: number;\n\n /**\n * Velocity components of the particle.\n */\n velocityX: number;\n /**\n *\n */\n velocityY: number;\n\n /**\n * Texture animation configuration for the particle.\n */\n textureConfig: {\n /**\n * Array of textures used for the particle.\n */\n textures: Texture[];\n /**\n * Duration of the texture animation in milliseconds.\n */\n duration: number;\n /**\n * Elapsed time of the texture animation in milliseconds.\n */\n elapsed: number;\n /**\n * Frame rate of the texture animation (frames per second).\n */\n framerate: number;\n /**\n * Whether the texture animation should loop.\n */\n loop: boolean;\n };\n};\n\n/**\n * Base interface for particles used by the Emitter.\n * @template DataType Type describing the data object stored on particles.\n * @group EmitterParticle/\n */\nexport interface IEmitterParticle<\n DataType extends BaseParticleData = BaseParticleData,\n> extends Particle {\n /**\n * Particle data used by emitter behaviors.\n * @see {@link BaseParticleData} for the structure of the data.\n */\n data: DataType;\n\n /**\n * Invoked when particle is fetched from pool.\n */\n onFetch(): void;\n\n /**\n * Invoked when particle is returned to pool.\n */\n onRecycle(): void;\n}\n\n/**\n * Creates a new instance of BaseParticleData with default values.\n * @returns A new BaseParticleData object with default values.\n * @group EmitterParticle/\n */\nexport function createBaseParticleData(): BaseParticleData {\n return {\n age: 0,\n agePercent: 0,\n maxLifetime: 0,\n oneOverLifetime: 0,\n directionVectorX: 0,\n directionVectorY: 0,\n accelerationX: 0,\n accelerationY: 0,\n velocityX: 0,\n velocityY: 0,\n textureConfig: {\n textures: [],\n duration: 0,\n elapsed: 0,\n framerate: 0,\n loop: false,\n },\n };\n}\n\n/**\n * Resets the base particle data.\n * @param data Data to reset.\n * @group EmitterParticle/\n */\nexport function resetBaseParticleData(data: BaseParticleData): void {\n data.age = 0;\n data.agePercent = 0;\n data.maxLifetime = 0;\n data.oneOverLifetime = 0;\n\n data.directionVectorX = 0;\n data.directionVectorY = 0;\n\n data.accelerationX = 0;\n data.accelerationY = 0;\n\n data.velocityX = 0;\n data.velocityY = 0;\n\n data.textureConfig.textures = [];\n data.textureConfig.duration = 0;\n data.textureConfig.elapsed = 0;\n data.textureConfig.framerate = 0;\n data.textureConfig.loop = false;\n}\n\n/**\n * Default implementation of a particle used by the Emitter.\n * @template DataType Type describing the particle data structure. Any custom data structure must extend {@link BaseParticleData}.\n * Any custom data will also need to be manually reset, as the default particle will only reset the base data.\n * @group EmitterParticle\n */\nexport class EmitterParticle<\n DataType extends BaseParticleData = BaseParticleData,\n>\n extends Particle\n implements IEmitterParticle<DataType>\n{\n public data: DataType;\n\n /**\n * Creates a new EmitterParticle instance.\n * @param data Particle data used by emitter behaviors.\n */\n constructor(data: DataType) {\n super(Texture.EMPTY);\n\n this.data = data;\n this.onRecycle();\n }\n\n /**\n * @inheritdoc\n */\n public onFetch(): void {\n this.alpha = 1;\n }\n\n /**\n * @inheritdoc\n */\n public onRecycle(): void {\n this.anchorX = 0.5;\n this.anchorY = 0.5;\n\n this.alpha = 0;\n\n this.scaleX = 1;\n this.scaleY = 1;\n\n this.rotation = 0;\n\n resetBaseParticleData(this.data);\n }\n}\n","import { ParticleContainer, Ticker } from \"pixi.js\";\nimport pkg from \"../package.json\";\nimport { AlphaBehavior } from \"./behavior/built-in/AlphaBehavior\";\nimport { ColorBehavior } from \"./behavior/built-in/ColorBehavior\";\nimport { MovementBehavior } from \"./behavior/built-in/MovementBehavior\";\nimport { RotationBehavior } from \"./behavior/built-in/RotationBehavior\";\nimport { ScaleBehavior } from \"./behavior/built-in/ScaleBehavior\";\nimport { SpawnBehavior } from \"./behavior/built-in/SpawnBehavior\";\nimport { TextureBehavior } from \"./behavior/built-in/TextureBehavior\";\nimport { InitBehavior, UpdateBehavior } from \"./behavior/EmitterBehavior\";\nimport { Ease, EaseFunction, getEaseFunction } from \"./data/easing/Ease\";\nimport { EmitterConfig } from \"./EmitterConfig\";\nimport {\n BaseParticleData,\n createBaseParticleData,\n EmitterParticle,\n IEmitterParticle,\n} from \"./particle/EmitterParticle\";\n\n/**\n * Extra emitter options allowing for custom particles/particle data.\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Emitter/\n */\nexport type EmitterOptions<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> =\n IEmitterParticle<DataType>,\n> = {\n /**\n * Creates and returns object containing particle data. By default,\n * uses {@link BaseParticleData} object to store particle data.\n * @returns New particle data object.\n */\n dataFactory?: () => DataType;\n\n /**\n * Creates and returns new instance of a particle. By default,\n * uses {@link EmitterParticle} as the base particle class.\n * @param data Data used by the particle.\n * @returns New particle instance.\n */\n particleFactory?: (data: DataType) => ParticleType;\n\n /**\n * Initializes any custom data for the particles. By default,\n * does nothing, as there is no custom data.\n * @param data Data used by the particle.\n */\n customDataInitializer?: (data: DataType) => void;\n};\n\n/**\n * Class responsible for spawning and managing particles using various behaviors.\n *\n * Emitter is the core class of the particle system, handling particle creation, updating,\n * and recycling. It utilizes a set of behaviors to define how particles are initialized\n * and updated over their lifetime.\n * @example\n * ```ts\n * const emitter = new Emitter(particleContainer, {\n * emitterVersion: 0,\n * minParticleLifetime: 1,\n * maxParticleLifetime: 3,\n * spawnInterval: 0.1,\n * maxParticles: 500,\n * alphaBehavior: {\n * mode: \"list\",\n * list: [1, 0]\n * },\n * scaleBehavior: {\n * mode: \"random\",\n * xList: [0.5, 1],\n * yList: [0.5, 1]\n * }\n * });\n *\n * emitter.play();\n * ```\n * @template DataType Type describing the data object stored on particles.\n * @template ParticleType Type describing the particle used within the emitter.\n * @group Emitter\n */\nexport class Emitter<\n DataType extends BaseParticleData = BaseParticleData,\n ParticleType extends IEmitterParticle<DataType> = EmitterParticle<DataType>,\n> {\n private readonly _version: string = pkg.version;\n\n private readonly _dataFactory: () => DataType;\n private readonly _particleFactory: (data: DataType) => ParticleType;\n private readonly _customDataInitializer: (data: DataType) => void;\n\n private readonly _parent: ParticleContainer;\n\n private readonly _particles: ParticleType[] = [];\n private readonly _pooledParticles: ParticleType[] = [];\n\n // prettier-ignore\n private readonly _initBehaviors: InitBehavior<DataType, ParticleType>[] = [];\n // prettier-ignore\n private readonly _updateBehaviors: UpdateBehavior<DataType, ParticleType>[] = [];\n\n // prettier-ignore\n private readonly _alphaBehavior: AlphaBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _colorBehavior: ColorBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _movementBehavior: MovementBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _rotationBehavior: RotationBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _scaleBehavior: ScaleBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _spawnBehavior: SpawnBehavior<DataType, ParticleType>;\n // prettier-ignore\n private readonly _textureBehavior: TextureBehavior<DataType, ParticleType>;\n\n private _ease: Ease = \"linear\";\n private _easeFunction: EaseFunction | null = null;\n\n private _minLifetime: number = 1;\n private _maxLifetime: number = 3;\n\n private _spawnInterval: number = 0.01;\n private _spawnChance: number = 1.0;\n\n private _maxParticles: number = 500;\n private _addAtBack: boolean = true;\n\n private _particlesPerWave: number = 1;\n\n private _particleCount: number = 0;\n\n private _spawnTimer: number = 0;\n private _emitterLife: number = -1;\n\n private _onComplete: (() => void) | null = null;\n\n private _isActive: boolean = false;\n private _isEmitting: boolean = false;\n private _isPaused: boolean = false;\n\n /**\n * Creates a new Emitter.\n * @param parent Parent ParticleContainer to which particles will be added.\n * @param initialConfig Optional initial configuration for the emitter.\n * @param options Optional factories and initializers for custom particle data and particles.\n */\n constructor(\n parent: ParticleContainer,\n initialConfig?: EmitterConfig,\n options?: EmitterOptions<DataType, ParticleType>,\n ) {\n this._parent = parent;\n\n this._dataFactory =\n options?.dataFactory ??\n ((): DataType => createBaseParticleData() as DataType);\n\n this._particleFactory =\n options?.particleFactory ??\n ((data: DataType): ParticleType =>\n new EmitterParticle<DataType>(data) as ParticleType);\n\n this._customDataInitializer =\n options?.customDataInitializer ?? ((): void => undefined);\n\n this._alphaBehavior = new AlphaBehavior(this);\n this._colorBehavior = new ColorBehavior(this);\n this._movementBehavior = new MovementBehavior(this);\n this._rotationBehavior = new RotationBehavior(this);\n this._scaleBehavior = new ScaleBehavior(this);\n this._spawnBehavior = new SpawnBehavior(this);\n this._textureBehavior = new TextureBehavior(this);\n\n // ! These are always active.\n this._initBehaviors.push(this._spawnBehavior, this._textureBehavior);\n\n if (initialConfig != null) {\n this.applyConfig(initialConfig);\n }\n }\n\n //#region Getters and Setters\n /**\n * Current version of the emitter.\n */\n public get version(): string {\n return this._version;\n }\n\n /**\n * Parent ParticleContainer of the emitter.\n */\n public get parent(): ParticleContainer {\n return this._parent;\n }\n\n /**\n * Number of active particles in the emitter.\n */\n public get particleCount(): number {\n return this._particleCount;\n }\n\n /**\n * Whether the emitter is currently emitting new particles.\n */\n public get isEmitting(): boolean {\n return this._isEmitting;\n }\n\n /**\n * Whether the emitter is currently paused.\n */\n public get isPaused(): boolean {\n return this._isPaused;\n }\n\n /**\n * Minimum lifetime of particles in seconds.\n */\n public get minLifetime(): number {\n return this._minLifetime;\n }\n public set minLifetime(value: number) {\n this._minLifetime = value;\n }\n\n /**\n * Maximum lifetime of particles in seconds.\n */\n public get maxLifetime(): number {\n return this._maxLifetime;\n }\n public set maxLifetime(value: number) {\n this._maxLifetime = value;\n }\n\n /**\n * Interval between particle spawns in seconds.\n */\n public get spawnInterval(): number {\n return this._spawnInterval;\n }\n public set spawnInterval(value: number) {\n this._spawnInterval = value;\n }\n\n /**\n * Chance of spawning a particle (0.0 - 1.0).\n */\n public get spawnChance(): number {\n return this._spawnChance;\n }\n public set spawnChance(value: number) {\n this._spawnChance = value;\n }\n\n /**\n * Maximum number of particles allowed in the emitter.\n */\n public get maxParticles(): number {\n return this._maxParticles;\n }\n public set maxParticles(value: number) {\n this._maxParticles = value;\n }\n\n /**\n * Whether to add new particles at the back of the container.\n */\n public get addAtBack(): boolean {\n return this._addAtBack;\n }\n public set addAtBack(value: boolean) {\n this._addAtBack = value;\n }\n\n /**\n * Number of particles to spawn per wave.\n */\n public get particlesPerWave(): number {\n return this._particlesPerWave;\n }\n public set particlesPerWave(value: number) {\n this._particlesPerWave = value;\n }\n\n /**\n * Ease applied to particle lifetime.\n */\n public get ease(): Ease {\n return this._ease;\n }\n public set ease(value: Ease) {\n this._ease = value;\n this._easeFunction = getEaseFunction(this._ease);\n }\n\n /**\n * Alpha behavior of the emitter.\n */\n public get alphaBehavior(): AlphaBehavior<DataType, ParticleType> {\n return this._alphaBehavior;\n }\n\n /**\n * Color behavior of the emitter.\n */\n public get colorBehavior(): ColorBehavior<DataType, ParticleType> {\n return this._colorBehavior;\n }\n\n /**\n * Movement behavior of the emitter.\n */\n public get movementBehavior(): MovementBehavior<DataType, ParticleType> {\n return this._movementBehavior;\n }\n\n /**\n * Rotation behavior of the emitter.\n */\n public get rotationBehavior(): RotationBehavior<DataType, ParticleType> {\n return this._rotationBehavior;\n }\n\n /**\n * Scale behavior of the emitter.\n */\n public get scaleBehavior(): ScaleBehavior<DataType, ParticleType> {\n return this._scaleBehavior;\n }\n\n /**\n * Spawn behavior of the emitter.\n */\n public get spawnBehavior(): SpawnBehavior<DataType, ParticleType> {\n return this._spawnBehavior;\n }\n\n /**\n * Texture behavior of the emitter.\n */\n public get textureBehavior(): TextureBehavior<DataType, ParticleType> {\n return this._textureBehavior;\n }\n //#endregion\n\n /**\n * Applies a configuration to the emitter.\n * @param config Configuration to apply.\n */\n public applyConfig(config: EmitterConfig): void {\n this.checkCompatibility(config.emitterVersion);\n\n this._minLifetime = config.minParticleLifetime ?? 0.2;\n this._maxLifetime = config.maxParticleLifetime ?? 0.5;\n this._spawnInterval = config.spawnInterval ?? 0.1;\n this._spawnChance = config.spawnChance ?? 1;\n this._maxParticles = config.maxParticles ?? 500;\n this._addAtBack = config.addAtBack ?? true;\n this._particlesPerWave = config.particlesPerWave ?? 1;\n\n if (config.ease) {\n this._ease = config.ease;\n this._easeFunction = getEaseFunction(config.ease);\n } else {\n this._ease = \"linear\";\n this._easeFunction = null;\n }\n\n if (config.alphaBehavior) {\n this._alphaBehavior.applyConfig(config.alphaBehavior);\n }\n\n if (config.colorBehavior) {\n this._colorBehavior.applyConfig(config.colorBehavior);\n }\n\n if (config.movementBehavior) {\n this._movementBehavior.applyConfig(config.movementBehavior);\n }\n\n if (config.rotationBehavior) {\n this._rotationBehavior.applyConfig(config.rotationBehavior);\n }\n\n if (config.scaleBehavior) {\n this._scaleBehavior.applyConfig(config.scaleBehavior);\n }\n\n if (config.spawnBehavior) {\n this._spawnBehavior.applyConfig(config.spawnBehavior);\n }\n\n if (config.textureBehavior) {\n this._textureBehavior.applyConfig(config.textureBehavior);\n }\n }\n\n /**\n * Retrieves the current configuration for emitter and its behaviors.\n * @returns Current configuration object.\n */\n public getConfig(): EmitterConfig {\n return {\n emitterVersion: this._version,\n minParticleLifetime: this._minLifetime,\n maxParticleLifetime: this._maxLifetime,\n spawnInterval: this._spawnInterval,\n spawnChance: this._spawnChance,\n maxParticles: this._maxParticles,\n addAtBack: this._addAtBack,\n particlesPerWave: this._particlesPerWave,\n\n alphaBehavior: this._alphaBehavior.getConfig(),\n colorBehavior: this._colorBehavior.getConfig(),\n movementBehavior: this._movementBehavior.getConfig(),\n rotationBehavior: this._rotationBehavior.getConfig(),\n scaleBehavior: this._scaleBehavior.getConfig(),\n spawnBehavior: this._spawnBehavior.getConfig(),\n textureBehavior: this._textureBehavior.getConfig(),\n };\n }\n\n /**\n * Starts the emitter and hooks into the shared ticker.\n */\n public play(): void {\n this._isEmitting = true;\n\n if (!this._isActive) {\n this._isActive = true;\n Ticker.shared.add(this.update, this);\n }\n }\n\n /**\n * Pauses the emitter by unhooking from the shared ticker.\n */\n public pause(): void {\n if (!this._isActive || this._isPaused) return;\n\n this._isPaused = true;\n Ticker.shared.remove(this.update, this);\n }\n\n /**\n * Resumes the emitter by rehooking into the shared ticker.\n */\n public resume(): void {\n if (!this._isActive || !this._isPaused) return;\n\n this._isPaused = false;\n Ticker.shared.add(this.update, this);\n }\n\n /**\n * Stops new particles from spawning, and lets existing particles die naturally.\n * @param instant When true, particles are removed instantly.\n */\n public stop(instant: boolean = false): void {\n if (!this._isActive) return;\n\n this._isEmitting = false;\n\n if (instant) {\n // TODO: Move this to shared method since it's duplicated in update().\n Ticker.shared.remove(this.update, this);\n\n for (const particle of this._particles) {\n this.recycleParticle(particle);\n }\n\n this._particles.length = 0;\n this._particleCount = 0;\n\n this._onComplete?.();\n this._onComplete = null;\n\n this._isActive = false;\n\n return;\n }\n }\n\n /**\n * Prewarms the emitter by simulating particle spawning and updating for a given time.\n * @param time Time in seconds to prewarm the emitter.\n */\n public prewarm(time: number): void {\n if (this._isEmitting === true) {\n // eslint-disable-next-line no-console\n console.warn(\n \"Emitter: Cannot prewarm an emitter that is already playing!\",\n );\n return;\n }\n\n if (time <= 0) {\n // eslint-disable-next-line no-console\n console.warn(\"Emitter: Prewarm time must be greater than zero!\");\n return;\n }\n\n const spawnCycles = Math.floor(time / this._spawnInterval);\n const maxCycles = Math.min(spawnCycles, this._maxParticles);\n\n for (let cycle = 0; cycle < maxCycles; cycle++) {\n const particleAge = cycle * this._spawnInterval;\n\n if (particleAge > this._maxLifetime) continue;\n\n if (Math.random() > this._spawnChance) continue;\n\n const lifetime =\n this._minLifetime === this._maxLifetime\n ? this._maxLifetime\n : Math.random() * (this._maxLifetime - this._minLifetime);\n\n if (particleAge >= lifetime) continue;\n\n let particle: ParticleType;\n\n if (this._pooledParticles.length > 0) {\n particle = this._pooledParticles.pop()!;\n particle.onFetch();\n } else {\n const particleData = this._dataFactory();\n particle = this._particleFactory(particleData);\n }\n\n this._customDataInitializer(particle.data);\n\n const particleData = particle.data;\n particleData.maxLifetime = lifetime;\n particleData.oneOverLifetime = 1 / lifetime;\n particleData.age = particleAge;\n particleData.agePercent = particleAge / lifetime;\n\n for (const behavior of this._initBehaviors) {\n behavior.init(particle);\n }\n\n for (const behavior of this._updateBehaviors) {\n behavior.update(particle, particleAge);\n }\n\n if (this._addAtBack) {\n this._parent.addParticle(particle);\n } else {\n this._parent.addParticleAt(particle, 0);\n }\n\n this._particles.push(particle);\n ++this._particleCount;\n\n if (this._particleCount >= this._maxParticles) break;\n }\n\n this.play();\n }\n\n /**\n * Checks if a behavior is currently active in the emitter's init behaviors.\n * @param behavior Behavior to check.\n * @returns Whether the behavior is active.\n */\n public isBehaviorInitActive(\n behavior: InitBehavior<DataType, ParticleType>,\n ): boolean {\n return this._initBehaviors.indexOf(behavior) !== -1;\n }\n\n /**\n * Checks if a behavior is currently active in the emitter's update behaviors.\n * @param behavior Behavior to check.\n * @returns Whether the behavior is active.\n */\n public isBehaviorUpdateActive(\n behavior: UpdateBehavior<DataType, ParticleType>,\n ): boolean {\n return this._updateBehaviors.indexOf(behavior) !== -1;\n }\n\n /**\n * Adds a behavior to the active init behaviors.\n * @param behavior Behavior to add.\n */\n public addToActiveInitBehaviors(\n behavior: InitBehavior<DataType, ParticleType>,\n ): void {\n this._initBehaviors.push(behavior);\n\n this._initBehaviors.sort((a, b) => {\n const orderA = a.updateOrder;\n const orderB = b.updateOrder;\n\n if (orderA === orderB) return 0;\n if (orderA === \"initial\") return -1;\n if (orderB === \"initial\") return 1;\n if (orderA === \"normal\" && orderB === \"late\") return -1;\n if (orderA === \"late\" && orderB === \"normal\") return 1;\n\n return 0;\n });\n }\n\n /**\n * Adds a behavior to the active update behaviors.\n * @param behavior Behavior to add.\n */\n public addToActiveUpdateBehaviors(\n behavior: UpdateBehavior<DataType, ParticleType>,\n ): void {\n this._updateBehaviors.push(behavior);\n\n this._updateBehaviors.sort((a, b) => {\n const orderA = a.updateOrder;\n const orderB = b.updateOrder;\n\n if (orderA === orderB) return 0;\n if (orderA === \"initial\") return -1;\n if (orderB === \"initial\") return 1;\n if (orderA === \"normal\" && orderB === \"late\") return -1;\n if (orderA === \"late\" && orderB === \"normal\") return 1;\n\n return 0;\n });\n }\n\n /**\n * Removes a behavior from the active init behaviors.\n * @param behavior Behavior to remove.\n */\n public removeFromActiveInitBehaviors(\n behavior: InitBehavior<DataType, ParticleType>,\n ): void {\n const index = this._initBehaviors.indexOf(behavior);\n\n if (index !== -1) {\n this._initBehaviors.splice(index, 1);\n }\n }\n\n /**\n * Removes a behavior from the active update behaviors.\n * @param behavior Behavior to remove.\n */\n public removeFromActiveUpdateBehaviors(\n behavior: UpdateBehavior<DataType, ParticleType>,\n ): void {\n const index = this._updateBehaviors.indexOf(behavior);\n\n if (index !== -1) {\n this._updateBehaviors.splice(index, 1);\n }\n }\n\n /**\n * Updates the emitter.\n * @param ticker Ticker instance.\n */\n private update(ticker: Ticker): void {\n const deltaTime = ticker.elapsedMS * 0.001;\n\n for (let i = this._particles.length - 1; i >= 0; i--) {\n const particle = this._particles[i];\n const particleData = particle.data;\n\n particleData.age += deltaTime;\n particleData.agePercent =\n particleData.age / particleData.maxLifetime;\n\n if (\n particleData.age > particleData.maxLifetime ||\n particleData.age < 0\n ) {\n this._particles[i] =\n this._particles[this._particles.length - 1];\n this._particles.pop();\n this._particleCount--;\n\n this.recycleParticle(particle);\n } else {\n let lerp = particle.data.age * particle.data.oneOverLifetime;\n\n if (this._easeFunction) {\n lerp = this._easeFunction(lerp);\n }\n\n particle.data.agePercent = lerp;\n\n for (const behavior of this._updateBehaviors) {\n behavior.update(particle, deltaTime);\n }\n }\n }\n\n if (this._isEmitting) {\n this._spawnTimer -= deltaTime < 0 ? 0 : deltaTime;\n\n while (this._spawnTimer <= 0) {\n if (this._emitterLife >= 0) {\n this._emitterLife -= this._spawnInterval;\n\n if (this._emitterLife <= 0) {\n this._spawnTimer = 0;\n this._emitterLife = 0;\n this._isEmitting = false;\n\n break;\n }\n }\n\n // Particles are maxed out, continue to next frame.\n if (this._particleCount >= this._maxParticles) {\n this._spawnTimer += this._spawnInterval;\n continue;\n }\n\n const newParticles: ParticleType[] = [];\n\n for (let i = 0; i < this._particlesPerWave; i++) {\n if (Math.random() > this._spawnChance) continue;\n\n let lifetime;\n\n if (this._minLifetime === this._maxLifetime) {\n lifetime = this._maxLifetime;\n } else {\n lifetime =\n Math.random() *\n (this._maxLifetime - this._minLifetime) +\n this._minLifetime;\n }\n\n // Skip spawning if particle was to die instantly.\n if (-this._spawnTimer >= lifetime) {\n continue;\n }\n\n let particle: ParticleType;\n\n if (this._pooledParticles.length > 0) {\n particle = this._pooledParticles.pop()!;\n particle.onFetch();\n } else {\n const particleData = this._dataFactory();\n particle = this._particleFactory(particleData);\n }\n\n this._customDataInitializer(particle.data);\n\n const particleData = particle.data;\n particleData.maxLifetime = lifetime;\n particleData.oneOverLifetime = 1 / lifetime;\n\n let lerp =\n particle.data.age * particle.data.oneOverLifetime;\n\n if (this._easeFunction) {\n lerp = this._easeFunction(lerp);\n }\n\n if (this._addAtBack) {\n this._parent.addParticleAt(particle, 0);\n } else {\n this._parent.addParticle(particle);\n }\n\n newParticles.push(particle);\n ++this._particleCount;\n }\n\n for (const particle of newParticles) {\n for (const behavior of this._initBehaviors) {\n behavior.init(particle);\n }\n\n for (const behavior of this._updateBehaviors) {\n behavior.update(particle, -this._spawnTimer);\n }\n }\n\n this._particles.push(...newParticles);\n this._spawnTimer += this._spawnInterval;\n }\n }\n\n this._parent.update();\n\n if (!this._isEmitting && this._particleCount === 0) {\n this._onComplete?.();\n this._onComplete = null;\n\n Ticker.shared.remove(this.update, this);\n\n this._isPaused = false;\n this._isActive = false;\n }\n }\n\n /**\n * Recycles a particle back into the pool.\n * @param particle Particle to recycle.\n */\n private recycleParticle(particle: ParticleType): void {\n this._parent.removeParticle(particle);\n\n particle.onRecycle();\n\n this._pooledParticles.push(particle);\n }\n\n /**\n * Parses a version string into major/minor/patch components.\n * @param version Version string to parse.\n * @returns Parsed version components.\n */\n private parseVersionString(version: string): {\n major: number;\n minor: number;\n patch: number;\n } {\n const parts = version.split(\".\").map((part) => parseInt(part, 10));\n\n return {\n major: parts[0] || 0,\n minor: parts[1] || 0,\n patch: parts[2] || 0,\n };\n }\n\n /**\n * Checks compatibility between the emitter version and config version.\n * @param configVersion Config version to check.\n */\n private checkCompatibility(configVersion: string): void {\n if (this._version === \"dev\") return;\n\n const current = this.parseVersionString(this._version);\n const config = this.parseVersionString(configVersion);\n\n if (current.major !== config.major) {\n // eslint-disable-next-line no-console\n console.error(\n `Emitter config major version (${config.major}) does not match emitter major version (${current.major}).`,\n \"This will most likely result in unexpected behavior, or outright failure.\",\n );\n\n return;\n }\n\n if (current.minor !== config.minor) {\n // eslint-disable-next-line no-console\n console.warn(\n `Emitter config minor version (${config.minor}) does not match emitter minor version (${current.minor}).`,\n \"This may result in unexpected behavior.\",\n );\n }\n\n // Patch version differences are ignored, as they should only contain bug fixes.\n // ? If needed, a log can be added here for patch version differences.\n }\n}\n"],"names":["EmitterError","message","k","k2","backIn","v","backOut","m","backInOut","t","bounceCoefficient","bounceDivisor","threshold1","threshold2","threshold3","offset1","offset2","offset3","bounceIn","bounceOut","bounceInOut","circleIn","circleOut","circleInOut","elasticC","elasticIn","elasticOut","elasticInOut","s","power2In","power2Out","power2InOut","power3In","power3Out","power3InOut","power4In","power4Out","power4InOut","power5In","power5Out","power5InOut","sineIn","sineOut","sineInOut","easeToFunctionMap","getEaseFunction","ease","defaultInterpolateFunction","List","value","data","simpleValue","lerp","complexValue","current","next","denom","steppedValue","NumberList","node","first","datum","newNode","EmitterBehavior","emitter","config","AlphaBehavior","particle","convertRgbToUint","r","g","b","convertHexToRGB","color","output","alpha","convertUintToHex","convertHexToUint","rgb","simpleColor","curVal","nextVal","complexColor","steppedColor","currentValue","ColorList","ColorBehavior","MovementBehavior","particleData","xVelocity","yVelocity","dirX","dirY","length","forwardX","forwardY","perpX","perpY","finalX","finalY","deltaTime","xAcceleration","yAcceleration","xValue","yValue","RotationBehavior","ScaleBehavior","xScale","yScale","SpawnBehavior","x","y","theta","radius","TextureBehavior","Texture","texture","frameIndex","createBaseParticleData","resetBaseParticleData","EmitterParticle","Particle","Emitter","parent","initialConfig","options","pkg","Ticker","instant","_a","time","spawnCycles","maxCycles","cycle","particleAge","lifetime","behavior","a","orderA","orderB","index","ticker","i","newParticles","version","parts","part","configVersion"],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Particle, Texture } from 'pixi.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base data structure for emitter particles.
|
|
4
|
+
* @group EmitterParticle/
|
|
5
|
+
*/
|
|
6
|
+
export type BaseParticleData = {
|
|
7
|
+
/**
|
|
8
|
+
* Maximum lifetime of the particle in milliseconds.
|
|
9
|
+
*/
|
|
10
|
+
maxLifetime: number;
|
|
11
|
+
/**
|
|
12
|
+
* Current age of the particle in milliseconds.
|
|
13
|
+
*/
|
|
14
|
+
age: number;
|
|
15
|
+
/**
|
|
16
|
+
* Age percent of the particle's lifetime (0.0 to 1.0).
|
|
17
|
+
*/
|
|
18
|
+
agePercent: number;
|
|
19
|
+
/**
|
|
20
|
+
* One over the lifetime of the particle (1.0 / maxLifetime).
|
|
21
|
+
*/
|
|
22
|
+
oneOverLifetime: number;
|
|
23
|
+
/**
|
|
24
|
+
* Direction vector components of the particle.
|
|
25
|
+
*/
|
|
26
|
+
directionVectorX: number;
|
|
27
|
+
/**
|
|
28
|
+
* Direction vector Y component of the particle.
|
|
29
|
+
*/
|
|
30
|
+
directionVectorY: number;
|
|
31
|
+
/**
|
|
32
|
+
* Acceleration components of the particle.
|
|
33
|
+
*/
|
|
34
|
+
accelerationX: number;
|
|
35
|
+
/**
|
|
36
|
+
* Acceleration Y component of the particle.
|
|
37
|
+
*/
|
|
38
|
+
accelerationY: number;
|
|
39
|
+
/**
|
|
40
|
+
* Velocity components of the particle.
|
|
41
|
+
*/
|
|
42
|
+
velocityX: number;
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
velocityY: number;
|
|
47
|
+
/**
|
|
48
|
+
* Texture animation configuration for the particle.
|
|
49
|
+
*/
|
|
50
|
+
textureConfig: {
|
|
51
|
+
/**
|
|
52
|
+
* Array of textures used for the particle.
|
|
53
|
+
*/
|
|
54
|
+
textures: Texture[];
|
|
55
|
+
/**
|
|
56
|
+
* Duration of the texture animation in milliseconds.
|
|
57
|
+
*/
|
|
58
|
+
duration: number;
|
|
59
|
+
/**
|
|
60
|
+
* Elapsed time of the texture animation in milliseconds.
|
|
61
|
+
*/
|
|
62
|
+
elapsed: number;
|
|
63
|
+
/**
|
|
64
|
+
* Frame rate of the texture animation (frames per second).
|
|
65
|
+
*/
|
|
66
|
+
framerate: number;
|
|
67
|
+
/**
|
|
68
|
+
* Whether the texture animation should loop.
|
|
69
|
+
*/
|
|
70
|
+
loop: boolean;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Base interface for particles used by the Emitter.
|
|
75
|
+
* @template DataType Type describing the data object stored on particles.
|
|
76
|
+
* @group EmitterParticle/
|
|
77
|
+
*/
|
|
78
|
+
export interface IEmitterParticle<DataType extends BaseParticleData = BaseParticleData> extends Particle {
|
|
79
|
+
/**
|
|
80
|
+
* Particle data used by emitter behaviors.
|
|
81
|
+
* @see {@link BaseParticleData} for the structure of the data.
|
|
82
|
+
*/
|
|
83
|
+
data: DataType;
|
|
84
|
+
/**
|
|
85
|
+
* Invoked when particle is fetched from pool.
|
|
86
|
+
*/
|
|
87
|
+
onFetch(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Invoked when particle is returned to pool.
|
|
90
|
+
*/
|
|
91
|
+
onRecycle(): void;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a new instance of BaseParticleData with default values.
|
|
95
|
+
* @returns A new BaseParticleData object with default values.
|
|
96
|
+
* @group EmitterParticle/
|
|
97
|
+
*/
|
|
98
|
+
export declare function createBaseParticleData(): BaseParticleData;
|
|
99
|
+
/**
|
|
100
|
+
* Resets the base particle data.
|
|
101
|
+
* @param data Data to reset.
|
|
102
|
+
* @group EmitterParticle/
|
|
103
|
+
*/
|
|
104
|
+
export declare function resetBaseParticleData(data: BaseParticleData): void;
|
|
105
|
+
/**
|
|
106
|
+
* Default implementation of a particle used by the Emitter.
|
|
107
|
+
* @template DataType Type describing the particle data structure. Any custom data structure must extend {@link BaseParticleData}.
|
|
108
|
+
* Any custom data will also need to be manually reset, as the default particle will only reset the base data.
|
|
109
|
+
* @group EmitterParticle
|
|
110
|
+
*/
|
|
111
|
+
export declare class EmitterParticle<DataType extends BaseParticleData = BaseParticleData> extends Particle implements IEmitterParticle<DataType> {
|
|
112
|
+
data: DataType;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a new EmitterParticle instance.
|
|
115
|
+
* @param data Particle data used by emitter behaviors.
|
|
116
|
+
*/
|
|
117
|
+
constructor(data: DataType);
|
|
118
|
+
/**
|
|
119
|
+
* @inheritdoc
|
|
120
|
+
*/
|
|
121
|
+
onFetch(): void;
|
|
122
|
+
/**
|
|
123
|
+
* @inheritdoc
|
|
124
|
+
*/
|
|
125
|
+
onRecycle(): void;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=EmitterParticle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmitterParticle.d.ts","sourceRoot":"","sources":["../../src/particle/EmitterParticle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,aAAa,EAAE;QACX;;WAEG;QACH,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB;;WAEG;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB;;WAEG;QACH,OAAO,EAAE,MAAM,CAAC;QAChB;;WAEG;QACH,SAAS,EAAE,MAAM,CAAC;QAClB;;WAEG;QACH,IAAI,EAAE,OAAO,CAAC;KACjB,CAAC;CACL,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB,CAC7B,QAAQ,SAAS,gBAAgB,GAAG,gBAAgB,CACtD,SAAQ,QAAQ;IACd;;;OAGG;IACH,IAAI,EAAE,QAAQ,CAAC;IAEf;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;IAEhB;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAoBzD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAoBlE;AAED;;;;;GAKG;AACH,qBAAa,eAAe,CACxB,QAAQ,SAAS,gBAAgB,GAAG,gBAAgB,CAEpD,SAAQ,QACR,YAAW,gBAAgB,CAAC,QAAQ,CAAC;IAE9B,IAAI,EAAE,QAAQ,CAAC;IAEtB;;;OAGG;gBACS,IAAI,EAAE,QAAQ;IAO1B;;OAEG;IACI,OAAO,IAAI,IAAI;IAItB;;OAEG;IACI,SAAS,IAAI,IAAI;CAa3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/particle/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RGBAColor } from './Types';
|
|
2
|
+
/**
|
|
3
|
+
* Combines separate color components (0-255) into a single uint color.
|
|
4
|
+
* @param r The red value of the color
|
|
5
|
+
* @param g The green value of the color
|
|
6
|
+
* @param b The blue value of the color
|
|
7
|
+
* @returns The color in the form of `0xRRGGBB`
|
|
8
|
+
*/
|
|
9
|
+
export declare function convertRgbToUint(r: number, g: number, b: number): number;
|
|
10
|
+
/**
|
|
11
|
+
* Converts a hex string from "#AARRGGBB", "#RRGGBB", "0xAARRGGBB", "0xRRGGBB",
|
|
12
|
+
* "AARRGGBB", or "RRGGBB" to an object of ints of 0-255, as
|
|
13
|
+
* {r, g, b, (a)}.
|
|
14
|
+
* @param color The input color string.
|
|
15
|
+
* @param output An object to put the output in. If omitted, a new object is created.
|
|
16
|
+
* @returns The object with r, g, and b properties, possibly with an a property.
|
|
17
|
+
*/
|
|
18
|
+
export declare function convertHexToRGB(color: string, output?: RGBAColor): RGBAColor;
|
|
19
|
+
/**
|
|
20
|
+
* Converts a uint color (0xRRGGBB) to a hex string ("#RRGGBB").
|
|
21
|
+
* @param color The color in the form of `0xRRGGBB`
|
|
22
|
+
* @returns The color as a hex string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function convertUintToHex(color: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Converts a hex string ("#RRGGBB") to a uint color (0xRRGGBB).
|
|
27
|
+
* @param color The color as a hex string.
|
|
28
|
+
* @returns The color in the form of `0xRRGGBB`
|
|
29
|
+
*/
|
|
30
|
+
export declare function convertHexToUint(color: string): number;
|
|
31
|
+
//# sourceMappingURL=ColorUtil.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorUtil.d.ts","sourceRoot":"","sources":["../../src/util/ColorUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CA2B5E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD"}
|