@tsparticles/plugin-emitters 3.9.0 → 4.0.0-alpha.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.
Files changed (58) hide show
  1. package/214.min.js +2 -0
  2. package/214.min.js.LICENSE.txt +1 -0
  3. package/921.min.js +2 -0
  4. package/921.min.js.LICENSE.txt +1 -0
  5. package/browser/EmitterInstance.js +12 -13
  6. package/browser/Emitters.js +9 -8
  7. package/browser/EmittersPlugin.js +19 -32
  8. package/browser/Options/Classes/Emitter.js +2 -6
  9. package/browser/ShapeManager.js +0 -3
  10. package/browser/index.js +10 -18
  11. package/cjs/EmitterContainer.js +1 -2
  12. package/cjs/EmitterInstance.js +34 -39
  13. package/cjs/EmitterShapeBase.js +1 -5
  14. package/cjs/Emitters.js +21 -24
  15. package/cjs/EmittersEngine.js +1 -2
  16. package/cjs/EmittersPlugin.js +31 -48
  17. package/cjs/Enums/EmitterClickMode.js +2 -5
  18. package/cjs/IEmitterShape.js +1 -2
  19. package/cjs/IEmitterShapeGenerator.js +1 -2
  20. package/cjs/IRandomPositionData.js +1 -2
  21. package/cjs/Options/Classes/Emitter.js +16 -24
  22. package/cjs/Options/Classes/EmitterLife.js +5 -9
  23. package/cjs/Options/Classes/EmitterRate.js +5 -9
  24. package/cjs/Options/Classes/EmitterShape.js +6 -10
  25. package/cjs/Options/Classes/EmitterShapeReplace.js +3 -7
  26. package/cjs/Options/Classes/EmitterSize.js +4 -8
  27. package/cjs/Options/Interfaces/IEmitter.js +1 -2
  28. package/cjs/Options/Interfaces/IEmitterLife.js +1 -2
  29. package/cjs/Options/Interfaces/IEmitterRate.js +1 -2
  30. package/cjs/Options/Interfaces/IEmitterShape.js +1 -2
  31. package/cjs/Options/Interfaces/IEmitterShapeReplace.js +1 -2
  32. package/cjs/Options/Interfaces/IEmitterSize.js +1 -2
  33. package/cjs/ShapeManager.js +1 -8
  34. package/cjs/index.js +12 -37
  35. package/cjs/types.js +1 -2
  36. package/dist_browser_EmittersPlugin_js.js +110 -0
  37. package/dist_browser_ShapeManager_js.js +30 -0
  38. package/esm/EmitterInstance.js +12 -13
  39. package/esm/Emitters.js +9 -8
  40. package/esm/EmittersPlugin.js +19 -32
  41. package/esm/Options/Classes/Emitter.js +2 -6
  42. package/esm/ShapeManager.js +0 -3
  43. package/esm/index.js +10 -18
  44. package/package.json +4 -3
  45. package/report.html +5 -4
  46. package/tsparticles.plugin.emitters.js +215 -126
  47. package/tsparticles.plugin.emitters.min.js +1 -1
  48. package/tsparticles.plugin.emitters.min.js.LICENSE.txt +1 -1
  49. package/types/Options/Classes/EmitterShape.d.ts +1 -1
  50. package/types/Options/Classes/EmitterShapeReplace.d.ts +1 -1
  51. package/types/ShapeManager.d.ts +0 -3
  52. package/types/index.d.ts +7 -7
  53. package/umd/EmitterInstance.js +13 -14
  54. package/umd/Emitters.js +9 -8
  55. package/umd/EmittersPlugin.js +19 -32
  56. package/umd/Options/Classes/Emitter.js +2 -6
  57. package/umd/ShapeManager.js +0 -3
  58. package/umd/index.js +34 -19
