@tsparticles/engine 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 (283) hide show
  1. package/794.min.js +2 -0
  2. package/794.min.js.LICENSE.txt +1 -0
  3. package/README.md +2 -5
  4. package/browser/Core/Canvas.js +18 -22
  5. package/browser/Core/Container.js +44 -169
  6. package/browser/Core/Engine.js +40 -61
  7. package/browser/Core/Particle.js +99 -58
  8. package/browser/Core/Particles.js +36 -25
  9. package/browser/Core/Utils/Constants.js +2 -2
  10. package/browser/Core/Utils/EventListeners.js +5 -250
  11. package/browser/Options/Classes/Options.js +7 -75
  12. package/browser/Options/Classes/Particles/ParticlesOptions.js +5 -11
  13. package/{esm/Options/Classes/Interactivity/Events → browser/Options/Classes}/ResizeEvent.js +1 -1
  14. package/browser/Utils/CanvasUtils.js +26 -83
  15. package/browser/Utils/ColorUtils.js +17 -2
  16. package/browser/Utils/MathUtils.js +3 -2
  17. package/browser/Utils/Utils.js +26 -33
  18. package/browser/exports.js +1 -21
  19. package/cjs/Core/Canvas.js +18 -22
  20. package/cjs/Core/Container.js +44 -169
  21. package/cjs/Core/Engine.js +40 -61
  22. package/cjs/Core/Particle.js +99 -58
  23. package/cjs/Core/Particles.js +36 -25
  24. package/cjs/Core/Utils/Constants.js +2 -2
  25. package/cjs/Core/Utils/EventListeners.js +5 -250
  26. package/cjs/Options/Classes/Options.js +7 -75
  27. package/cjs/Options/Classes/Particles/ParticlesOptions.js +5 -11
  28. package/cjs/Options/Classes/{Interactivity/Events/ResizeEvent.js → ResizeEvent.js} +1 -1
  29. package/cjs/Utils/CanvasUtils.js +26 -83
  30. package/cjs/Utils/ColorUtils.js +17 -2
  31. package/cjs/Utils/MathUtils.js +3 -2
  32. package/cjs/Utils/Utils.js +26 -33
  33. package/cjs/exports.js +1 -21
  34. package/dist_browser_Core_Container_js.js +6 -16
  35. package/esm/Core/Canvas.js +18 -22
  36. package/esm/Core/Container.js +44 -169
  37. package/esm/Core/Engine.js +40 -61
  38. package/esm/Core/Particle.js +99 -58
  39. package/esm/Core/Particles.js +36 -25
  40. package/esm/Core/Utils/Constants.js +2 -2
  41. package/esm/Core/Utils/EventListeners.js +5 -250
  42. package/esm/Options/Classes/Options.js +7 -75
  43. package/esm/Options/Classes/Particles/ParticlesOptions.js +5 -11
  44. package/{browser/Options/Classes/Interactivity/Events → esm/Options/Classes}/ResizeEvent.js +1 -1
  45. package/esm/Utils/CanvasUtils.js +26 -83
  46. package/esm/Utils/ColorUtils.js +17 -2
  47. package/esm/Utils/MathUtils.js +3 -2
  48. package/esm/Utils/Utils.js +26 -33
  49. package/esm/exports.js +1 -21
  50. package/package.json +1 -1
  51. package/report.html +1 -1
  52. package/tsparticles.engine.js +16 -208
  53. package/tsparticles.engine.min.js +1 -1
  54. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  55. package/types/Core/Canvas.d.ts +3 -0
  56. package/types/Core/Container.d.ts +4 -15
  57. package/types/Core/Engine.d.ts +4 -19
  58. package/types/Core/Interfaces/IContainerPlugin.d.ts +8 -1
  59. package/types/Core/Interfaces/IDrawParticleParams.d.ts +1 -1
  60. package/types/Core/Interfaces/IParticleOpacityData.d.ts +4 -0
  61. package/types/Core/Interfaces/IParticleRotateData.d.ts +4 -0
  62. package/types/Core/Interfaces/IParticleTransformValues.d.ts +4 -4
  63. package/types/Core/Interfaces/IParticleUpdater.d.ts +1 -1
  64. package/types/Core/Interfaces/IPlugin.d.ts +5 -1
  65. package/types/Core/Particle.d.ts +12 -2
  66. package/types/Core/Particles.d.ts +1 -5
  67. package/types/Core/Utils/Constants.d.ts +2 -2
  68. package/types/Core/Utils/EventListeners.d.ts +0 -14
  69. package/types/Options/Classes/Options.d.ts +2 -11
  70. package/types/Options/Classes/Particles/ParticlesOptions.d.ts +0 -2
  71. package/types/Options/Classes/ResizeEvent.d.ts +9 -0
  72. package/types/Options/Interfaces/IOptions.d.ts +2 -8
  73. package/types/Options/Interfaces/Particles/IParticlesOptions.d.ts +0 -3
  74. package/types/Types/CustomEventListener.d.ts +1 -1
  75. package/types/Types/EngineInitializers.d.ts +10 -0
  76. package/types/Utils/CanvasUtils.d.ts +6 -21
  77. package/types/Utils/EventDispatcher.d.ts +1 -1
  78. package/types/Utils/Utils.d.ts +4 -6
  79. package/types/export-types.d.ts +3 -19
  80. package/types/exports.d.ts +1 -21
  81. package/umd/Core/Canvas.js +17 -21
  82. package/umd/Core/Container.js +44 -169
  83. package/umd/Core/Engine.js +41 -62
  84. package/umd/Core/Particle.js +99 -58
  85. package/umd/Core/Particles.js +37 -26
  86. package/umd/Core/Utils/Constants.js +3 -3
  87. package/umd/Core/Utils/EventListeners.js +7 -252
  88. package/umd/Options/Classes/Options.js +7 -75
  89. package/umd/Options/Classes/Particles/ParticlesOptions.js +5 -11
  90. package/umd/Options/Classes/{Interactivity/Events/ResizeEvent.js → ResizeEvent.js} +2 -2
  91. package/umd/Utils/CanvasUtils.js +25 -82
  92. package/umd/Utils/ColorUtils.js +17 -2
  93. package/umd/Utils/MathUtils.js +3 -2
  94. package/umd/Utils/Utils.js +27 -36
  95. package/umd/exports.js +2 -22
  96. package/638.min.js +0 -2
  97. package/638.min.js.LICENSE.txt +0 -1
  98. package/browser/Core/Utils/ExternalInteractorBase.js +0 -7
  99. package/browser/Core/Utils/InteractionManager.js +0 -60
  100. package/browser/Core/Utils/ParticlesInteractorBase.js +0 -7
  101. package/browser/Enums/InteractivityDetect.js +0 -6
  102. package/browser/Enums/Modes/ResponsiveMode.js +0 -5
  103. package/browser/Enums/Modes/ThemeMode.js +0 -6
  104. package/browser/Enums/Types/DivType.js +0 -5
  105. package/browser/Enums/Types/InteractorType.js +0 -5
  106. package/browser/Options/Classes/Interactivity/Events/ClickEvent.js +0 -18
  107. package/browser/Options/Classes/Interactivity/Events/DivEvent.js +0 -27
  108. package/browser/Options/Classes/Interactivity/Events/Events.js +0 -30
  109. package/browser/Options/Classes/Interactivity/Events/HoverEvent.js +0 -21
  110. package/browser/Options/Classes/Interactivity/Events/Parallax.js +0 -22
  111. package/browser/Options/Classes/Interactivity/Interactivity.js +0 -22
  112. package/browser/Options/Classes/Interactivity/Modes/Modes.js +0 -25
  113. package/browser/Options/Classes/ManualParticle.js +0 -21
  114. package/browser/Options/Classes/Responsive.js +0 -29
  115. package/browser/Options/Classes/Theme/Theme.js +0 -21
  116. package/browser/Options/Classes/Theme/ThemeDefault.js +0 -23
  117. package/browser/Options/Interfaces/Interactivity/Events/IEvents.js +0 -1
  118. package/browser/Options/Interfaces/Interactivity/Events/IHoverEvent.js +0 -1
  119. package/browser/Options/Interfaces/Interactivity/Events/IParallax.js +0 -1
  120. package/browser/Options/Interfaces/Interactivity/IInteractivity.js +0 -1
  121. package/browser/Options/Interfaces/Interactivity/Modes/IModeDiv.js +0 -1
  122. package/browser/Options/Interfaces/Interactivity/Modes/IModes.js +0 -1
  123. package/browser/Options/Interfaces/Theme/ITheme.js +0 -1
  124. package/browser/Options/Interfaces/Theme/IThemeDefault.js +0 -1
  125. package/cjs/Core/Interfaces/IContainerInteractivity.js +0 -1
  126. package/cjs/Core/Interfaces/IExternalInteractor.js +0 -1
  127. package/cjs/Core/Interfaces/IInteractor.js +0 -1
  128. package/cjs/Core/Interfaces/IMouseData.js +0 -1
  129. package/cjs/Core/Interfaces/IParticlesInteractor.js +0 -1
  130. package/cjs/Core/Utils/ExternalInteractorBase.js +0 -7
  131. package/cjs/Core/Utils/InteractionManager.js +0 -60
  132. package/cjs/Core/Utils/ParticlesInteractorBase.js +0 -7
  133. package/cjs/Enums/InteractivityDetect.js +0 -6
  134. package/cjs/Enums/Modes/ResponsiveMode.js +0 -5
  135. package/cjs/Enums/Modes/ThemeMode.js +0 -6
  136. package/cjs/Enums/Types/DivType.js +0 -5
  137. package/cjs/Enums/Types/InteractorType.js +0 -5
  138. package/cjs/Options/Classes/Interactivity/Events/ClickEvent.js +0 -18
  139. package/cjs/Options/Classes/Interactivity/Events/DivEvent.js +0 -27
  140. package/cjs/Options/Classes/Interactivity/Events/Events.js +0 -30
  141. package/cjs/Options/Classes/Interactivity/Events/HoverEvent.js +0 -21
  142. package/cjs/Options/Classes/Interactivity/Events/Parallax.js +0 -22
  143. package/cjs/Options/Classes/Interactivity/Interactivity.js +0 -22
  144. package/cjs/Options/Classes/Interactivity/Modes/Modes.js +0 -25
  145. package/cjs/Options/Classes/ManualParticle.js +0 -21
  146. package/cjs/Options/Classes/Responsive.js +0 -29
  147. package/cjs/Options/Classes/Theme/Theme.js +0 -21
  148. package/cjs/Options/Classes/Theme/ThemeDefault.js +0 -23
  149. package/cjs/Options/Interfaces/IManualParticle.js +0 -1
  150. package/cjs/Options/Interfaces/IResponsive.js +0 -1
  151. package/cjs/Options/Interfaces/Interactivity/Events/IClickEvent.js +0 -1
  152. package/cjs/Options/Interfaces/Interactivity/Events/IDivEvent.js +0 -1
  153. package/cjs/Options/Interfaces/Interactivity/Events/IEvents.js +0 -1
  154. package/cjs/Options/Interfaces/Interactivity/Events/IHoverEvent.js +0 -1
  155. package/cjs/Options/Interfaces/Interactivity/Events/IParallax.js +0 -1
  156. package/cjs/Options/Interfaces/Interactivity/IInteractivity.js +0 -1
  157. package/cjs/Options/Interfaces/Interactivity/Modes/IModeDiv.js +0 -1
  158. package/cjs/Options/Interfaces/Interactivity/Modes/IModes.js +0 -1
  159. package/cjs/Options/Interfaces/Theme/ITheme.js +0 -1
  160. package/cjs/Options/Interfaces/Theme/IThemeDefault.js +0 -1
  161. package/esm/Core/Interfaces/IContainerInteractivity.js +0 -1
  162. package/esm/Core/Interfaces/IExternalInteractor.js +0 -1
  163. package/esm/Core/Interfaces/IInteractor.js +0 -1
  164. package/esm/Core/Interfaces/IMouseData.js +0 -1
  165. package/esm/Core/Interfaces/IParticlesInteractor.js +0 -1
  166. package/esm/Core/Utils/ExternalInteractorBase.js +0 -7
  167. package/esm/Core/Utils/InteractionManager.js +0 -60
  168. package/esm/Core/Utils/ParticlesInteractorBase.js +0 -7
  169. package/esm/Enums/InteractivityDetect.js +0 -6
  170. package/esm/Enums/Modes/ResponsiveMode.js +0 -5
  171. package/esm/Enums/Modes/ThemeMode.js +0 -6
  172. package/esm/Enums/Types/DivType.js +0 -5
  173. package/esm/Enums/Types/InteractorType.js +0 -5
  174. package/esm/Options/Classes/Interactivity/Events/ClickEvent.js +0 -18
  175. package/esm/Options/Classes/Interactivity/Events/DivEvent.js +0 -27
  176. package/esm/Options/Classes/Interactivity/Events/Events.js +0 -30
  177. package/esm/Options/Classes/Interactivity/Events/HoverEvent.js +0 -21
  178. package/esm/Options/Classes/Interactivity/Events/Parallax.js +0 -22
  179. package/esm/Options/Classes/Interactivity/Interactivity.js +0 -22
  180. package/esm/Options/Classes/Interactivity/Modes/Modes.js +0 -25
  181. package/esm/Options/Classes/ManualParticle.js +0 -21
  182. package/esm/Options/Classes/Responsive.js +0 -29
  183. package/esm/Options/Classes/Theme/Theme.js +0 -21
  184. package/esm/Options/Classes/Theme/ThemeDefault.js +0 -23
  185. package/esm/Options/Interfaces/IManualParticle.js +0 -1
  186. package/esm/Options/Interfaces/IResponsive.js +0 -1
  187. package/esm/Options/Interfaces/Interactivity/Events/IClickEvent.js +0 -1
  188. package/esm/Options/Interfaces/Interactivity/Events/IDivEvent.js +0 -1
  189. package/esm/Options/Interfaces/Interactivity/Events/IEvents.js +0 -1
  190. package/esm/Options/Interfaces/Interactivity/Events/IHoverEvent.js +0 -1
  191. package/esm/Options/Interfaces/Interactivity/Events/IParallax.js +0 -1
  192. package/esm/Options/Interfaces/Interactivity/IInteractivity.js +0 -1
  193. package/esm/Options/Interfaces/Interactivity/Modes/IModeDiv.js +0 -1
  194. package/esm/Options/Interfaces/Interactivity/Modes/IModes.js +0 -1
  195. package/esm/Options/Interfaces/Theme/ITheme.js +0 -1
  196. package/esm/Options/Interfaces/Theme/IThemeDefault.js +0 -1
  197. package/types/Core/Interfaces/IContainerInteractivity.d.ts +0 -6
  198. package/types/Core/Interfaces/IExternalInteractor.d.ts +0 -12
  199. package/types/Core/Interfaces/IInteractor.d.ts +0 -16
  200. package/types/Core/Interfaces/IMouseData.d.ts +0 -9
  201. package/types/Core/Interfaces/IParticlesInteractor.d.ts +0 -7
  202. package/types/Core/Utils/ExternalInteractorBase.d.ts +0 -15
  203. package/types/Core/Utils/InteractionManager.d.ts +0 -17
  204. package/types/Core/Utils/ParticlesInteractorBase.d.ts +0 -15
  205. package/types/Enums/InteractivityDetect.d.ts +0 -5
  206. package/types/Enums/Modes/ResponsiveMode.d.ts +0 -4
  207. package/types/Enums/Modes/ThemeMode.d.ts +0 -5
  208. package/types/Enums/Types/DivType.d.ts +0 -4
  209. package/types/Enums/Types/InteractorType.d.ts +0 -4
  210. package/types/Options/Classes/Interactivity/Events/ClickEvent.d.ts +0 -10
  211. package/types/Options/Classes/Interactivity/Events/DivEvent.d.ts +0 -13
  212. package/types/Options/Classes/Interactivity/Events/Events.d.ts +0 -16
  213. package/types/Options/Classes/Interactivity/Events/HoverEvent.d.ts +0 -12
  214. package/types/Options/Classes/Interactivity/Events/Parallax.d.ts +0 -10
  215. package/types/Options/Classes/Interactivity/Events/ResizeEvent.d.ts +0 -9
  216. package/types/Options/Classes/Interactivity/Interactivity.d.ts +0 -16
  217. package/types/Options/Classes/Interactivity/Modes/Modes.d.ts +0 -12
  218. package/types/Options/Classes/ManualParticle.d.ts +0 -10
  219. package/types/Options/Classes/Responsive.d.ts +0 -12
  220. package/types/Options/Classes/Theme/Theme.d.ts +0 -12
  221. package/types/Options/Classes/Theme/ThemeDefault.d.ts +0 -11
  222. package/types/Options/Interfaces/IManualParticle.d.ts +0 -7
  223. package/types/Options/Interfaces/IResponsive.d.ts +0 -7
  224. package/types/Options/Interfaces/Interactivity/Events/IClickEvent.d.ts +0 -5
  225. package/types/Options/Interfaces/Interactivity/Events/IDivEvent.d.ts +0 -8
  226. package/types/Options/Interfaces/Interactivity/Events/IEvents.d.ts +0 -11
  227. package/types/Options/Interfaces/Interactivity/Events/IHoverEvent.d.ts +0 -7
  228. package/types/Options/Interfaces/Interactivity/Events/IParallax.d.ts +0 -5
  229. package/types/Options/Interfaces/Interactivity/IInteractivity.d.ts +0 -9
  230. package/types/Options/Interfaces/Interactivity/Modes/IModeDiv.d.ts +0 -4
  231. package/types/Options/Interfaces/Interactivity/Modes/IModes.d.ts +0 -1
  232. package/types/Options/Interfaces/Theme/ITheme.d.ts +0 -7
  233. package/types/Options/Interfaces/Theme/IThemeDefault.d.ts +0 -6
  234. package/umd/Core/Interfaces/IMouseData.js +0 -12
  235. package/umd/Core/Interfaces/IParticlesInteractor.js +0 -12
  236. package/umd/Core/Utils/ExternalInteractorBase.js +0 -21
  237. package/umd/Core/Utils/InteractionManager.js +0 -74
  238. package/umd/Core/Utils/ParticlesInteractorBase.js +0 -21
  239. package/umd/Enums/InteractivityDetect.js +0 -19
  240. package/umd/Enums/Modes/ResponsiveMode.js +0 -18
  241. package/umd/Enums/Modes/ThemeMode.js +0 -19
  242. package/umd/Enums/Types/DivType.js +0 -18
  243. package/umd/Enums/Types/InteractorType.js +0 -18
  244. package/umd/Options/Classes/Interactivity/Events/ClickEvent.js +0 -32
  245. package/umd/Options/Classes/Interactivity/Events/DivEvent.js +0 -41
  246. package/umd/Options/Classes/Interactivity/Events/Events.js +0 -44
  247. package/umd/Options/Classes/Interactivity/Events/HoverEvent.js +0 -35
  248. package/umd/Options/Classes/Interactivity/Events/Parallax.js +0 -36
  249. package/umd/Options/Classes/Interactivity/Interactivity.js +0 -36
  250. package/umd/Options/Classes/Interactivity/Modes/Modes.js +0 -39
  251. package/umd/Options/Classes/ManualParticle.js +0 -35
  252. package/umd/Options/Classes/Responsive.js +0 -43
  253. package/umd/Options/Classes/Theme/Theme.js +0 -35
  254. package/umd/Options/Classes/Theme/ThemeDefault.js +0 -37
  255. package/umd/Options/Interfaces/IManualParticle.js +0 -12
  256. package/umd/Options/Interfaces/IResponsive.js +0 -12
  257. package/umd/Options/Interfaces/Interactivity/Events/IClickEvent.js +0 -12
  258. package/umd/Options/Interfaces/Interactivity/Events/IDivEvent.js +0 -12
  259. package/umd/Options/Interfaces/Interactivity/Events/IEvents.js +0 -12
  260. package/umd/Options/Interfaces/Interactivity/Events/IHoverEvent.js +0 -12
  261. package/umd/Options/Interfaces/Interactivity/Events/IParallax.js +0 -12
  262. package/umd/Options/Interfaces/Interactivity/IInteractivity.js +0 -12
  263. package/umd/Options/Interfaces/Interactivity/Modes/IModeDiv.js +0 -12
  264. package/umd/Options/Interfaces/Interactivity/Modes/IModes.js +0 -12
  265. package/umd/Options/Interfaces/Theme/ITheme.js +0 -12
  266. package/umd/Options/Interfaces/Theme/IThemeDefault.js +0 -12
  267. /package/browser/Core/Interfaces/{IContainerInteractivity.js → IParticleOpacityData.js} +0 -0
  268. /package/browser/Core/Interfaces/{IExternalInteractor.js → IParticleRotateData.js} +0 -0
  269. /package/browser/Options/Interfaces/{Interactivity/Events/IResizeEvent.js → IResizeEvent.js} +0 -0
  270. /package/browser/{Core/Interfaces/IInteractor.js → Types/EngineInitializers.js} +0 -0
  271. /package/{browser/Core/Interfaces/IMouseData.js → cjs/Core/Interfaces/IParticleOpacityData.js} +0 -0
  272. /package/{browser/Core/Interfaces/IParticlesInteractor.js → cjs/Core/Interfaces/IParticleRotateData.js} +0 -0
  273. /package/cjs/Options/Interfaces/{Interactivity/Events/IResizeEvent.js → IResizeEvent.js} +0 -0
  274. /package/{browser/Options/Interfaces/IManualParticle.js → cjs/Types/EngineInitializers.js} +0 -0
  275. /package/{browser/Options/Interfaces/IResponsive.js → esm/Core/Interfaces/IParticleOpacityData.js} +0 -0
  276. /package/{browser/Options/Interfaces/Interactivity/Events/IClickEvent.js → esm/Core/Interfaces/IParticleRotateData.js} +0 -0
  277. /package/esm/Options/Interfaces/{Interactivity/Events/IResizeEvent.js → IResizeEvent.js} +0 -0
  278. /package/{browser/Options/Interfaces/Interactivity/Events/IDivEvent.js → esm/Types/EngineInitializers.js} +0 -0
  279. /package/types/Options/Interfaces/{Interactivity/Events/IResizeEvent.d.ts → IResizeEvent.d.ts} +0 -0
  280. /package/umd/Core/Interfaces/{IContainerInteractivity.js → IParticleOpacityData.js} +0 -0
  281. /package/umd/Core/Interfaces/{IExternalInteractor.js → IParticleRotateData.js} +0 -0
  282. /package/umd/Options/Interfaces/{Interactivity/Events/IResizeEvent.js → IResizeEvent.js} +0 -0
  283. /package/umd/{Core/Interfaces/IInteractor.js → Types/EngineInitializers.js} +0 -0
