@tsparticles/plugin-emitters 4.0.0-alpha.2 → 4.0.0-alpha.4

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.
Files changed (73) hide show
  1. package/129.min.js +2 -0
  2. package/129.min.js.LICENSE.txt +1 -0
  3. package/246.min.js +2 -0
  4. package/246.min.js.LICENSE.txt +1 -0
  5. package/330.min.js +2 -0
  6. package/330.min.js.LICENSE.txt +1 -0
  7. package/{921.min.js → 490.min.js} +2 -2
  8. package/490.min.js.LICENSE.txt +1 -0
  9. package/849.min.js +2 -0
  10. package/849.min.js.LICENSE.txt +1 -0
  11. package/940.min.js +2 -0
  12. package/940.min.js.LICENSE.txt +1 -0
  13. package/browser/EmitterInstance.js +10 -14
  14. package/browser/EmittersInstancesManager.js +69 -0
  15. package/browser/EmittersInteractor.js +112 -0
  16. package/browser/EmittersPlugin.js +8 -55
  17. package/browser/EmittersPluginInstance.js +42 -0
  18. package/browser/ShapeManager.js +4 -4
  19. package/browser/constants.js +4 -0
  20. package/browser/index.js +8 -4
  21. package/cjs/EmitterInstance.js +10 -14
  22. package/cjs/EmittersInstancesManager.js +69 -0
  23. package/cjs/EmittersInteractor.js +112 -0
  24. package/cjs/EmittersPlugin.js +8 -55
  25. package/cjs/EmittersPluginInstance.js +42 -0
  26. package/cjs/ShapeManager.js +4 -4
  27. package/cjs/constants.js +4 -0
  28. package/cjs/index.js +8 -4
  29. package/dist_browser_EmitterInstance_js.js +30 -0
  30. package/dist_browser_EmittersInstancesManager_js.js +90 -0
  31. package/dist_browser_EmittersInteractor_js.js +100 -0
  32. package/dist_browser_EmittersPluginInstance_js.js +30 -0
  33. package/dist_browser_EmittersPlugin_js.js +2 -22
  34. package/dist_browser_ShapeManager_js.js +2 -2
  35. package/esm/EmitterInstance.js +10 -14
  36. package/esm/EmittersInstancesManager.js +69 -0
  37. package/esm/EmittersInteractor.js +112 -0
  38. package/esm/EmittersPlugin.js +8 -55
  39. package/esm/EmittersPluginInstance.js +42 -0
  40. package/esm/ShapeManager.js +4 -4
  41. package/esm/constants.js +4 -0
  42. package/esm/index.js +8 -4
  43. package/package.json +3 -2
  44. package/report.html +1 -1
  45. package/tsparticles.plugin.emitters.js +48 -20
  46. package/tsparticles.plugin.emitters.min.js +1 -1
  47. package/tsparticles.plugin.emitters.min.js.LICENSE.txt +1 -1
  48. package/types/EmitterContainer.d.ts +8 -7
  49. package/types/EmitterInstance.d.ts +2 -3
  50. package/types/EmittersEngine.d.ts +2 -2
  51. package/types/EmittersInstancesManager.d.ts +15 -0
  52. package/types/EmittersInteractor.d.ts +18 -0
  53. package/types/EmittersPlugin.d.ts +6 -7
  54. package/types/EmittersPluginInstance.d.ts +14 -0
  55. package/types/constants.d.ts +2 -0
  56. package/types/index.d.ts +2 -2
  57. package/types/types.d.ts +15 -9
  58. package/umd/EmitterInstance.js +10 -14
  59. package/umd/EmittersInstancesManager.js +117 -0
  60. package/umd/EmittersInteractor.js +126 -0
  61. package/umd/EmittersPlugin.js +42 -55
  62. package/umd/EmittersPluginInstance.js +56 -0
  63. package/umd/ShapeManager.js +4 -4
  64. package/umd/constants.js +17 -0
  65. package/umd/index.js +8 -4
  66. package/214.min.js +0 -2
  67. package/214.min.js.LICENSE.txt +0 -1
  68. package/921.min.js.LICENSE.txt +0 -1
  69. package/browser/Emitters.js +0 -128
  70. package/cjs/Emitters.js +0 -128
  71. package/esm/Emitters.js +0 -128
  72. package/types/Emitters.d.ts +0 -24
  73. package/umd/Emitters.js +0 -142