package/214.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 214.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_emitters=this.webpackChunk_tsparticles_plugin_emitters||[]).push([[214],{214(t,i,e){e.d(i,{EmittersPlugin:()=>m});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 n{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 a{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 a,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))}}class h{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))}}class l{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new o,this.rate=new n,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 h,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))}}var c=e(271);function d(t,i){t.color?t.color.value=i:t.color={value:i}}class u{constructor(t,i,e,o,n){this.emitters=i,this.container=e,this._destroy=()=>{this._mutationObserver?.disconnect(),this._mutationObserver=void 0,this._resizeObserver?.disconnect(),this._resizeObserver=void 0,this.emitters.removeEmitter(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=n,o instanceof l?this.options=o:(this.options=new l,this.options.load(o)),this._spawnDelay=e.retina.reduceFactor?(0,s.getRangeValue)(this.options.life.delay??0)*s.millisecondsToSeconds/e.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 a=(0,s.deepExtend)({},this.options.particles);if(a.move??={},a.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=a,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 r=this.options.shape,h=this._engine.emitterShapeManager?.getShapeGenerator(r.type);h&&(this._shape=h.generate(this.position,this.size,this.fill,r.options)),this._engine.dispatchEvent("emitterCreated",{container:e,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 h;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.container.retina.reduceFactor;for(let o=0;o<t*e;o++){const t=(0,s.deepExtend)({},i);if(this.spawnColor){const i=this.options.spawnColor?.animation;if(i){const t={h:s.hMax,s:s.sMax,l:s.lMax},e=3.6;this.spawnColor.h=this._setColorAnimation(i.h,this.spawnColor.h,t.h,e),this.spawnColor.s=this._setColorAnimation(i.s,this.spawnColor.s,t.s),this.spawnColor.l=this._setColorAnimation(i.l,this.spawnColor.l,t.l)}d(t,this.spawnColor)}const e=this.options.shape;let o=this.position;if(this._shape){const i=this._shape.randomPosition();if(i){o=i.position;const s=e.replace;s.color&&i.color&&d(t,i.color),s.opacity&&(t.opacity?t.opacity.value=i.opacity:t.opacity={value:i.opacity})}else o=null}o&&this.container.particles.addParticle(o,t)}}}class p{constructor(t,i){this.container=i,this._engine=t,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]};i.getEmitter=t=>void 0===t||(0,s.isNumber)(t)?this.array[t??0]:this.array.find((i=>i.name===t)),i.addEmitter=async(t,i)=>this.addEmitter(t,i),i.removeEmitter=t=>{const e=i.getEmitter(t);e&&this.removeEmitter(e)},i.playEmitter=t=>{const e=i.getEmitter(t);e&&e.externalPlay()},i.pauseEmitter=t=>{const e=i.getEmitter(t);e&&e.externalPause()}}async addEmitter(t,i){const e=new l;e.load(t);const s=new u(this._engine,this,this.container,e,i);return await s.init(),this.array.push(s),s}handleClickMode(t){const i=this.interactivityEmitters;if(t!==c.c.emitter)return;let e;if((0,s.isArray)(i.value)){const t=0;if(i.value.length>t&&i.random.enable){e=[];const t=[];for(let o=0;o<i.random.count;o++){const n=(0,s.arrayRandomIndex)(i.value);if(t.includes(n)&&t.length<i.value.length){o--;continue}t.push(n);const a=(0,s.itemFromArray)(i.value,n);a&&e.push(a)}}else e=i.value}else e=i.value;const o=e,n=this.container.interactivity.mouse.clickPosition;(0,s.executeOnSingleOrMultiple)(o,(async t=>{await this.addEmitter(t,n)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,(0,s.isArray)(this.emitters))for(const t of this.emitters)await this.addEmitter(t);else await this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const i=this.array.indexOf(t);i>=0&&this.array.splice(i,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}update(t){for(const i of this.array)i.update(t)}}class m{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return Promise.resolve(new p(this._engine,t))}loadOptions(t,i){if(!this.needsPlugin(t)&&!this.needsPlugin(i))return;i?.emitters&&(t.emitters=(0,s.executeOnSingleOrMultiple)(i.emitters,(t=>{const i=new l;return i.load(t),i})));const e=i?.interactivity?.modes?.emitters;if(e)if((0,s.isArray)(e))t.interactivity.modes.emitters={random:{count:1,enable:!0},value:e.map((t=>{const i=new l;return i.load(t),i}))};else{const i=e;if((0,s.isArray)(i.value))t.interactivity.modes.emitters={random:{count:i.random.count,enable:i.random.enable},value:i.value.map((t=>{const i=new l;return i.load(t),i}))};else{const e=new l;e.load(i.value),t.interactivity.modes.emitters={random:{count:i.random.count,enable:i.random.enable},value:e}}}}needsPlugin(t){if(!t)return!1;const i=t.emitters;return(0,s.isArray)(i)&&!!i.length||void 0!==i||!!t.interactivity?.events?.onClick?.mode&&(0,s.isInArray)(c.c.emitter,t.interactivity.events.onClick.mode)}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.0 by Matteo Bruni */
package/921.min.js ADDED
@@ -0,0 +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()}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Emitters Plugin v4.0.0-alpha.0 by Matteo Bruni */
@@ -1,7 +1,7 @@
1
- import { PixelMode, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, millisecondsToSeconds, randomInRange, rangeColorToHsl, } from "@tsparticles/engine";
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 half = 0.5, 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;
5
5
  function setParticlesOptionsColor(particlesOptions, color) {
6
6
  if (particlesOptions.color) {
7
7
  particlesOptions.color.value = color;
@@ -33,7 +33,7 @@ export class EmitterInstance {
33
33
  if (this._paused) {
34
34
  return;
35
35
  }
36
- const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
36
+ const duration = this.options.life.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
37
37
  if ((this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
38
38
  this._duration = duration * millisecondsToSeconds;
39
39
  }
@@ -43,9 +43,9 @@ export class EmitterInstance {
43
43
  if (!animation.enable) {
44
44
  return initValue;
45
45
  }
46
- const colorOffset = randomInRange(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = container.retina.reduceFactor
46
+ const colorOffset = randomInRangeValue(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = container.retina.reduceFactor
47
47
  ? (delay * millisecondsToSeconds) / container.retina.reduceFactor
48
- : Infinity, defaultColorSpeed = 0, colorSpeed = getRangeValue(animation.speed ?? defaultColorSpeed);
48
+ : Infinity, colorSpeed = getRangeValue(animation.speed);
49
49
  return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * factor) % maxValue;
50
50
  };
51
51
  this._engine = engine;
@@ -69,8 +69,7 @@ export class EmitterInstance {
69
69
  this.fill = this.options.fill;
70
70
  this._firstSpawn = !this.options.life.wait;
71
71
  this._startParticlesAdded = false;
72
- let particlesOptions = deepExtend({}, this.options.particles);
73
- particlesOptions ??= {};
72
+ const particlesOptions = deepExtend({}, this.options.particles);
74
73
  particlesOptions.move ??= {};
75
74
  particlesOptions.move.direction ??= this.options.direction;
76
75
  if (this.options.spawnColor) {
@@ -83,7 +82,7 @@ export class EmitterInstance {
83
82
  this._lifeCount = this.options.life.count ?? defaultLifeCount;
84
83
  this._immortal = this._lifeCount <= minLifeCount;
85
84
  if (this.options.domId) {
86
- const element = document.getElementById(this.options.domId);
85
+ const element = safeDocument().getElementById(this.options.domId);
87
86
  if (element) {
88
87
  this._mutationObserver = new MutationObserver(() => {
89
88
  this.resize();
@@ -217,7 +216,7 @@ export class EmitterInstance {
217
216
  _calcPosition() {
218
217
  const container = this.container;
219
218
  if (this.options.domId) {
220
- const element = document.getElementById(this.options.domId);
219
+ const element = safeDocument().getElementById(this.options.domId);
221
220
  if (element) {
222
221
  const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
223
222
  return {
@@ -234,7 +233,7 @@ export class EmitterInstance {
234
233
  _calcSize() {
235
234
  const container = this.container;
236
235
  if (this.options.domId) {
237
- const element = document.getElementById(this.options.domId);
236
+ const element = safeDocument().getElementById(this.options.domId);
238
237
  if (element) {
239
238
  const elRect = element.getBoundingClientRect();
240
239
  return {
@@ -270,9 +269,9 @@ export class EmitterInstance {
270
269
  const hslAnimation = this.options.spawnColor?.animation;
271
270
  if (hslAnimation) {
272
271
  const maxValues = {
273
- h: 360,
274
- s: 100,
275
- l: 100,
272
+ h: hMax,
273
+ s: sMax,
274
+ l: lMax,
276
275
  }, colorFactor = 3.6;
277
276
  this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h, colorFactor);
278
277
  this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
@@ -48,12 +48,12 @@ export class Emitters {
48
48
  return emitter;
49
49
  }
50
50
  handleClickMode(mode) {
51
- const emitterOptions = this.emitters, modeEmitters = this.interactivityEmitters;
51
+ const modeEmitters = this.interactivityEmitters;
52
52
  if (mode !== EmitterClickMode.emitter) {
53
53
  return;
54
54
  }
55
55
  let emittersModeOptions;
56
- if (modeEmitters && isArray(modeEmitters.value)) {
56
+ if (isArray(modeEmitters.value)) {
57
57
  const minLength = 0;
58
58
  if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
59
59
  emittersModeOptions = [];
@@ -65,7 +65,11 @@ export class Emitters {
65
65
  continue;
66
66
  }
67
67
  usedIndexes.push(idx);
68
- emittersModeOptions.push(itemFromArray(modeEmitters.value, idx));
68
+ const selectedOptions = itemFromArray(modeEmitters.value, idx);
69
+ if (!selectedOptions) {
70
+ continue;
71
+ }
72
+ emittersModeOptions.push(selectedOptions);
69
73
  }
70
74
  }
71
75
  else {
@@ -73,9 +77,9 @@ export class Emitters {
73
77
  }
74
78
  }
75
79
  else {
76
- emittersModeOptions = modeEmitters?.value;
80
+ emittersModeOptions = modeEmitters.value;
77
81
  }
78
- const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
82
+ const emittersOptions = emittersModeOptions, ePosition = this.container.interactivity.mouse.clickPosition;
79
83
  void executeOnSingleOrMultiple(emittersOptions, async (emitter) => {
80
84
  await this.addEmitter(emitter, ePosition);
81
85
  });
@@ -83,9 +87,6 @@ export class Emitters {
83
87
  async init() {
84
88
  this.emitters = this.container.actualOptions.emitters;
85
89
  this.interactivityEmitters = this.container.actualOptions.interactivity.modes.emitters;
86
- if (!this.emitters) {
87
- return;
88
- }
89
90
  if (isArray(this.emitters)) {
90
91
  for (const emitterOptions of this.emitters) {
91
92
  await this.addEmitter(emitterOptions);
@@ -38,42 +38,29 @@ export class EmittersPlugin {
38
38
  }
39
39
  else {
40
40
  const emitterMode = interactivityEmitters;
41
- if (emitterMode.value !== undefined) {
42
- const defaultCount = 1;
43
- if (isArray(emitterMode.value)) {
44
- options.interactivity.modes.emitters = {
45
- random: {
46
- count: emitterMode.random.count ?? defaultCount,
47
- enable: emitterMode.random.enable ?? false,
48
- },
49
- value: emitterMode.value.map(s => {
50
- const tmp = new Emitter();
51
- tmp.load(s);
52
- return tmp;
53
- }),
54
- };
55
- }
56
- else {
57
- const tmp = new Emitter();
58
- tmp.load(emitterMode.value);
59
- options.interactivity.modes.emitters = {
60
- random: {
61
- count: emitterMode.random.count ?? defaultCount,
62
- enable: emitterMode.random.enable ?? false,
63
- },
64
- value: tmp,
65
- };
66
- }
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
+ };
67
53
  }
68
54
  else {
69
- const emitterOptions = (options.interactivity.modes.emitters = {
55
+ const tmp = new Emitter();
56
+ tmp.load(emitterMode.value);
57
+ options.interactivity.modes.emitters = {
70
58
  random: {
71
- count: 1,
72
- enable: false,
59
+ count: emitterMode.random.count,
60
+ enable: emitterMode.random.enable,
73
61
  },
74
- value: new Emitter(),
75
- });
76
- emitterOptions.value.load(interactivityEmitters);
62
+ value: tmp,
63
+ };
77
64
  }
78
65
  }
79
66
  }
@@ -20,9 +20,7 @@ export class Emitter {
20
20
  this.autoPlay = data.autoPlay;
21
21
  }
22
22
  if (data.size !== undefined) {
23
- if (!this.size) {
24
- this.size = new EmitterSize();
25
- }
23
+ this.size ??= new EmitterSize();
26
24
  this.size.load(data.size);
27
25
  }
28
26
  if (data.direction !== undefined) {
@@ -49,9 +47,7 @@ export class Emitter {
49
47
  }
50
48
  }
51
49
  if (data.spawnColor !== undefined) {
52
- if (this.spawnColor === undefined) {
53
- this.spawnColor = new AnimatableColor();
54
- }
50
+ this.spawnColor ??= new AnimatableColor();
55
51
  this.spawnColor.load(data.spawnColor);
56
52
  }
57
53
  if (data.startCount !== undefined) {
@@ -1,8 +1,5 @@
1
1
  const shapeGeneratorss = new Map();
2
2
  export class ShapeManager {
3
- constructor(engine) {
4
- this._engine = engine;
5
- }
6
3
  addShapeGenerator(name, generator) {
7
4
  if (!this.getShapeGenerator(name)) {
8
5
  shapeGeneratorss.set(name, generator);
package/browser/index.js CHANGED
@@ -1,22 +1,14 @@
1
- import { EmittersPlugin } from "./EmittersPlugin.js";
2
- import { ShapeManager } from "./ShapeManager.js";
3
- export async function loadEmittersPlugin(engine, refresh = true) {
4
- engine.checkVersion("3.9.0");
5
- if (!engine.emitterShapeManager) {
6
- engine.emitterShapeManager = new ShapeManager(engine);
7
- }
8
- if (!engine.addEmitterShapeGenerator) {
9
- engine.addEmitterShapeGenerator = (name, generator) => {
10
- engine.emitterShapeManager?.addShapeGenerator(name, generator);
1
+ export function loadEmittersPlugin(engine) {
2
+ engine.checkVersion("4.0.0-alpha.0");
3
+ engine.register(async (e) => {
4
+ const { ShapeManager } = await import("./ShapeManager.js"), { EmittersPlugin } = await import("./EmittersPlugin.js");
5
+ e.emitterShapeManager ??= new ShapeManager();
6
+ e.addEmitterShapeGenerator ??= (name, generator) => {
7
+ e.emitterShapeManager?.addShapeGenerator(name, generator);
11
8
  };
12
- }
13
- const plugin = new EmittersPlugin(engine);
14
- await engine.addPlugin(plugin, refresh);
9
+ const plugin = new EmittersPlugin(e);
10
+ e.addPlugin(plugin);
11
+ });
15
12
  }
16
- export * from "./EmitterContainer.js";
17
13
  export * from "./EmitterShapeBase.js";
18
- export * from "./EmittersEngine.js";
19
- export * from "./IEmitterShape.js";
20
- export * from "./IEmitterShapeGenerator.js";
21
14
  export * from "./Enums/EmitterClickMode.js";
22
- export * from "./IRandomPositionData.js";
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmitterInstance = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const Emitter_js_1 = require("./Options/Classes/Emitter.js");
6
- const EmitterSize_js_1 = require("./Options/Classes/EmitterSize.js");
7
- const half = 0.5, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1;
1
+ import { PixelMode, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, hMax, half, isPointInside, itemFromSingleOrMultiple, lMax, millisecondsToSeconds, randomInRangeValue, rangeColorToHsl, sMax, safeDocument, } from "@tsparticles/engine";
2
+ import { Emitter } from "./Options/Classes/Emitter.js";
3
+ import { EmitterSize } from "./Options/Classes/EmitterSize.js";
4
+ const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1;
8
5
  function setParticlesOptionsColor(particlesOptions, color) {
9
6
  if (particlesOptions.color) {
10
7
  particlesOptions.color.value = color;
@@ -15,7 +12,7 @@ function setParticlesOptionsColor(particlesOptions, color) {
15
12
  };
16
13
  }
17
14
  }
18
- class EmitterInstance {
15
+ export class EmitterInstance {
19
16
  constructor(engine, emitters, container, options, position) {
20
17
  this.emitters = emitters;
21
18
  this.container = container;
@@ -36,9 +33,9 @@ class EmitterInstance {
36
33
  if (this._paused) {
37
34
  return;
38
35
  }
39
- const duration = this.options.life?.duration !== undefined ? (0, engine_1.getRangeValue)(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
36
+ const duration = this.options.life.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
40
37
  if ((this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
41
- this._duration = duration * engine_1.millisecondsToSeconds;
38
+ this._duration = duration * millisecondsToSeconds;
42
39
  }
43
40
  };
44
41
  this._setColorAnimation = (animation, initValue, maxValue, factor = defaultColorAnimationFactor) => {
@@ -46,9 +43,9 @@ class EmitterInstance {
46
43
  if (!animation.enable) {
47
44
  return initValue;
48
45
  }
49
- const colorOffset = (0, engine_1.randomInRange)(animation.offset), delay = (0, engine_1.getRangeValue)(this.options.rate.delay), emitFactor = container.retina.reduceFactor
50
- ? (delay * engine_1.millisecondsToSeconds) / container.retina.reduceFactor
51
- : Infinity, defaultColorSpeed = 0, colorSpeed = (0, engine_1.getRangeValue)(animation.speed ?? defaultColorSpeed);
46
+ const colorOffset = randomInRangeValue(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = container.retina.reduceFactor
47
+ ? (delay * millisecondsToSeconds) / container.retina.reduceFactor
48
+ : Infinity, colorSpeed = getRangeValue(animation.speed);
52
49
  return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * factor) % maxValue;
53
50
  };
54
51
  this._engine = engine;
@@ -56,15 +53,15 @@ class EmitterInstance {
56
53
  this._currentEmitDelay = 0;
57
54
  this._currentSpawnDelay = 0;
58
55
  this._initialPosition = position;
59
- if (options instanceof Emitter_js_1.Emitter) {
56
+ if (options instanceof Emitter) {
60
57
  this.options = options;
61
58
  }
62
59
  else {
63
- this.options = new Emitter_js_1.Emitter();
60
+ this.options = new Emitter();
64
61
  this.options.load(options);
65
62
  }
66
63
  this._spawnDelay = container.retina.reduceFactor
67
- ? ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
64
+ ? (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
68
65
  container.retina.reduceFactor
69
66
  : Infinity;
70
67
  this.position = this._initialPosition ?? this._calcPosition();
@@ -72,21 +69,20 @@ class EmitterInstance {
72
69
  this.fill = this.options.fill;
73
70
  this._firstSpawn = !this.options.life.wait;
74
71
  this._startParticlesAdded = false;
75
- let particlesOptions = (0, engine_1.deepExtend)({}, this.options.particles);
76
- particlesOptions ??= {};
72
+ const particlesOptions = deepExtend({}, this.options.particles);
77
73
  particlesOptions.move ??= {};
78
74
  particlesOptions.move.direction ??= this.options.direction;
79
75
  if (this.options.spawnColor) {
80
- this.spawnColor = (0, engine_1.rangeColorToHsl)(this._engine, this.options.spawnColor);
76
+ this.spawnColor = rangeColorToHsl(this._engine, this.options.spawnColor);
81
77
  }
82
78
  this._paused = !this.options.autoPlay;
83
79
  this._particlesOptions = particlesOptions;
84
80
  this._size = this._calcSize();
85
- this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size);
81
+ this.size = getSize(this._size, this.container.canvas.size);
86
82
  this._lifeCount = this.options.life.count ?? defaultLifeCount;
87
83
  this._immortal = this._lifeCount <= minLifeCount;
88
84
  if (this.options.domId) {
89
- const element = document.getElementById(this.options.domId);
85
+ const element = safeDocument().getElementById(this.options.domId);
90
86
  if (element) {
91
87
  this._mutationObserver = new MutationObserver(() => {
92
88
  this.resize();
@@ -140,9 +136,9 @@ class EmitterInstance {
140
136
  }
141
137
  const container = this.container;
142
138
  if (this._emitDelay === undefined) {
143
- const delay = (0, engine_1.getRangeValue)(this.options.rate.delay);
139
+ const delay = getRangeValue(this.options.rate.delay);
144
140
  this._emitDelay = container.retina.reduceFactor
145
- ? (delay * engine_1.millisecondsToSeconds) / container.retina.reduceFactor
141
+ ? (delay * millisecondsToSeconds) / container.retina.reduceFactor
146
142
  : Infinity;
147
143
  }
148
144
  if (this._lifeCount > minLifeCount || this._immortal) {
@@ -152,11 +148,11 @@ class EmitterInstance {
152
148
  resize() {
153
149
  const initialPosition = this._initialPosition, container = this.container;
154
150
  this.position =
155
- initialPosition && (0, engine_1.isPointInside)(initialPosition, container.canvas.size, engine_1.Vector.origin)
151
+ initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
156
152
  ? initialPosition
157
153
  : this._calcPosition();
158
154
  this._size = this._calcSize();
159
- this.size = (0, engine_1.getSize)(this._size, container.canvas.size);
155
+ this.size = getSize(this._size, container.canvas.size);
160
156
  this._shape?.resize(this.position, this.size);
161
157
  }
162
158
  update(delta) {
@@ -187,7 +183,7 @@ class EmitterInstance {
187
183
  this.position = this._calcPosition();
188
184
  this._shape?.resize(this.position, this.size);
189
185
  this._spawnDelay = container.retina.reduceFactor
190
- ? ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
186
+ ? (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
191
187
  container.retina.reduceFactor
192
188
  : Infinity;
193
189
  }
@@ -220,7 +216,7 @@ class EmitterInstance {
220
216
  _calcPosition() {
221
217
  const container = this.container;
222
218
  if (this.options.domId) {
223
- const element = document.getElementById(this.options.domId);
219
+ const element = safeDocument().getElementById(this.options.domId);
224
220
  if (element) {
225
221
  const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
226
222
  return {
@@ -229,7 +225,7 @@ class EmitterInstance {
229
225
  };
230
226
  }
231
227
  }
232
- return (0, engine_1.calcPositionOrRandomFromSizeRanged)({
228
+ return calcPositionOrRandomFromSizeRanged({
233
229
  size: container.canvas.size,
234
230
  position: this.options.position,
235
231
  });
@@ -237,22 +233,22 @@ class EmitterInstance {
237
233
  _calcSize() {
238
234
  const container = this.container;
239
235
  if (this.options.domId) {
240
- const element = document.getElementById(this.options.domId);
236
+ const element = safeDocument().getElementById(this.options.domId);
241
237
  if (element) {
242
238
  const elRect = element.getBoundingClientRect();
243
239
  return {
244
240
  width: elRect.width * container.retina.pixelRatio,
245
241
  height: elRect.height * container.retina.pixelRatio,
246
- mode: engine_1.PixelMode.precise,
242
+ mode: PixelMode.precise,
247
243
  };
248
244
  }
249
245
  }
250
246
  return (this.options.size ??
251
247
  (() => {
252
- const size = new EmitterSize_js_1.EmitterSize();
248
+ const size = new EmitterSize();
253
249
  size.load({
254
250
  height: 0,
255
- mode: engine_1.PixelMode.percent,
251
+ mode: PixelMode.percent,
256
252
  width: 0,
257
253
  });
258
254
  return size;
@@ -262,20 +258,20 @@ class EmitterInstance {
262
258
  if (this._paused) {
263
259
  return;
264
260
  }
265
- const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity);
261
+ const quantity = getRangeValue(this.options.rate.quantity);
266
262
  this._emitParticles(quantity);
267
263
  }
268
264
  _emitParticles(quantity) {
269
- const singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions), reduceFactor = this.container.retina.reduceFactor;
265
+ const singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions), reduceFactor = this.container.retina.reduceFactor;
270
266
  for (let i = 0; i < quantity * reduceFactor; i++) {
271
- const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions);
267
+ const particlesOptions = deepExtend({}, singleParticlesOptions);
272
268
  if (this.spawnColor) {
273
269
  const hslAnimation = this.options.spawnColor?.animation;
274
270
  if (hslAnimation) {
275
271
  const maxValues = {
276
- h: 360,
277
- s: 100,
278
- l: 100,
272
+ h: hMax,
273
+ s: sMax,
274
+ l: lMax,
279
275
  }, colorFactor = 3.6;
280
276
  this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h, colorFactor);
281
277
  this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
@@ -314,4 +310,3 @@ class EmitterInstance {
314
310
  }
315
311
  }
316
312
  }
317
- exports.EmitterInstance = EmitterInstance;
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmitterShapeBase = void 0;
4
- class EmitterShapeBase {
1
+ export class EmitterShapeBase {
5
2
  constructor(position, size, fill, options) {
6
3
  this.position = position;
7
4
  this.size = size;
@@ -13,4 +10,3 @@ class EmitterShapeBase {
13
10
  this.size = size;
14
11
  }
15
12
  }
16
- exports.EmitterShapeBase = EmitterShapeBase;
package/cjs/Emitters.js CHANGED
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Emitters = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const Emitter_js_1 = require("./Options/Classes/Emitter.js");
6
- const EmitterClickMode_js_1 = require("./Enums/EmitterClickMode.js");
7
- const EmitterInstance_js_1 = require("./EmitterInstance.js");
8
- class Emitters {
1
+ import { arrayRandomIndex, executeOnSingleOrMultiple, isArray, isNumber, itemFromArray, } from "@tsparticles/engine";
2
+ import { Emitter } from "./Options/Classes/Emitter.js";
3
+ import { EmitterClickMode } from "./Enums/EmitterClickMode.js";
4
+ import { EmitterInstance } from "./EmitterInstance.js";
5
+ export class Emitters {
9
6
  constructor(engine, container) {
10
7
  this.container = container;
11
8
  this._engine = engine;
@@ -19,7 +16,7 @@ class Emitters {
19
16
  value: [],
20
17
  };
21
18
  const defaultIndex = 0;
22
- container.getEmitter = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
19
+ container.getEmitter = (idxOrName) => idxOrName === undefined || isNumber(idxOrName)
23
20
  ? this.array[idxOrName ?? defaultIndex]
24
21
  : this.array.find(t => t.name === idxOrName);
25
22
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
@@ -43,32 +40,36 @@ class Emitters {
43
40
  };
44
41
  }
45
42
  async addEmitter(options, position) {
46
- const emitterOptions = new Emitter_js_1.Emitter();
43
+ const emitterOptions = new Emitter();
47
44
  emitterOptions.load(options);
48
- const emitter = new EmitterInstance_js_1.EmitterInstance(this._engine, this, this.container, emitterOptions, position);
45
+ const emitter = new EmitterInstance(this._engine, this, this.container, emitterOptions, position);
49
46
  await emitter.init();
50
47
  this.array.push(emitter);
51
48
  return emitter;
52
49
  }
53
50
  handleClickMode(mode) {
54
- const emitterOptions = this.emitters, modeEmitters = this.interactivityEmitters;
55
- if (mode !== EmitterClickMode_js_1.EmitterClickMode.emitter) {
51
+ const modeEmitters = this.interactivityEmitters;
52
+ if (mode !== EmitterClickMode.emitter) {
56
53
  return;
57
54
  }
58
55
  let emittersModeOptions;
59
- if (modeEmitters && (0, engine_1.isArray)(modeEmitters.value)) {
56
+ if (isArray(modeEmitters.value)) {
60
57
  const minLength = 0;
61
58
  if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
62
59
  emittersModeOptions = [];
63
60
  const usedIndexes = [];
64
61
  for (let i = 0; i < modeEmitters.random.count; i++) {
65
- const idx = (0, engine_1.arrayRandomIndex)(modeEmitters.value);
62
+ const idx = arrayRandomIndex(modeEmitters.value);
66
63
  if (usedIndexes.includes(idx) && usedIndexes.length < modeEmitters.value.length) {
67
64
  i--;
68
65
  continue;
69
66
  }
70
67
  usedIndexes.push(idx);
71
- emittersModeOptions.push((0, engine_1.itemFromArray)(modeEmitters.value, idx));
68
+ const selectedOptions = itemFromArray(modeEmitters.value, idx);
69
+ if (!selectedOptions) {
70
+ continue;
71
+ }
72
+ emittersModeOptions.push(selectedOptions);
72
73
  }
73
74
  }
74
75
  else {
@@ -76,20 +77,17 @@ class Emitters {
76
77
  }
77
78
  }
78
79
  else {
79
- emittersModeOptions = modeEmitters?.value;
80
+ emittersModeOptions = modeEmitters.value;
80
81
  }
81
- const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
82
- void (0, engine_1.executeOnSingleOrMultiple)(emittersOptions, async (emitter) => {
82
+ const emittersOptions = emittersModeOptions, ePosition = this.container.interactivity.mouse.clickPosition;
83
+ void executeOnSingleOrMultiple(emittersOptions, async (emitter) => {
83
84
  await this.addEmitter(emitter, ePosition);
84
85
  });
85
86
  }
86
87
  async init() {
87
88
  this.emitters = this.container.actualOptions.emitters;
88
89
  this.interactivityEmitters = this.container.actualOptions.interactivity.modes.emitters;
89
- if (!this.emitters) {
90
- return;
91
- }
92
- if ((0, engine_1.isArray)(this.emitters)) {
90
+ if (isArray(this.emitters)) {
93
91
  for (const emitterOptions of this.emitters) {
94
92
  await this.addEmitter(emitterOptions);
95
93
  }
@@ -128,4 +126,3 @@ class Emitters {
128
126
  }
129
127
  }
130
128
  }
131
- exports.Emitters = Emitters;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};