@@ -1,7 +1,8 @@
1
1
  import { clear, clearDrawPlugin, drawParticle, drawParticlePlugin, drawPlugin, paintBase, paintImage, } from "../Utils/CanvasUtils.js";
2
2
  import { cloneStyle, getFullScreenStyle, safeMatchMedia, safeMutationObserver } from "../Utils/Utils.js";
3
- import { defaultOpacity, defaultTransformValue, generatedAttribute, minimumSize, zIndexFactorOffset, } from "./Utils/Constants.js";
3
+ import { defaultTransformValue, generatedAttribute, minimumSize, zIndexFactorOffset } from "./Utils/Constants.js";
4
4
  import { getStyleFromHsl, getStyleFromRgb, rangeColorToHsl, rangeColorToRgb } from "../Utils/ColorUtils.js";
5
+ const fColorIndex = 0, sColorIndex = 1;
5
6
  function setTransformValue(factor, newFactor, key) {
6
7
  const newValue = newFactor[key];
7
8
  if (newValue !== undefined) {
@@ -40,6 +41,9 @@ function setStyle(canvas, style, important = false) {
40
41
  export class Canvas {
41
42
  constructor(container, engine) {
42
43
  this.container = container;
44
+ this._reusableColorStyles = {};
45
+ this._reusablePluginColors = [undefined, undefined];
46
+ this._reusableTransform = {};
43
47
  this._applyPostDrawUpdaters = particle => {
44
48
  for (const updater of this._postDrawUpdaters) {
45
49
  updater.afterDraw?.(particle);
@@ -83,7 +87,9 @@ export class Canvas {
83
87
  break;
84
88
  }
85
89
  }
86
- return [fColor, sColor];
90
+ this._reusablePluginColors[fColorIndex] = fColor;
91
+ this._reusablePluginColors[sColorIndex] = sColor;
92
+ return this._reusablePluginColors;
87
93
  };
88
94
  this._initStyle = () => {
89
95
  const element = this.element, options = this.container.actualOptions;
@@ -97,7 +103,7 @@ export class Canvas {
97
103
  this._resetOriginalStyle();
98
104
  }
99
105
  for (const key in options.style) {
100
- if (!key || !Object.prototype.hasOwnProperty.call(options.style, key)) {
106
+ if (!key || !Object.hasOwn(options.style, key)) {
101
107
  continue;
102
108
  }
103
109
  const value = options.style[key];
@@ -178,7 +184,7 @@ export class Canvas {
178
184
  }
179
185
  clear() {
180
186
  let pluginHandled = false;
181
- for (const plugin of this.container.plugins.values()) {
187
+ for (const plugin of this.container.plugins) {
182
188
  if (!pluginHandled && plugin.canvasClear) {
183
189
  pluginHandled = plugin.canvasClear();
184
190
  }
@@ -230,22 +236,12 @@ export class Canvas {
230
236
  if (!fColor && !sColor) {
231
237
  return;
232
238
  }
233
- const container = this.container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity, strokeOpacity = particle.strokeOpacity ?? opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, getFillStyle = () => {
234
- if (!fColor) {
235
- return;
236
- }
237
- return getStyleFromHsl(fColor, container.hdr, zOpacity);
238
- }, colorStyles = {
239
- fill: getFillStyle(),
240
- }, getStrokestyle = () => {
241
- if (!sColor) {
242
- return colorStyles.fill;
243
- }
244
- return getStyleFromHsl(sColor, container.hdr, zStrokeOpacity);
245
- };
246
- colorStyles.stroke = getStrokestyle();
239
+ const container = this.container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, { opacity, strokeOpacity } = particle.getOpacity(), transform = this._reusableTransform, colorStyles = this._reusableColorStyles, fill = fColor ? getStyleFromHsl(fColor, container.hdr, opacity) : undefined, stroke = sColor ? getStyleFromHsl(sColor, container.hdr, strokeOpacity) : fill;
240
+ transform.a = transform.b = transform.c = transform.d = undefined;
241
+ colorStyles.fill = fill;
242
+ colorStyles.stroke = stroke;
247
243
  this.draw((context) => {
248
- this._applyPreDrawUpdaters(context, particle, radius, zOpacity, colorStyles, transform);
244
+ this._applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
249
245
  drawParticle({
250
246
  container,
251
247
  context,
@@ -253,7 +249,7 @@ export class Canvas {
253
249
  delta,
254
250
  colorStyles,
255
251
  radius: radius * zIndexFactor ** zIndexOptions.sizeRate,
256
- opacity: zOpacity,
252
+ opacity: opacity,
257
253
  transform,
258
254
  });
259
255
  });
@@ -326,7 +322,7 @@ export class Canvas {
326
322
  }
327
323
  initPlugins() {
328
324
  this._resizePlugins = [];
329
- for (const plugin of this.container.plugins.values()) {
325
+ for (const plugin of this.container.plugins) {
330
326
  if (plugin.resize) {
331
327
  this._resizePlugins.push(plugin);
332
328
  }
@@ -384,7 +380,7 @@ export class Canvas {
384
380
  }
385
381
  paint() {
386
382
  let handled = false;
387
- for (const plugin of this.container.plugins.values()) {
383
+ for (const plugin of this.container.plugins) {
388
384
  if (handled) {
389
385
  break;
390
386
  }
@@ -1,5 +1,5 @@
1
1
  import { animate, cancelAnimation, getRangeValue } from "../Utils/MathUtils.js";
2
- import { clickRadius, defaultFps, defaultFpsLimit, millisecondsToSeconds, minCoordinate, minFpsLimit, removeDeleteCount, removeMinIndex, touchEndLengthOffset, } from "./Utils/Constants.js";
2
+ import { defaultFps, defaultFpsLimit, millisecondsToSeconds, minFpsLimit, removeDeleteCount, removeMinIndex, } from "./Utils/Constants.js";
3
3
  import { Canvas } from "./Canvas.js";
4
4
  import { EventListeners } from "./Utils/EventListeners.js";
5
5
  import { EventType } from "../Enums/Types/EventType.js";
@@ -8,15 +8,12 @@ import { Particles } from "./Particles.js";
8
8
  import { Retina } from "./Retina.js";
9
9
  import { getLogger } from "../Utils/LogUtils.js";
10
10
  import { loadOptions } from "../Utils/OptionsUtils.js";
11
- import { safeIntersectionObserver } from "../Utils/Utils.js";
12
11
  function guardCheck(container) {
13
12
  return !container.destroyed;
14
13
  }
15
- function initDelta(value, fpsLimit = defaultFps, smooth = false) {
16
- return {
17
- value,
18
- factor: smooth ? defaultFps / fpsLimit : (defaultFps * value) / millisecondsToSeconds,
19
- };
14
+ function updateDelta(delta, value, fpsLimit = defaultFps, smooth = false) {
15
+ delta.value = value;
16
+ delta.factor = smooth ? defaultFps / fpsLimit : (defaultFps * value) / millisecondsToSeconds;
20
17
  }
21
18
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
22
19
  const options = new Options(engine, container);
@@ -25,22 +22,7 @@ function loadContainerOptions(engine, container, ...sourceOptionsArr) {
25
22
  }
26
23
  export class Container {
27
24
  constructor(engine, id, sourceOptions) {
28
- this._intersectionManager = entries => {
29
- if (!guardCheck(this) || !this.actualOptions.pauseOnOutsideViewport) {
30
- return;
31
- }
32
- for (const entry of entries) {
33
- if (entry.target !== this.interactivity.element) {
34
- continue;
35
- }
36
- if (entry.isIntersecting) {
37
- this.play();
38
- }
39
- else {
40
- this.pause();
41
- }
42
- }
43
- };
25
+ this._delta = { value: 0, factor: 0 };
44
26
  this._nextFrame = (timestamp) => {
45
27
  try {
46
28
  if (!this._smooth &&
@@ -50,14 +32,14 @@ export class Container {
50
32
  return;
51
33
  }
52
34
  this._lastFrameTime ??= timestamp;
53
- const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
54
- this.addLifeTime(delta.value);
35
+ updateDelta(this._delta, timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
36
+ this.addLifeTime(this._delta.value);
55
37
  this._lastFrameTime = timestamp;
56
- if (delta.value > millisecondsToSeconds) {
38
+ if (this._delta.value > millisecondsToSeconds) {
57
39
  this.draw(false);
58
40
  return;
59
41
  }
60
- this.canvas.drawParticles(delta);
42
+ this.canvas.drawParticles(this._delta);
61
43
  if (!this.alive()) {
62
44
  this.destroy();
63
45
  return;
@@ -85,28 +67,18 @@ export class Container {
85
67
  this._lastFrameTime = 0;
86
68
  this.zLayers = 100;
87
69
  this.pageHidden = false;
88
- this._clickHandlers = new Map();
89
70
  this._sourceOptions = sourceOptions;
90
71
  this._initialSourceOptions = sourceOptions;
91
72
  this.retina = new Retina(this);
92
73
  this.canvas = new Canvas(this, this._engine);
93
74
  this.particles = new Particles(this._engine, this);
94
75
  this.pathGenerators = new Map();
95
- this.interactivity = {
96
- mouse: {
97
- clicking: false,
98
- inside: false,
99
- },
100
- };
101
- this.plugins = new Map();
76
+ this.plugins = [];
102
77
  this.effectDrawers = new Map();
103
78
  this.shapeDrawers = new Map();
104
79
  this._options = loadContainerOptions(this._engine, this);
105
80
  this.actualOptions = loadContainerOptions(this._engine, this);
106
81
  this._eventListeners = new EventListeners(this);
107
- this._intersectionObserver = safeIntersectionObserver(entries => {
108
- this._intersectionManager(entries);
109
- });
110
82
  this._engine.dispatchEvent(EventType.containerBuilt, { container: this });
111
83
  }
112
84
  get animationStatus() {
@@ -118,77 +90,6 @@ export class Container {
118
90
  get sourceOptions() {
119
91
  return this._sourceOptions;
120
92
  }
121
- addClickHandler(callback) {
122
- if (!guardCheck(this)) {
123
- return;
124
- }
125
- const el = this.interactivity.element;
126
- if (!el) {
127
- return;
128
- }
129
- const clickOrTouchHandler = (e, pos, radius) => {
130
- if (!guardCheck(this)) {
131
- return;
132
- }
133
- const pxRatio = this.retina.pixelRatio, posRetina = {
134
- x: pos.x * pxRatio,
135
- y: pos.y * pxRatio,
136
- }, particles = this.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
137
- callback(e, particles);
138
- }, clickHandler = (e) => {
139
- if (!guardCheck(this)) {
140
- return;
141
- }
142
- const mouseEvent = e, pos = {
143
- x: mouseEvent.offsetX || mouseEvent.clientX,
144
- y: mouseEvent.offsetY || mouseEvent.clientY,
145
- };
146
- clickOrTouchHandler(e, pos, clickRadius);
147
- }, touchStartHandler = () => {
148
- if (!guardCheck(this)) {
149
- return;
150
- }
151
- touched = true;
152
- touchMoved = false;
153
- }, touchMoveHandler = () => {
154
- if (!guardCheck(this)) {
155
- return;
156
- }
157
- touchMoved = true;
158
- }, touchEndHandler = (e) => {
159
- if (!guardCheck(this)) {
160
- return;
161
- }
162
- if (touched && !touchMoved) {
163
- const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - touchEndLengthOffset];
164
- if (!lastTouch) {
165
- return;
166
- }
167
- const element = this.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
168
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
169
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
170
- };
171
- clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
172
- }
173
- touched = false;
174
- touchMoved = false;
175
- }, touchCancelHandler = () => {
176
- if (!guardCheck(this)) {
177
- return;
178
- }
179
- touched = false;
180
- touchMoved = false;
181
- };
182
- let touched = false, touchMoved = false;
183
- this._clickHandlers.set("click", clickHandler);
184
- this._clickHandlers.set("touchstart", touchStartHandler);
185
- this._clickHandlers.set("touchmove", touchMoveHandler);
186
- this._clickHandlers.set("touchend", touchEndHandler);
187
- this._clickHandlers.set("touchcancel", touchCancelHandler);
188
- for (const [key, handler] of this._clickHandlers) {
189
- el.addEventListener(key, handler);
190
- }
191
- }
192
93
  addLifeTime(value) {
193
94
  this._lifeTime += value;
194
95
  }
@@ -202,39 +103,29 @@ export class Container {
202
103
  alive() {
203
104
  return !this._duration || this._lifeTime <= this._duration;
204
105
  }
205
- clearClickHandlers() {
206
- if (!guardCheck(this)) {
207
- return;
208
- }
209
- for (const [key, handler] of this._clickHandlers) {
210
- this.interactivity.element?.removeEventListener(key, handler);
211
- }
212
- this._clickHandlers.clear();
213
- }
214
106
  destroy(remove = true) {
215
107
  if (!guardCheck(this)) {
216
108
  return;
217
109
  }
218
110
  this.stop();
219
- this.clearClickHandlers();
220
111
  this.particles.destroy();
221
112
  this.canvas.destroy();
222
113
  for (const effectDrawer of this.effectDrawers.values()) {
223
114
  effectDrawer.destroy?.(this);
224
115
  }
116
+ this.effectDrawers.clear();
225
117
  for (const shapeDrawer of this.shapeDrawers.values()) {
226
118
  shapeDrawer.destroy?.(this);
227
119
  }
228
- for (const key of this.effectDrawers.keys()) {
229
- this.effectDrawers.delete(key);
230
- }
231
- for (const key of this.shapeDrawers.keys()) {
232
- this.shapeDrawers.delete(key);
120
+ this.shapeDrawers.clear();
121
+ for (const plugin of this.plugins) {
122
+ plugin.destroy?.();
233
123
  }
124
+ this.plugins.length = 0;
234
125
  this._engine.clearPlugins(this);
235
126
  this.destroyed = true;
236
127
  if (remove) {
237
- const mainArr = this._engine.items, idx = mainArr.findIndex(t => t === this);
128
+ const mainArr = this._engine.items, idx = mainArr.indexOf(this);
238
129
  if (idx >= removeMinIndex) {
239
130
  mainArr.splice(idx, removeDeleteCount);
240
131
  }
@@ -258,7 +149,7 @@ export class Container {
258
149
  });
259
150
  }
260
151
  async export(type, options = {}) {
261
- for (const plugin of this.plugins.values()) {
152
+ for (const plugin of this.plugins) {
262
153
  if (!plugin.export) {
263
154
  continue;
264
155
  }
@@ -271,15 +162,6 @@ export class Container {
271
162
  getLogger().error(`Export plugin with type ${type} not found`);
272
163
  return undefined;
273
164
  }
274
- handleClickMode(mode) {
275
- if (!guardCheck(this)) {
276
- return;
277
- }
278
- this.particles.handleClickMode(mode);
279
- for (const plugin of this.plugins.values()) {
280
- plugin.handleClickMode?.(mode);
281
- }
282
- }
283
165
  async init() {
284
166
  if (!guardCheck(this)) {
285
167
  return;
@@ -298,12 +180,21 @@ export class Container {
298
180
  this.shapeDrawers.set(type, drawer);
299
181
  }
300
182
  }
183
+ const allContainerPlugins = new Map();
184
+ for (const plugin of this._engine.plugins) {
185
+ const containerPlugin = await plugin.getPlugin(this);
186
+ if (containerPlugin.preInit) {
187
+ await containerPlugin.preInit();
188
+ }
189
+ allContainerPlugins.set(plugin, containerPlugin);
190
+ }
301
191
  await this.particles.initPlugins();
302
192
  this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
303
193
  this.actualOptions = loadContainerOptions(this._engine, this, this._options);
304
- const availablePlugins = await this._engine.getAvailablePlugins(this);
305
- for (const [id, plugin] of availablePlugins) {
306
- this.plugins.set(id, plugin);
194
+ for (const [plugin, containerPlugin] of allContainerPlugins) {
195
+ if (plugin.needsPlugin(this.actualOptions)) {
196
+ this.plugins.push(containerPlugin);
197
+ }
307
198
  }
308
199
  this.retina.init();
309
200
  this.canvas.init();
@@ -318,30 +209,23 @@ export class Container {
318
209
  this._lifeTime = 0;
319
210
  this.fpsLimit = fpsLimit > minFpsLimit ? fpsLimit : defaultFpsLimit;
320
211
  this._smooth = smooth;
212
+ for (const plugin of this.plugins) {
213
+ await plugin.init?.();
214
+ }
321
215
  for (const drawer of this.effectDrawers.values()) {
322
216
  await drawer.init?.(this);
323
217
  }
324
218
  for (const drawer of this.shapeDrawers.values()) {
325
219
  await drawer.init?.(this);
326
220
  }
327
- for (const plugin of this.plugins.values()) {
328
- await plugin.init?.();
329
- }
330
221
  this._engine.dispatchEvent(EventType.containerInit, { container: this });
331
222
  await this.particles.init();
332
223
  this.particles.setDensity();
333
- for (const plugin of this.plugins.values()) {
224
+ for (const plugin of this.plugins) {
334
225
  plugin.particlesSetup?.();
335
226
  }
336
227
  this._engine.dispatchEvent(EventType.particlesSetup, { container: this });
337
228
  }
338
- async loadTheme(name) {
339
- if (!guardCheck(this)) {
340
- return;
341
- }
342
- this._currentTheme = name;
343
- await this.refresh();
344
- }
345
229
  pause() {
346
230
  if (!guardCheck(this)) {
347
231
  return;
@@ -353,7 +237,7 @@ export class Container {
353
237
  if (this._paused) {
354
238
  return;
355
239
  }
356
- for (const plugin of this.plugins.values()) {
240
+ for (const plugin of this.plugins) {
357
241
  plugin.pause?.();
358
242
  }
359
243
  if (!this.pageHidden) {
@@ -374,7 +258,7 @@ export class Container {
374
258
  this._paused = false;
375
259
  }
376
260
  if (needsUpdate) {
377
- for (const plugin of this.plugins.values()) {
261
+ for (const plugin of this.plugins) {
378
262
  if (plugin.play) {
379
263
  plugin.play();
380
264
  }
@@ -409,10 +293,7 @@ export class Container {
409
293
  await new Promise(resolve => {
410
294
  const start = async () => {
411
295
  this._eventListeners.addListeners();
412
- if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
413
- this._intersectionObserver.observe(this.interactivity.element);
414
- }
415
- for (const plugin of this.plugins.values()) {
296
+ for (const plugin of this.plugins) {
416
297
  await plugin.start?.();
417
298
  }
418
299
  this._engine.dispatchEvent(EventType.containerStarted, { container: this });
@@ -436,26 +317,20 @@ export class Container {
436
317
  this.pause();
437
318
  this.particles.clear();
438
319
  this.canvas.stop();
439
- if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
440
- this._intersectionObserver.unobserve(this.interactivity.element);
441
- }
442
- for (const plugin of this.plugins.values()) {
320
+ for (const plugin of this.plugins) {
443
321
  plugin.stop?.();
444
322
  }
445
- for (const key of this.plugins.keys()) {
446
- this.plugins.delete(key);
447
- }
323
+ this.plugins.length = 0;
448
324
  this._sourceOptions = this._options;
449
325
  this._engine.dispatchEvent(EventType.containerStopped, { container: this });
450
326
  }
451
327
  updateActualOptions() {
452
- this.actualOptions.responsive = [];
453
- const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
454
- this.actualOptions.setTheme(this._currentTheme);
455
- if (this._responsiveMaxWidth === newMaxWidth) {
456
- return false;
328
+ let refresh = false;
329
+ for (const plugin of this.plugins) {
330
+ if (plugin.updateActualOptions) {
331
+ refresh = plugin.updateActualOptions() || refresh;
332
+ }
457
333
  }
458
- this._responsiveMaxWidth = newMaxWidth;
459
- return true;
334
+ return refresh;
460
335
  }
461
336
  }
@@ -1,17 +1,10 @@
1
1
  import { canvasFirstIndex, canvasTag, generatedAttribute, generatedFalse, generatedTrue, loadMinIndex, loadRandomFactor, none, one, removeDeleteCount, } from "./Utils/Constants.js";
2
- import { itemFromSingleOrMultiple, safeDocument } from "../Utils/Utils.js";
2
+ import { getItemsFromInitializer, itemFromSingleOrMultiple, safeDocument } from "../Utils/Utils.js";
3
3
  import { EventDispatcher } from "../Utils/EventDispatcher.js";
4
4
  import { EventType } from "../Enums/Types/EventType.js";
5
5
  import { getLogger } from "../Utils/LogUtils.js";
6
6
  import { getRandom } from "../Utils/MathUtils.js";
7
- async function getItemsFromInitializer(container, map, initializers, force = false) {
8
- let res = map.get(container);
9
- if (!res || force) {
10
- res = await Promise.all([...initializers.values()].map(t => t(container)));
11
- map.set(container, res);
12
- }
13
- return res;
14
- }
7
+ const fullPercent = "100%";
15
8
  async function getDataFromUrl(data) {
16
9
  const url = itemFromSingleOrMultiple(data.url, data.index);
17
10
  if (!url) {
@@ -25,6 +18,7 @@ async function getDataFromUrl(data) {
25
18
  return data.fallback;
26
19
  }
27
20
  const getCanvasFromContainer = (domContainer) => {
21
+ const documentSafe = safeDocument();
28
22
  let canvasEl;
29
23
  if (domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag) {
30
24
  canvasEl = domContainer;
@@ -37,28 +31,24 @@ const getCanvasFromContainer = (domContainer) => {
37
31
  canvasEl.dataset[generatedAttribute] = generatedFalse;
38
32
  }
39
33
  else {
40
- canvasEl = safeDocument().createElement(canvasTag);
34
+ canvasEl = documentSafe.createElement(canvasTag);
41
35
  canvasEl.dataset[generatedAttribute] = generatedTrue;
42
36
  domContainer.appendChild(canvasEl);
43
37
  }
44
38
  }
45
- const fullPercent = "100%";
46
- if (!canvasEl.style.width) {
47
- canvasEl.style.width = fullPercent;
48
- }
49
- if (!canvasEl.style.height) {
50
- canvasEl.style.height = fullPercent;
51
- }
39
+ canvasEl.style.width ||= fullPercent;
40
+ canvasEl.style.height ||= fullPercent;
52
41
  return canvasEl;
53
42
  }, getDomContainer = (id, source) => {
54
- let domContainer = source ?? safeDocument().getElementById(id);
43
+ const documentSafe = safeDocument();
44
+ let domContainer = source ?? documentSafe.getElementById(id);
55
45
  if (domContainer) {
56
46
  return domContainer;
57
47
  }
58
- domContainer = safeDocument().createElement("div");
48
+ domContainer = documentSafe.createElement("div");
59
49
  domContainer.id = id;
60
50
  domContainer.dataset[generatedAttribute] = generatedTrue;
61
- safeDocument().body.append(domContainer);
51
+ documentSafe.body.append(domContainer);
62
52
  return domContainer;
63
53
  };
64
54
  export class Engine {
@@ -72,11 +62,9 @@ export class Engine {
72
62
  this.colorManagers = new Map();
73
63
  this.easingFunctions = new Map();
74
64
  this._initializers = {
75
- interactors: new Map(),
76
65
  movers: new Map(),
77
66
  updaters: new Map(),
78
67
  };
79
- this.interactors = new Map();
80
68
  this.movers = new Map();
81
69
  this.updaters = new Map();
82
70
  this.presets = new Map();
@@ -95,7 +83,7 @@ export class Engine {
95
83
  return this._domArray;
96
84
  }
97
85
  get version() {
98
- return "4.0.0-alpha.2";
86
+ return "4.0.0-alpha.4";
99
87
  }
100
88
  addColorManager(manager) {
101
89
  this.colorManagers.set(manager.key, manager);
@@ -120,9 +108,6 @@ export class Engine {
120
108
  addEventListener(type, listener) {
121
109
  this._eventDispatcher.addEventListener(type, listener);
122
110
  }
123
- addInteractor(name, interactorInitializer) {
124
- this._initializers.interactors.set(name, interactorInitializer);
125
- }
126
111
  addMover(name, moverInitializer) {
127
112
  this._initializers.movers.set(name, moverInitializer);
128
113
  }
@@ -164,35 +149,16 @@ export class Engine {
164
149
  clearPlugins(container) {
165
150
  this.updaters.delete(container);
166
151
  this.movers.delete(container);
167
- this.interactors.delete(container);
168
152
  }
169
153
  dispatchEvent(type, args) {
170
154
  this._eventDispatcher.dispatchEvent(type, args);
171
155
  }
172
- dom() {
173
- return this.items;
174
- }
175
- domItem(index) {
176
- return this.item(index);
177
- }
178
- async getAvailablePlugins(container) {
179
- const res = new Map();
180
- for (const plugin of this.plugins) {
181
- if (plugin.needsPlugin(container.actualOptions)) {
182
- res.set(plugin.id, await plugin.getPlugin(container));
183
- }
184
- }
185
- return res;
186
- }
187
156
  getEasing(name) {
188
157
  return this.easingFunctions.get(name) ?? ((value) => value);
189
158
  }
190
159
  getEffectDrawer(type) {
191
160
  return this.effectDrawers.get(type);
192
161
  }
193
- async getInteractors(container, force = false) {
194
- return getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
195
- }
196
162
  async getMovers(container, force = false) {
197
163
  return getItemsFromInitializer(container, this.movers, this._initializers.movers, force);
198
164
  }
@@ -221,10 +187,36 @@ export class Engine {
221
187
  if (this._initialized) {
222
188
  return;
223
189
  }
224
- for (const loadPromise of this._loadPromises) {
225
- await loadPromise(this);
190
+ const executed = new Set(), allLoaders = new Set(this._loadPromises), stack = [...allLoaders];
191
+ while (stack.length) {
192
+ const loader = stack.shift();
193
+ if (!loader) {
194
+ continue;
195
+ }
196
+ if (executed.has(loader)) {
197
+ continue;
198
+ }
199
+ executed.add(loader);
200
+ const inner = [], origRegister = this.register.bind(this);
201
+ this.register = (...loaders) => {
202
+ inner.push(...loaders);
203
+ for (const loader of loaders) {
204
+ allLoaders.add(loader);
205
+ }
206
+ };
207
+ try {
208
+ await loader(this);
209
+ }
210
+ finally {
211
+ this.register = origRegister;
212
+ }
213
+ stack.unshift(...inner);
214
+ this._loadPromises.delete(loader);
226
215
  }
227
216
  this._loadPromises.clear();
217
+ for (const loader of allLoaders) {
218
+ this._loadPromises.add(loader);
219
+ }
228
220
  this._initialized = true;
229
221
  }
230
222
  item(index) {
@@ -237,6 +229,7 @@ export class Engine {
237
229
  }
238
230
  async load(params) {
239
231
  await this.init();
232
+ this._loadPromises.clear();
240
233
  const { Container } = await import("./Container.js"), id = params.id ??
241
234
  params.element?.id ??
242
235
  `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container(this, id, currentOptions);
@@ -255,11 +248,6 @@ export class Engine {
255
248
  await newItem.start();
256
249
  return newItem;
257
250
  }
258
- loadOptions(options, sourceOptions) {
259
- this.plugins.forEach(plugin => {
260
- plugin.loadOptions(options, sourceOptions);
261
- });
262
- }
263
251
  loadParticlesOptions(container, options, ...sourceOptions) {
264
252
  const updaters = this.updaters.get(container);
265
253
  if (!updaters) {
@@ -284,13 +272,4 @@ export class Engine {
284
272
  removeEventListener(type, listener) {
285
273
  this._eventDispatcher.removeEventListener(type, listener);
286
274
  }
287
- setOnClickHandler(callback) {
288
- const { items } = this;
289
- if (!items.length) {
290
- throw new Error("Click handlers can only be set after calling tsParticles.load()");
291
- }
292
- items.forEach(item => {
293
- item.addClickHandler(callback);
294
- });
295
- }
296
275
  }