package/129.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 129.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[129],{510(t,i,e){e.d(i,{EmitterInstance:()=>r});var s=e(303),o=e(21),n=e(129);function a(t,i){t.color?t.color.value=i:t.color={value:i}}class r{constructor(t,i,e,n,a){this.container=i,this.removeCallback=e,this._destroy=()=>{this._mutationObserver?.disconnect(),this._mutationObserver=void 0,this._resizeObserver?.disconnect(),this._resizeObserver=void 0,this.removeCallback(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._prepareToDie=()=>{if(this._paused)return;const t=void 0!==this.options.life.duration?(0,s.getRangeValue)(this.options.life.duration):void 0;(this._lifeCount>0||this._immortal)&&void 0!==t&&t>0&&(this._duration=t*s.millisecondsToSeconds)},this._setColorAnimation=(t,i,e,o=1)=>{const n=this.container;if(!t.enable)return i;const a=(0,s.randomInRangeValue)(t.offset),r=(0,s.getRangeValue)(this.options.rate.delay),h=n.retina.reduceFactor?r*s.millisecondsToSeconds/n.retina.reduceFactor:1/0;return(i+(0,s.getRangeValue)(t.speed)*n.fpsLimit/h+a*o)%e},this._engine=t,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=a,n instanceof o.v?this.options=n:(this.options=new o.v,this.options.load(n)),this._spawnDelay=i.retina.reduceFactor?(0,s.getRangeValue)(this.options.life.delay??0)*s.millisecondsToSeconds/i.retina.reduceFactor:1/0,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;const r=(0,s.deepExtend)({},this.options.particles);if(r.move??={},r.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=(0,s.rangeColorToHsl)(this._engine,this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=r,this._size=this._calcSize(),this.size=(0,s.getSize)(this._size,this.container.canvas.size),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this.options.domId){const t=(0,s.safeDocument)().getElementById(this.options.domId);t&&(this._mutationObserver=new MutationObserver((()=>{this.resize()})),this._resizeObserver=new ResizeObserver((()=>{this.resize()})),this._mutationObserver.observe(t,{attributes:!0,attributeFilter:["style","width","height"]}),this._resizeObserver.observe(t))}const h=this.options.shape,l=this._engine.emitterShapeManager?.getShapeGenerator(h.type);l&&(this._shape=l.generate(this.position,this.size,this.fill,h.options)),this._engine.dispatchEvent("emitterCreated",{container:i,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}async init(){await(this._shape?.init())}pause(){this._paused||delete this._emitDelay}play(){if(this._paused)return;if(!(this._lifeCount>0||this._immortal)&&this.options.life.count||!(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0)))return;const t=this.container;if(void 0===this._emitDelay){const i=(0,s.getRangeValue)(this.options.rate.delay);this._emitDelay=t.retina.reduceFactor?i*s.millisecondsToSeconds/t.retina.reduceFactor:1/0}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}resize(){const t=this._initialPosition,i=this.container;this.position=t&&(0,s.isPointInside)(t,i.canvas.size,s.Vector.origin)?t:this._calcPosition(),this._size=this._calcSize(),this.size=(0,s.getSize)(this._size,i.canvas.size),this._shape?.resize(this.position,this.size)}update(t){if(this._paused)return;const i=this.container;this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=t.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._shape?.resize(this.position,this.size),this._spawnDelay=i.retina.reduceFactor?(0,s.getRangeValue)(this.options.life.delay??0)*s.millisecondsToSeconds/i.retina.reduceFactor:1/0):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=t.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=t.value,this._currentEmitDelay>=this._emitDelay&&(this._emit(),this._currentEmitDelay-=this._emitDelay))}_calcPosition(){const t=this.container;if(this.options.domId){const i=(0,s.safeDocument)().getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect(),o=t.retina.pixelRatio;return{x:(e.x+e.width*s.half)*o,y:(e.y+e.height*s.half)*o}}}return(0,s.calcPositionOrRandomFromSizeRanged)({size:t.canvas.size,position:this.options.position})}_calcSize(){const t=this.container;if(this.options.domId){const i=(0,s.safeDocument)().getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{width:e.width*t.retina.pixelRatio,height:e.height*t.retina.pixelRatio,mode:s.PixelMode.precise}}}return this.options.size??(()=>{const t=new n.G;return t.load({height:0,mode:s.PixelMode.percent,width:0}),t})()}_emit(){if(this._paused)return;const t=(0,s.getRangeValue)(this.options.rate.quantity);this._emitParticles(t)}_emitParticles(t){const i=(0,s.itemFromSingleOrMultiple)(this._particlesOptions)??{},e=this.options.spawnColor?.animation,o=this.container.retina.reduceFactor,n=!!e,r=!!this._shape,h=n||r,l=n?{h:s.hMax,s:s.sMax,l:s.lMax}:null,c=this.options.shape;for(let n=0;n<t*o;n++){const t=h?(0,s.deepExtend)({},i):i;this.spawnColor&&(e&&l&&(this.spawnColor.h=this._setColorAnimation(e.h,this.spawnColor.h,l.h,3.6),this.spawnColor.s=this._setColorAnimation(e.s,this.spawnColor.s,l.s),this.spawnColor.l=this._setColorAnimation(e.l,this.spawnColor.l,l.l)),a(t,this.spawnColor));let o=this.position;if(this._shape){const i=this._shape.randomPosition();if(i){o=i.position;const e=c.replace;e.color&&i.color&&a(t,i.color),e.opacity&&(t.opacity?t.opacity.value=i.opacity:t.opacity={value:i.opacity})}else o=null}o&&this.container.particles.addParticle(o,t)}}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
package/246.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 246.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[246],{21(t,i,e){e.d(i,{v:()=>h});var s=e(303);class o{constructor(){this.wait=!1}load(t){(0,s.isNull)(t)||(void 0!==t.count&&(this.count=t.count),void 0!==t.delay&&(this.delay=(0,s.setRangeValue)(t.delay)),void 0!==t.duration&&(this.duration=(0,s.setRangeValue)(t.duration)),void 0!==t.wait&&(this.wait=t.wait))}}class a{constructor(){this.quantity=1,this.delay=.1}load(t){(0,s.isNull)(t)||(void 0!==t.quantity&&(this.quantity=(0,s.setRangeValue)(t.quantity)),void 0!==t.delay&&(this.delay=(0,s.setRangeValue)(t.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){(0,s.isNull)(t)||(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class r{constructor(){this.options={},this.replace=new n,this.type="square"}load(t){(0,s.isNull)(t)||(void 0!==t.options&&(this.options=(0,s.deepExtend)({},t.options??{})),this.replace.load(t.replace),void 0!==t.type&&(this.type=t.type))}}var l=e(129);class h{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new o,this.rate=new a,this.shape=new r,this.startCount=0}load(t){(0,s.isNull)(t)||(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.size&&(this.size??=new l.G,this.size.load(t.size)),void 0!==t.direction&&(this.direction=t.direction),this.domId=t.domId,void 0!==t.fill&&(this.fill=t.fill),this.life.load(t.life),this.name=t.name,this.particles=(0,s.executeOnSingleOrMultiple)(t.particles,(t=>(0,s.deepExtend)({},t))),this.rate.load(t.rate),this.shape.load(t.shape),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=(0,s.setRangeValue)(t.position.x)),void 0!==t.position.y&&(this.position.y=(0,s.setRangeValue)(t.position.y))),void 0!==t.spawnColor&&(this.spawnColor??=new s.AnimatableColor,this.spawnColor.load(t.spawnColor)),void 0!==t.startCount&&(this.startCount=t.startCount))}}},129(t,i,e){e.d(i,{G:()=>o});var s=e(303);class o{constructor(){this.mode=s.PixelMode.percent,this.height=0,this.width=0}load(t){(0,s.isNull)(t)||(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}},246(t,i,e){e.d(i,{EmittersInstancesManager:()=>a});var s=e(303),o=e(21);class a{constructor(t){this._containerArrays=new Map,this._engine=t}async addEmitter(t,i,s){const a=new o.v;a.load(i);const{EmitterInstance:n}=await e.e(129).then(e.bind(e,510)),r=new n(this._engine,t,(i=>{this.removeEmitter(t,i)}),a,s);return await r.init(),this.getArray(t).push(r),r}clear(t){this.initContainer(t),this._containerArrays.set(t,[])}getArray(t){this.initContainer(t);let i=this._containerArrays.get(t);return i||(i=[],this._containerArrays.set(t,i)),i}initContainer(t){this._containerArrays.has(t)||(this._containerArrays.set(t,[]),t.getEmitter=i=>{const e=this.getArray(t);return void 0===i||(0,s.isNumber)(i)?e[i??0]:e.find((t=>t.name===i))},t.addEmitter=async(i,e)=>this.addEmitter(t,i,e),t.removeEmitter=i=>{const e=t.getEmitter?.(i);e&&this.removeEmitter(t,e)},t.playEmitter=i=>{const e=t.getEmitter?.(i);e&&e.externalPlay()},t.pauseEmitter=i=>{const e=t.getEmitter?.(i);e&&e.externalPause()})}removeEmitter(t,i){const e=this.getArray(t).indexOf(i);e>=0&&this.getArray(t).splice(e,1)}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
package/330.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 330.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[330],{21(t,i,s){s.d(i,{v:()=>h});var e=s(303);class o{constructor(){this.wait=!1}load(t){(0,e.isNull)(t)||(void 0!==t.count&&(this.count=t.count),void 0!==t.delay&&(this.delay=(0,e.setRangeValue)(t.delay)),void 0!==t.duration&&(this.duration=(0,e.setRangeValue)(t.duration)),void 0!==t.wait&&(this.wait=t.wait))}}class a{constructor(){this.quantity=1,this.delay=.1}load(t){(0,e.isNull)(t)||(void 0!==t.quantity&&(this.quantity=(0,e.setRangeValue)(t.quantity)),void 0!==t.delay&&(this.delay=(0,e.setRangeValue)(t.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){(0,e.isNull)(t)||(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class l{constructor(){this.options={},this.replace=new n,this.type="square"}load(t){(0,e.isNull)(t)||(void 0!==t.options&&(this.options=(0,e.deepExtend)({},t.options??{})),this.replace.load(t.replace),void 0!==t.type&&(this.type=t.type))}}var d=s(129);class h{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new o,this.rate=new a,this.shape=new l,this.startCount=0}load(t){(0,e.isNull)(t)||(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.size&&(this.size??=new d.G,this.size.load(t.size)),void 0!==t.direction&&(this.direction=t.direction),this.domId=t.domId,void 0!==t.fill&&(this.fill=t.fill),this.life.load(t.life),this.name=t.name,this.particles=(0,e.executeOnSingleOrMultiple)(t.particles,(t=>(0,e.deepExtend)({},t))),this.rate.load(t.rate),this.shape.load(t.shape),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=(0,e.setRangeValue)(t.position.x)),void 0!==t.position.y&&(this.position.y=(0,e.setRangeValue)(t.position.y))),void 0!==t.spawnColor&&(this.spawnColor??=new e.AnimatableColor,this.spawnColor.load(t.spawnColor)),void 0!==t.startCount&&(this.startCount=t.startCount))}}},129(t,i,s){s.d(i,{G:()=>o});var e=s(303);class o{constructor(){this.mode=e.PixelMode.percent,this.height=0,this.width=0}load(t){(0,e.isNull)(t)||(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}},330(t,i,s){s.d(i,{EmittersPlugin:()=>a});var e=s(303),o=s(21);class a{constructor(t){this._instancesManager=t,this.id="emitters"}async getPlugin(t){const{EmittersPluginInstance:i}=await s.e(849).then(s.bind(s,849));return new i(this._instancesManager,t)}loadOptions(t,i,s){(this.needsPlugin(i)||this.needsPlugin(s))&&s?.emitters&&(i.emitters=(0,e.executeOnSingleOrMultiple)(s.emitters,(t=>{const i=new o.v;return i.load(t),i})))}needsPlugin(t){if(!t)return!1;const i=t.emitters;return(0,e.isArray)(i)&&!!i.length||void 0!==i}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
@@ -1,2 +1,2 @@
1
- /*! For license information please see 921.min.js.LICENSE.txt */
2
- (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[921],{921(e,t,a){a.d(t,{ShapeManager:()=>s});const r=new Map;class s{addShapeGenerator(e,t){this.getShapeGenerator(e)||r.set(e,t)}getShapeGenerator(e){return r.get(e)}getSupportedShapeGenerators(){return r.keys()}}}}]);
1
+ /*! For license information please see 490.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[490],{490(e,t,a){a.d(t,{ShapeManager:()=>s});const r=new Map;class s{addShapeGenerator(e,t){this.getShapeGenerator(e)||r.set(e,t)}getShapeGenerator(e){return r.get(e)}getSupportedShapeGenerators(){return r.keys()}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
package/849.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 849.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[849],{849(t,a,s){s.d(a,{EmittersPluginInstance:()=>i});var n=s(303);class i{constructor(t,a){this.container=a,this._instancesManager=t,this._instancesManager.initContainer(a)}async init(){const t=this.container.actualOptions.emitters;if((0,n.isArray)(t))for(const a of t)await this._instancesManager.addEmitter(this.container,a);else await this._instancesManager.addEmitter(this.container,t)}pause(){for(const t of this._instancesManager.getArray(this.container))t.pause()}play(){for(const t of this._instancesManager.getArray(this.container))t.play()}resize(){for(const t of this._instancesManager.getArray(this.container))t.resize()}stop(){this._instancesManager.clear(this.container)}update(t){this._instancesManager.getArray(this.container).forEach((a=>{a.update(t)}))}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
package/940.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 940.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[940],{21(t,i,e){e.d(i,{v:()=>c});var s=e(303);class o{constructor(){this.wait=!1}load(t){(0,s.isNull)(t)||(void 0!==t.count&&(this.count=t.count),void 0!==t.delay&&(this.delay=(0,s.setRangeValue)(t.delay)),void 0!==t.duration&&(this.duration=(0,s.setRangeValue)(t.duration)),void 0!==t.wait&&(this.wait=t.wait))}}class a{constructor(){this.quantity=1,this.delay=.1}load(t){(0,s.isNull)(t)||(void 0!==t.quantity&&(this.quantity=(0,s.setRangeValue)(t.quantity)),void 0!==t.delay&&(this.delay=(0,s.setRangeValue)(t.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){(0,s.isNull)(t)||(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class r{constructor(){this.options={},this.replace=new n,this.type="square"}load(t){(0,s.isNull)(t)||(void 0!==t.options&&(this.options=(0,s.deepExtend)({},t.options??{})),this.replace.load(t.replace),void 0!==t.type&&(this.type=t.type))}}var l=e(129);class c{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new o,this.rate=new a,this.shape=new r,this.startCount=0}load(t){(0,s.isNull)(t)||(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.size&&(this.size??=new l.G,this.size.load(t.size)),void 0!==t.direction&&(this.direction=t.direction),this.domId=t.domId,void 0!==t.fill&&(this.fill=t.fill),this.life.load(t.life),this.name=t.name,this.particles=(0,s.executeOnSingleOrMultiple)(t.particles,(t=>(0,s.deepExtend)({},t))),this.rate.load(t.rate),this.shape.load(t.shape),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=(0,s.setRangeValue)(t.position.x)),void 0!==t.position.y&&(this.position.y=(0,s.setRangeValue)(t.position.y))),void 0!==t.spawnColor&&(this.spawnColor??=new s.AnimatableColor,this.spawnColor.load(t.spawnColor)),void 0!==t.startCount&&(this.startCount=t.startCount))}}},129(t,i,e){e.d(i,{G:()=>o});var s=e(303);class o{constructor(){this.mode=s.PixelMode.percent,this.height=0,this.width=0}load(t){(0,s.isNull)(t)||(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}},940(t,i,e){e.d(i,{EmittersInteractor:()=>l});var s=e(702),o=e(303),a=e(21);const n={count:1,enable:!0},r="emitters";class l extends s.ExternalInteractorBase{constructor(t,i){super(i),this._instancesManager=t,this.handleClickMode=(t,i)=>{const e=this.container.actualOptions.interactivity.modes.emitters;if(!e||t!==r)return;let s;if((0,o.isArray)(e.value)){const t=0,i=e.value.length;if(i>t&&e.random.enable){s=[];const t=new Set;for(let a=0;a<e.random.count;a++){const n=(0,o.arrayRandomIndex)(e.value);if(t.has(n)&&t.size<i){a--;continue}t.add(n);const r=(0,o.itemFromArray)(e.value,n);r&&s.push(r)}}else s=e.value}else s=e.value;const a=s,n=i.mouse.clickPosition;(0,o.executeOnSingleOrMultiple)(a,(async t=>{await this._instancesManager.addEmitter(this.container,t,n)}))}}clear(){}init(){}interact(t,i){for(const t of this._instancesManager.getArray(this.container))t.update(i)}isEnabled(t,i){const e=this.container.actualOptions,s=t.mouse,a=(i?.interactivity??e.interactivity).events;return!(!s.clickPosition||!a.onClick.enable)&&(0,o.isInArray)(r,a.onClick.mode)}loadModeOptions(t,...i){t.emitters={random:n,value:[]};for(const e of i)if(e?.emitters)if((0,o.isArray)(e.emitters))for(const i of e.emitters){const e=new a.v;e.load(i),t.emitters.value.push(e)}else if(Object.hasOwn(e.emitters,"value")){const i=e.emitters;if(t.emitters.random.enable=i.random?.enable??t.emitters.random.enable,t.emitters.random.count=i.random?.count??t.emitters.random.count,(0,o.isArray)(i.value))for(const e of i.value){const i=new a.v;i.load(e),t.emitters.value.push(i)}else{const e=new a.v;e.load(i.value),t.emitters.value.push(e)}}else{const i=new a.v;i.load(e.emitters),t.emitters.value.push(i)}}removeEmitter(t){const i=this._instancesManager.getArray(this.container).indexOf(t);i>=0&&this._instancesManager.getArray(this.container).splice(i,1)}reset(){}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.4 by Matteo Bruni */
@@ -1,7 +1,7 @@
1
1
  import { PixelMode, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, hMax, half, isPointInside, itemFromSingleOrMultiple, lMax, millisecondsToSeconds, randomInRangeValue, rangeColorToHsl, sMax, safeDocument, } from "@tsparticles/engine";
2
2
  import { Emitter } from "./Options/Classes/Emitter.js";
3
3
  import { EmitterSize } from "./Options/Classes/EmitterSize.js";
4
- const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1;
4
+ const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1, colorFactor = 3.6;
5
5
  function setParticlesOptionsColor(particlesOptions, color) {
6
6
  if (particlesOptions.color) {
7
7
  particlesOptions.color.value = color;
@@ -13,15 +13,15 @@ function setParticlesOptionsColor(particlesOptions, color) {
13
13
  }
14
14
  }
15
15
  export class EmitterInstance {
16
- constructor(engine, emitters, container, options, position) {
17
- this.emitters = emitters;
16
+ constructor(engine, container, removeCallback, options, position) {
18
17
  this.container = container;
18
+ this.removeCallback = removeCallback;
19
19
  this._destroy = () => {
20
20
  this._mutationObserver?.disconnect();
21
21
  this._mutationObserver = undefined;
22
22
  this._resizeObserver?.disconnect();
23
23
  this._resizeObserver = undefined;
24
- this.emitters.removeEmitter(this);
24
+ this.removeCallback(this);
25
25
  this._engine.dispatchEvent("emitterDestroyed", {
26
26
  container: this.container,
27
27
  data: {
@@ -262,24 +262,20 @@ export class EmitterInstance {
262
262
  this._emitParticles(quantity);
263
263
  }
264
264
  _emitParticles(quantity) {
265
- const singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions), reduceFactor = this.container.retina.reduceFactor;
265
+ const singleParticlesOptions = (itemFromSingleOrMultiple(this._particlesOptions) ??
266
+ {}), hslAnimation = this.options.spawnColor?.animation, reduceFactor = this.container.retina.reduceFactor, needsColorAnimation = !!hslAnimation, needsShapeData = !!this._shape, needsCopy = needsColorAnimation || needsShapeData, maxValues = needsColorAnimation ? { h: hMax, s: sMax, l: lMax } : null, shapeOptions = this.options.shape;
266
267
  for (let i = 0; i < quantity * reduceFactor; i++) {
267
- const particlesOptions = deepExtend({}, singleParticlesOptions);
268
+ const particlesOptions = needsCopy
269
+ ? deepExtend({}, singleParticlesOptions)
270
+ : singleParticlesOptions;
268
271
  if (this.spawnColor) {
269
- const hslAnimation = this.options.spawnColor?.animation;
270
- if (hslAnimation) {
271
- const maxValues = {
272
- h: hMax,
273
- s: sMax,
274
- l: lMax,
275
- }, colorFactor = 3.6;
272
+ if (hslAnimation && maxValues) {
276
273
  this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h, colorFactor);
277
274
  this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
278
275
  this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
279
276
  }
280
277
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
281
278
  }
282
- const shapeOptions = this.options.shape;
283
279
  let position = this.position;
284
280
  if (this._shape) {
285
281
  const shapePosData = this._shape.randomPosition();
@@ -0,0 +1,69 @@
1
+ import { isNumber } from "@tsparticles/engine";
2
+ import { Emitter } from "./Options/Classes/Emitter.js";
3
+ const defaultIndex = 0;
4
+ export class EmittersInstancesManager {
5
+ constructor(engine) {
6
+ this._containerArrays = new Map();
7
+ this._engine = engine;
8
+ }
9
+ async addEmitter(container, options, position) {
10
+ const emitterOptions = new Emitter();
11
+ emitterOptions.load(options);
12
+ const { EmitterInstance } = await import("./EmitterInstance.js"), emitter = new EmitterInstance(this._engine, container, (emitter) => {
13
+ this.removeEmitter(container, emitter);
14
+ }, emitterOptions, position);
15
+ await emitter.init();
16
+ this.getArray(container).push(emitter);
17
+ return emitter;
18
+ }
19
+ clear(container) {
20
+ this.initContainer(container);
21
+ this._containerArrays.set(container, []);
22
+ }
23
+ getArray(container) {
24
+ this.initContainer(container);
25
+ let array = this._containerArrays.get(container);
26
+ if (!array) {
27
+ array = [];
28
+ this._containerArrays.set(container, array);
29
+ }
30
+ return array;
31
+ }
32
+ initContainer(container) {
33
+ if (this._containerArrays.has(container)) {
34
+ return;
35
+ }
36
+ this._containerArrays.set(container, []);
37
+ container.getEmitter = (idxOrName) => {
38
+ const array = this.getArray(container);
39
+ return idxOrName === undefined || isNumber(idxOrName)
40
+ ? array[idxOrName ?? defaultIndex]
41
+ : array.find(t => t.name === idxOrName);
42
+ };
43
+ container.addEmitter = async (options, position) => this.addEmitter(container, options, position);
44
+ container.removeEmitter = (idxOrName) => {
45
+ const emitter = container.getEmitter?.(idxOrName);
46
+ if (emitter) {
47
+ this.removeEmitter(container, emitter);
48
+ }
49
+ };
50
+ container.playEmitter = (idxOrName) => {
51
+ const emitter = container.getEmitter?.(idxOrName);
52
+ if (emitter) {
53
+ emitter.externalPlay();
54
+ }
55
+ };
56
+ container.pauseEmitter = (idxOrName) => {
57
+ const emitter = container.getEmitter?.(idxOrName);
58
+ if (emitter) {
59
+ emitter.externalPause();
60
+ }
61
+ };
62
+ }
63
+ removeEmitter(container, emitter) {
64
+ const index = this.getArray(container).indexOf(emitter), minIndex = 0, deleteCount = 1;
65
+ if (index >= minIndex) {
66
+ this.getArray(container).splice(index, deleteCount);
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,112 @@
1
+ import { ExternalInteractorBase, } from "@tsparticles/plugin-interactivity";
2
+ import { arrayRandomIndex, executeOnSingleOrMultiple, isArray, isInArray, itemFromArray, } from "@tsparticles/engine";
3
+ import { Emitter } from "./Options/Classes/Emitter.js";
4
+ import { defaultRandomOptions } from "./constants.js";
5
+ const emittersMode = "emitters";
6
+ export class EmittersInteractor extends ExternalInteractorBase {
7
+ constructor(instancesManager, container) {
8
+ super(container);
9
+ this._instancesManager = instancesManager;
10
+ this.handleClickMode = (mode, interactivityData) => {
11
+ const container = this.container, options = container.actualOptions, modeEmitters = options.interactivity.modes.emitters;
12
+ if (!modeEmitters || mode !== emittersMode) {
13
+ return;
14
+ }
15
+ let emittersModeOptions;
16
+ if (isArray(modeEmitters.value)) {
17
+ const minLength = 0, modeEmittersCount = modeEmitters.value.length;
18
+ if (modeEmittersCount > minLength && modeEmitters.random.enable) {
19
+ emittersModeOptions = [];
20
+ const usedIndexes = new Set();
21
+ for (let i = 0; i < modeEmitters.random.count; i++) {
22
+ const idx = arrayRandomIndex(modeEmitters.value);
23
+ if (usedIndexes.has(idx) && usedIndexes.size < modeEmittersCount) {
24
+ i--;
25
+ continue;
26
+ }
27
+ usedIndexes.add(idx);
28
+ const selectedOptions = itemFromArray(modeEmitters.value, idx);
29
+ if (!selectedOptions) {
30
+ continue;
31
+ }
32
+ emittersModeOptions.push(selectedOptions);
33
+ }
34
+ }
35
+ else {
36
+ emittersModeOptions = modeEmitters.value;
37
+ }
38
+ }
39
+ else {
40
+ emittersModeOptions = modeEmitters.value;
41
+ }
42
+ const emittersOptions = emittersModeOptions, ePosition = interactivityData.mouse.clickPosition;
43
+ void executeOnSingleOrMultiple(emittersOptions, async (emitter) => {
44
+ await this._instancesManager.addEmitter(this.container, emitter, ePosition);
45
+ });
46
+ };
47
+ }
48
+ clear() {
49
+ }
50
+ init() {
51
+ }
52
+ interact(_interactivityData, delta) {
53
+ for (const emitter of this._instancesManager.getArray(this.container)) {
54
+ emitter.update(delta);
55
+ }
56
+ }
57
+ isEnabled(interactivityData, particle) {
58
+ const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity).events;
59
+ if (!mouse.clickPosition || !events.onClick.enable) {
60
+ return false;
61
+ }
62
+ return isInArray(emittersMode, events.onClick.mode);
63
+ }
64
+ loadModeOptions(options, ...sources) {
65
+ options.emitters = {
66
+ random: defaultRandomOptions,
67
+ value: [],
68
+ };
69
+ for (const source of sources) {
70
+ if (!source?.emitters) {
71
+ continue;
72
+ }
73
+ if (isArray(source.emitters)) {
74
+ for (const emitter of source.emitters) {
75
+ const tmp = new Emitter();
76
+ tmp.load(emitter);
77
+ options.emitters.value.push(tmp);
78
+ }
79
+ }
80
+ else if (Object.hasOwn(source.emitters, "value")) {
81
+ const emitterModeOptions = source.emitters;
82
+ options.emitters.random.enable = emitterModeOptions.random?.enable ?? options.emitters.random.enable;
83
+ options.emitters.random.count = emitterModeOptions.random?.count ?? options.emitters.random.count;
84
+ if (isArray(emitterModeOptions.value)) {
85
+ for (const emitter of emitterModeOptions.value) {
86
+ const tmp = new Emitter();
87
+ tmp.load(emitter);
88
+ options.emitters.value.push(tmp);
89
+ }
90
+ }
91
+ else {
92
+ const tmp = new Emitter();
93
+ tmp.load(emitterModeOptions.value);
94
+ options.emitters.value.push(tmp);
95
+ }
96
+ }
97
+ else {
98
+ const tmp = new Emitter();
99
+ tmp.load(source.emitters);
100
+ options.emitters.value.push(tmp);
101
+ }
102
+ }
103
+ }
104
+ removeEmitter(emitter) {
105
+ const index = this._instancesManager.getArray(this.container).indexOf(emitter), minIndex = 0, deleteCount = 1;
106
+ if (index >= minIndex) {
107
+ this._instancesManager.getArray(this.container).splice(index, deleteCount);
108
+ }
109
+ }
110
+ reset() {
111
+ }
112
+ }
@@ -1,16 +1,15 @@
1
- import { executeOnSingleOrMultiple, isArray, isInArray, } from "@tsparticles/engine";
1
+ import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
2
  import { Emitter } from "./Options/Classes/Emitter.js";
3
- import { EmitterClickMode } from "./Enums/EmitterClickMode.js";
4
- import { Emitters } from "./Emitters.js";
5
3
  export class EmittersPlugin {
6
- constructor(engine) {
7
- this._engine = engine;
4
+ constructor(instancesManager) {
5
+ this._instancesManager = instancesManager;
8
6
  this.id = "emitters";
9
7
  }
10
- getPlugin(container) {
11
- return Promise.resolve(new Emitters(this._engine, container));
8
+ async getPlugin(container) {
9
+ const { EmittersPluginInstance } = await import("./EmittersPluginInstance.js");
10
+ return new EmittersPluginInstance(this._instancesManager, container);
12
11
  }
13
- loadOptions(options, source) {
12
+ loadOptions(_container, options, source) {
14
13
  if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
15
14
  return;
16
15
  }
@@ -21,58 +20,12 @@ export class EmittersPlugin {
21
20
  return tmp;
22
21
  });
23
22
  }
24
- const interactivityEmitters = source?.interactivity?.modes?.emitters;
25
- if (interactivityEmitters) {
26
- if (isArray(interactivityEmitters)) {
27
- options.interactivity.modes.emitters = {
28
- random: {
29
- count: 1,
30
- enable: true,
31
- },
32
- value: interactivityEmitters.map(s => {
33
- const tmp = new Emitter();
34
- tmp.load(s);
35
- return tmp;
36
- }),
37
- };
38
- }
39
- else {
40
- const emitterMode = interactivityEmitters;
41
- if (isArray(emitterMode.value)) {
42
- options.interactivity.modes.emitters = {
43
- random: {
44
- count: emitterMode.random.count,
45
- enable: emitterMode.random.enable,
46
- },
47
- value: emitterMode.value.map(s => {
48
- const tmp = new Emitter();
49
- tmp.load(s);
50
- return tmp;
51
- }),
52
- };
53
- }
54
- else {
55
- const tmp = new Emitter();
56
- tmp.load(emitterMode.value);
57
- options.interactivity.modes.emitters = {
58
- random: {
59
- count: emitterMode.random.count,
60
- enable: emitterMode.random.enable,
61
- },
62
- value: tmp,
63
- };
64
- }
65
- }
66
- }
67
23
  }
68
24
  needsPlugin(options) {
69
25
  if (!options) {
70
26
  return false;
71
27
  }
72
28
  const emitters = options.emitters;
73
- return ((isArray(emitters) && !!emitters.length) ||
74
- emitters !== undefined ||
75
- (!!options.interactivity?.events?.onClick?.mode &&
76
- isInArray(EmitterClickMode.emitter, options.interactivity.events.onClick.mode)));
29
+ return (isArray(emitters) && !!emitters.length) || emitters !== undefined;
77
30
  }
78
31
  }
@@ -0,0 +1,42 @@
1
+ import { isArray } from "@tsparticles/engine";
2
+ export class EmittersPluginInstance {
3
+ constructor(instancesManager, container) {
4
+ this.container = container;
5
+ this._instancesManager = instancesManager;
6
+ this._instancesManager.initContainer(container);
7
+ }
8
+ async init() {
9
+ const emittersOptions = this.container.actualOptions.emitters;
10
+ if (isArray(emittersOptions)) {
11
+ for (const emitterOptions of emittersOptions) {
12
+ await this._instancesManager.addEmitter(this.container, emitterOptions);
13
+ }
14
+ }
15
+ else {
16
+ await this._instancesManager.addEmitter(this.container, emittersOptions);
17
+ }
18
+ }
19
+ pause() {
20
+ for (const emitter of this._instancesManager.getArray(this.container)) {
21
+ emitter.pause();
22
+ }
23
+ }
24
+ play() {
25
+ for (const emitter of this._instancesManager.getArray(this.container)) {
26
+ emitter.play();
27
+ }
28
+ }
29
+ resize() {
30
+ for (const emitter of this._instancesManager.getArray(this.container)) {
31
+ emitter.resize();
32
+ }
33
+ }
34
+ stop() {
35
+ this._instancesManager.clear(this.container);
36
+ }
37
+ update(delta) {
38
+ this._instancesManager.getArray(this.container).forEach(emitter => {
39
+ emitter.update(delta);
40
+ });
41
+ }
42
+ }
@@ -1,14 +1,14 @@
1
- const shapeGeneratorss = new Map();
1
+ const shapeGenerators = new Map();
2
2
  export class ShapeManager {
3
3
  addShapeGenerator(name, generator) {
4
4
  if (!this.getShapeGenerator(name)) {
5
- shapeGeneratorss.set(name, generator);
5
+ shapeGenerators.set(name, generator);
6
6
  }
7
7
  }
8
8
  getShapeGenerator(name) {
9
- return shapeGeneratorss.get(name);
9
+ return shapeGenerators.get(name);
10
10
  }
11
11
  getSupportedShapeGenerators() {
12
- return shapeGeneratorss.keys();
12
+ return shapeGenerators.keys();
13
13
  }
14
14
  }
@@ -0,0 +1,4 @@
1
+ export const defaultRandomOptions = {
2
+ count: 1,
3
+ enable: true,
4
+ };
package/browser/index.js CHANGED
@@ -1,13 +1,17 @@
1
1
  export function loadEmittersPlugin(engine) {
2
- engine.checkVersion("4.0.0-alpha.2");
2
+ engine.checkVersion("4.0.0-alpha.4");
3
3
  engine.register(async (e) => {
4
- const { ShapeManager } = await import("./ShapeManager.js"), { EmittersPlugin } = await import("./EmittersPlugin.js");
4
+ const { loadInteractivityPlugin } = await import("@tsparticles/plugin-interactivity"), { ShapeManager } = await import("./ShapeManager.js"), { EmittersInstancesManager } = await import("./EmittersInstancesManager.js"), { EmittersPlugin } = await import("./EmittersPlugin.js"), instancesManager = new EmittersInstancesManager(e);
5
+ loadInteractivityPlugin(e);
5
6
  e.emitterShapeManager ??= new ShapeManager();
6
7
  e.addEmitterShapeGenerator ??= (name, generator) => {
7
8
  e.emitterShapeManager?.addShapeGenerator(name, generator);
8
9
  };
9
- const plugin = new EmittersPlugin(e);
10
- e.addPlugin(plugin);
10
+ e.addPlugin(new EmittersPlugin(instancesManager));
11
+ e.addInteractor?.("externalEmitters", async (container) => {
12
+ const { EmittersInteractor } = await import("./EmittersInteractor.js");
13
+ return new EmittersInteractor(instancesManager, container);
14
+ });
11
15
  });
12
16
  }
13
17
  export * from "./EmitterShapeBase.js";
@@ -1,7 +1,7 @@
1
1
  import { PixelMode, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, hMax, half, isPointInside, itemFromSingleOrMultiple, lMax, millisecondsToSeconds, randomInRangeValue, rangeColorToHsl, sMax, safeDocument, } from "@tsparticles/engine";
2
2
  import { Emitter } from "./Options/Classes/Emitter.js";
3
3
  import { EmitterSize } from "./Options/Classes/EmitterSize.js";
4
- const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1;
4
+ const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1, colorFactor = 3.6;
5
5
  function setParticlesOptionsColor(particlesOptions, color) {
6
6
  if (particlesOptions.color) {
7
7
  particlesOptions.color.value = color;
@@ -13,15 +13,15 @@ function setParticlesOptionsColor(particlesOptions, color) {
13
13
  }
14
14
  }
15
15
  export class EmitterInstance {
16
- constructor(engine, emitters, container, options, position) {
17
- this.emitters = emitters;
16
+ constructor(engine, container, removeCallback, options, position) {
18
17
  this.container = container;
18
+ this.removeCallback = removeCallback;
19
19
  this._destroy = () => {
20
20
  this._mutationObserver?.disconnect();
21
21
  this._mutationObserver = undefined;
22
22
  this._resizeObserver?.disconnect();
23
23
  this._resizeObserver = undefined;
24
- this.emitters.removeEmitter(this);
24
+ this.removeCallback(this);
25
25
  this._engine.dispatchEvent("emitterDestroyed", {
26
26
  container: this.container,
27
27
  data: {
@@ -262,24 +262,20 @@ export class EmitterInstance {
262
262
  this._emitParticles(quantity);
263
263
  }
264
264
  _emitParticles(quantity) {
265
- const singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions), reduceFactor = this.container.retina.reduceFactor;
265
+ const singleParticlesOptions = (itemFromSingleOrMultiple(this._particlesOptions) ??
266
+ {}), hslAnimation = this.options.spawnColor?.animation, reduceFactor = this.container.retina.reduceFactor, needsColorAnimation = !!hslAnimation, needsShapeData = !!this._shape, needsCopy = needsColorAnimation || needsShapeData, maxValues = needsColorAnimation ? { h: hMax, s: sMax, l: lMax } : null, shapeOptions = this.options.shape;
266
267
  for (let i = 0; i < quantity * reduceFactor; i++) {
267
- const particlesOptions = deepExtend({}, singleParticlesOptions);
268
+ const particlesOptions = needsCopy
269
+ ? deepExtend({}, singleParticlesOptions)
270
+ : singleParticlesOptions;
268
271
  if (this.spawnColor) {
269
- const hslAnimation = this.options.spawnColor?.animation;
270
- if (hslAnimation) {
271
- const maxValues = {
272
- h: hMax,
273
- s: sMax,
274
- l: lMax,
275
- }, colorFactor = 3.6;
272
+ if (hslAnimation && maxValues) {
276
273
  this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h, colorFactor);
277
274
  this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
278
275
  this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
279
276
  }
280
277
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
281
278
  }
282
- const shapeOptions = this.options.shape;
283
279
  let position = this.position;
284
280
  if (this._shape) {
285
281
  const shapePosData = this._shape.randomPosition();
@@ -0,0 +1,69 @@
1
+ import { isNumber } from "@tsparticles/engine";
2
+ import { Emitter } from "./Options/Classes/Emitter.js";
3
+ const defaultIndex = 0;
4
+ export class EmittersInstancesManager {
5
+ constructor(engine) {
6
+ this._containerArrays = new Map();
7
+ this._engine = engine;
8
+ }
9
+ async addEmitter(container, options, position) {
10
+ const emitterOptions = new Emitter();
11
+ emitterOptions.load(options);
12
+ const { EmitterInstance } = await import("./EmitterInstance.js"), emitter = new EmitterInstance(this._engine, container, (emitter) => {
13
+ this.removeEmitter(container, emitter);
14
+ }, emitterOptions, position);
15
+ await emitter.init();
16
+ this.getArray(container).push(emitter);
17
+ return emitter;
18
+ }
19
+ clear(container) {
20
+ this.initContainer(container);
21
+ this._containerArrays.set(container, []);
22
+ }
23
+ getArray(container) {
24
+ this.initContainer(container);
25
+ let array = this._containerArrays.get(container);
26
+ if (!array) {
27
+ array = [];
28
+ this._containerArrays.set(container, array);
29
+ }
30
+ return array;
31
+ }
32
+ initContainer(container) {
33
+ if (this._containerArrays.has(container)) {
34
+ return;
35
+ }
36
+ this._containerArrays.set(container, []);
37
+ container.getEmitter = (idxOrName) => {
38
+ const array = this.getArray(container);
39
+ return idxOrName === undefined || isNumber(idxOrName)
40
+ ? array[idxOrName ?? defaultIndex]
41
+ : array.find(t => t.name === idxOrName);
42
+ };
43
+ container.addEmitter = async (options, position) => this.addEmitter(container, options, position);
44
+ container.removeEmitter = (idxOrName) => {
45
+ const emitter = container.getEmitter?.(idxOrName);
46
+ if (emitter) {
47
+ this.removeEmitter(container, emitter);
48
+ }
49
+ };
50
+ container.playEmitter = (idxOrName) => {
51
+ const emitter = container.getEmitter?.(idxOrName);
52
+ if (emitter) {
53
+ emitter.externalPlay();
54
+ }
55
+ };
56
+ container.pauseEmitter = (idxOrName) => {
57
+ const emitter = container.getEmitter?.(idxOrName);
58
+ if (emitter) {
59
+ emitter.externalPause();
60
+ }
61
+ };
62
+ }
63
+ removeEmitter(container, emitter) {
64
+ const index = this.getArray(container).indexOf(emitter), minIndex = 0, deleteCount = 1;
65
+ if (index >= minIndex) {
66
+ this.getArray(container).splice(index, deleteCount);
67
+ }
68
+ }
69
+ }