@tsparticles/plugin-interactivity 4.0.0-alpha.14

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 (168) hide show
  1. package/19.min.js +1 -0
  2. package/74.min.js +1 -0
  3. package/LICENSE +21 -0
  4. package/README.md +74 -0
  5. package/browser/DivType.js +5 -0
  6. package/browser/ExternalInteractorBase.js +8 -0
  7. package/browser/IExternalInteractor.js +1 -0
  8. package/browser/IInteractivityData.js +1 -0
  9. package/browser/IInteractor.js +1 -0
  10. package/browser/IMouseData.js +1 -0
  11. package/browser/IParticlesInteractor.js +1 -0
  12. package/browser/InteractionManager.js +212 -0
  13. package/browser/InteractivityConstants.js +1 -0
  14. package/browser/InteractivityDetect.js +6 -0
  15. package/browser/InteractivityEventListeners.js +244 -0
  16. package/browser/InteractivityPlugin.js +49 -0
  17. package/browser/InteractivityPluginInstance.js +55 -0
  18. package/browser/InteractorType.js +5 -0
  19. package/browser/Options/Classes/Events/ClickEvent.js +20 -0
  20. package/browser/Options/Classes/Events/DivEvent.js +31 -0
  21. package/browser/Options/Classes/Events/Events.js +29 -0
  22. package/browser/Options/Classes/Events/HoverEvent.js +20 -0
  23. package/browser/Options/Classes/Interactivity.js +25 -0
  24. package/browser/Options/Classes/Modes/Modes.js +27 -0
  25. package/browser/Options/Interfaces/Events/IClickEvent.js +1 -0
  26. package/browser/Options/Interfaces/Events/IDivEvent.js +1 -0
  27. package/browser/Options/Interfaces/Events/IEvents.js +1 -0
  28. package/browser/Options/Interfaces/Events/IHoverEvent.js +1 -0
  29. package/browser/Options/Interfaces/IInteractivity.js +1 -0
  30. package/browser/Options/Interfaces/Modes/IModeDiv.js +1 -0
  31. package/browser/Options/Interfaces/Modes/IModes.js +1 -0
  32. package/browser/ParticlesInteractorBase.js +8 -0
  33. package/browser/index.js +38 -0
  34. package/browser/package.json +1 -0
  35. package/browser/types.js +1 -0
  36. package/browser/utils.js +32 -0
  37. package/cjs/DivType.js +5 -0
  38. package/cjs/ExternalInteractorBase.js +8 -0
  39. package/cjs/IExternalInteractor.js +1 -0
  40. package/cjs/IInteractivityData.js +1 -0
  41. package/cjs/IInteractor.js +1 -0
  42. package/cjs/IMouseData.js +1 -0
  43. package/cjs/IParticlesInteractor.js +1 -0
  44. package/cjs/InteractionManager.js +212 -0
  45. package/cjs/InteractivityConstants.js +1 -0
  46. package/cjs/InteractivityDetect.js +6 -0
  47. package/cjs/InteractivityEventListeners.js +244 -0
  48. package/cjs/InteractivityPlugin.js +49 -0
  49. package/cjs/InteractivityPluginInstance.js +55 -0
  50. package/cjs/InteractorType.js +5 -0
  51. package/cjs/Options/Classes/Events/ClickEvent.js +20 -0
  52. package/cjs/Options/Classes/Events/DivEvent.js +31 -0
  53. package/cjs/Options/Classes/Events/Events.js +29 -0
  54. package/cjs/Options/Classes/Events/HoverEvent.js +20 -0
  55. package/cjs/Options/Classes/Interactivity.js +25 -0
  56. package/cjs/Options/Classes/Modes/Modes.js +27 -0
  57. package/cjs/Options/Interfaces/Events/IClickEvent.js +1 -0
  58. package/cjs/Options/Interfaces/Events/IDivEvent.js +1 -0
  59. package/cjs/Options/Interfaces/Events/IEvents.js +1 -0
  60. package/cjs/Options/Interfaces/Events/IHoverEvent.js +1 -0
  61. package/cjs/Options/Interfaces/IInteractivity.js +1 -0
  62. package/cjs/Options/Interfaces/Modes/IModeDiv.js +1 -0
  63. package/cjs/Options/Interfaces/Modes/IModes.js +1 -0
  64. package/cjs/ParticlesInteractorBase.js +8 -0
  65. package/cjs/index.js +38 -0
  66. package/cjs/package.json +1 -0
  67. package/cjs/types.js +1 -0
  68. package/cjs/utils.js +32 -0
  69. package/dist_browser_InteractivityPluginInstance_js.js +50 -0
  70. package/dist_browser_InteractivityPlugin_js.js +70 -0
  71. package/esm/DivType.js +5 -0
  72. package/esm/ExternalInteractorBase.js +8 -0
  73. package/esm/IExternalInteractor.js +1 -0
  74. package/esm/IInteractivityData.js +1 -0
  75. package/esm/IInteractor.js +1 -0
  76. package/esm/IMouseData.js +1 -0
  77. package/esm/IParticlesInteractor.js +1 -0
  78. package/esm/InteractionManager.js +212 -0
  79. package/esm/InteractivityConstants.js +1 -0
  80. package/esm/InteractivityDetect.js +6 -0
  81. package/esm/InteractivityEventListeners.js +244 -0
  82. package/esm/InteractivityPlugin.js +49 -0
  83. package/esm/InteractivityPluginInstance.js +55 -0
  84. package/esm/InteractorType.js +5 -0
  85. package/esm/Options/Classes/Events/ClickEvent.js +20 -0
  86. package/esm/Options/Classes/Events/DivEvent.js +31 -0
  87. package/esm/Options/Classes/Events/Events.js +29 -0
  88. package/esm/Options/Classes/Events/HoverEvent.js +20 -0
  89. package/esm/Options/Classes/Interactivity.js +25 -0
  90. package/esm/Options/Classes/Modes/Modes.js +27 -0
  91. package/esm/Options/Interfaces/Events/IClickEvent.js +1 -0
  92. package/esm/Options/Interfaces/Events/IDivEvent.js +1 -0
  93. package/esm/Options/Interfaces/Events/IEvents.js +1 -0
  94. package/esm/Options/Interfaces/Events/IHoverEvent.js +1 -0
  95. package/esm/Options/Interfaces/IInteractivity.js +1 -0
  96. package/esm/Options/Interfaces/Modes/IModeDiv.js +1 -0
  97. package/esm/Options/Interfaces/Modes/IModes.js +1 -0
  98. package/esm/ParticlesInteractorBase.js +8 -0
  99. package/esm/index.js +38 -0
  100. package/esm/package.json +1 -0
  101. package/esm/types.js +1 -0
  102. package/esm/utils.js +32 -0
  103. package/package.json +95 -0
  104. package/report.html +40 -0
  105. package/tsparticles.plugin.interactivity.js +407 -0
  106. package/tsparticles.plugin.interactivity.min.js +2 -0
  107. package/types/DivType.d.ts +4 -0
  108. package/types/ExternalInteractorBase.d.ts +15 -0
  109. package/types/IExternalInteractor.d.ts +11 -0
  110. package/types/IInteractivityData.d.ts +6 -0
  111. package/types/IInteractor.d.ts +12 -0
  112. package/types/IMouseData.d.ts +9 -0
  113. package/types/IParticlesInteractor.d.ts +7 -0
  114. package/types/InteractionManager.d.ts +27 -0
  115. package/types/InteractivityConstants.d.ts +1 -0
  116. package/types/InteractivityDetect.d.ts +5 -0
  117. package/types/InteractivityEventListeners.d.ts +25 -0
  118. package/types/InteractivityPlugin.d.ts +11 -0
  119. package/types/InteractivityPluginInstance.d.ts +20 -0
  120. package/types/InteractorType.d.ts +4 -0
  121. package/types/Options/Classes/Events/ClickEvent.d.ts +8 -0
  122. package/types/Options/Classes/Events/DivEvent.d.ts +11 -0
  123. package/types/Options/Classes/Events/Events.d.ts +12 -0
  124. package/types/Options/Classes/Events/HoverEvent.d.ts +8 -0
  125. package/types/Options/Classes/Interactivity.d.ts +14 -0
  126. package/types/Options/Classes/Modes/Modes.d.ts +10 -0
  127. package/types/Options/Interfaces/Events/IClickEvent.d.ts +5 -0
  128. package/types/Options/Interfaces/Events/IDivEvent.d.ts +8 -0
  129. package/types/Options/Interfaces/Events/IEvents.d.ts +9 -0
  130. package/types/Options/Interfaces/Events/IHoverEvent.d.ts +5 -0
  131. package/types/Options/Interfaces/IInteractivity.d.ts +9 -0
  132. package/types/Options/Interfaces/Modes/IModeDiv.d.ts +4 -0
  133. package/types/Options/Interfaces/Modes/IModes.d.ts +1 -0
  134. package/types/ParticlesInteractorBase.d.ts +15 -0
  135. package/types/index.d.ts +19 -0
  136. package/types/types.d.ts +34 -0
  137. package/types/utils.d.ts +7 -0
  138. package/umd/DivType.js +18 -0
  139. package/umd/ExternalInteractorBase.js +22 -0
  140. package/umd/IExternalInteractor.js +12 -0
  141. package/umd/IInteractivityData.js +12 -0
  142. package/umd/IInteractor.js +12 -0
  143. package/umd/IMouseData.js +12 -0
  144. package/umd/IParticlesInteractor.js +12 -0
  145. package/umd/InteractionManager.js +226 -0
  146. package/umd/InteractivityConstants.js +14 -0
  147. package/umd/InteractivityDetect.js +19 -0
  148. package/umd/InteractivityEventListeners.js +258 -0
  149. package/umd/InteractivityPlugin.js +97 -0
  150. package/umd/InteractivityPluginInstance.js +69 -0
  151. package/umd/InteractorType.js +18 -0
  152. package/umd/Options/Classes/Events/ClickEvent.js +34 -0
  153. package/umd/Options/Classes/Events/DivEvent.js +45 -0
  154. package/umd/Options/Classes/Events/Events.js +43 -0
  155. package/umd/Options/Classes/Events/HoverEvent.js +34 -0
  156. package/umd/Options/Classes/Interactivity.js +39 -0
  157. package/umd/Options/Classes/Modes/Modes.js +41 -0
  158. package/umd/Options/Interfaces/Events/IClickEvent.js +12 -0
  159. package/umd/Options/Interfaces/Events/IDivEvent.js +12 -0
  160. package/umd/Options/Interfaces/Events/IEvents.js +12 -0
  161. package/umd/Options/Interfaces/Events/IHoverEvent.js +12 -0
  162. package/umd/Options/Interfaces/IInteractivity.js +12 -0
  163. package/umd/Options/Interfaces/Modes/IModeDiv.js +12 -0
  164. package/umd/Options/Interfaces/Modes/IModes.js +12 -0
  165. package/umd/ParticlesInteractorBase.js +22 -0
  166. package/umd/index.js +88 -0
  167. package/umd/types.js +12 -0
  168. package/umd/utils.js +48 -0
package/19.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_plugin_interactivity=this.webpackChunk_tsparticles_plugin_interactivity||[]).push([[19],{19(e,t,i){i.d(t,{InteractivityPlugin:()=>o});var n=i(303),s=i(210);class o{id="interactivity";_engine;constructor(e){this._engine=e}async getPlugin(e){let{InteractivityPluginInstance:t}=await i.e(74).then(i.bind(i,74));return new t(this._engine,e)}loadOptions(e,t,i){if(!this.needsPlugin())return;let n=t.interactivity;n?.load||(t.interactivity=n=new s.k(this._engine,e)),n.load(i?.interactivity);let o=this._engine.interactors?.get(e);if(o)for(let e of o)e.loadOptions&&e.loadOptions(t,i)}loadParticlesOptions(e,t,i){i?.interactivity&&(t.interactivity=(0,n.deepExtend)({},i.interactivity));let s=this._engine.interactors?.get(e);if(s)for(let e of s)e.loadParticlesOptions&&e.loadParticlesOptions(t,i)}needsPlugin(){return!0}}},210(e,t,i){i.d(t,{k:()=>c});var n=i(303);class s{enable;mode;constructor(){this.enable=!1,this.mode=[]}load(e){(0,n.isNull)(e)||(void 0!==e.enable&&(this.enable=e.enable),void 0!==e.mode&&(this.mode=e.mode))}}var o=i(570);class l{enable;mode;constructor(){this.enable=!1,this.mode=[]}load(e){(0,n.isNull)(e)||(void 0!==e.enable&&(this.enable=e.enable),void 0!==e.mode&&(this.mode=e.mode))}}class a{onClick;onDiv;onHover;constructor(){this.onClick=new s,this.onDiv=new o.G,this.onHover=new l}load(e){if((0,n.isNull)(e))return;this.onClick.load(e.onClick);let t=e.onDiv;void 0!==t&&(this.onDiv=(0,n.executeOnSingleOrMultiple)(t,e=>{let t=new o.G;return t.load(e),t})),this.onHover.load(e.onHover)}}var r=i(551),d=i(870);class c{detectsOn;events;modes;constructor(e,t){this.detectsOn=r.h.window,this.events=new a,this.modes=new d.d(e,t)}load(e){if((0,n.isNull)(e))return;let t=e.detectsOn;void 0!==t&&(this.detectsOn=t),this.events.load(e.events),this.modes.load(e.modes)}}}}]);
package/74.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_plugin_interactivity=this.webpackChunk_tsparticles_plugin_interactivity||[]).push([[74],{74(e,t,i){i.d(t,{InteractivityPluginInstance:()=>h});var n=i(303),s=i(311),a=i(551);class r{_canPush=!0;_clickPositionPlugins;_container;_handlers;_interactionManager;_touches;constructor(e,t){this._container=e,this._clickPositionPlugins=[],this._interactionManager=t,this._touches=new Map,this._handlers={mouseDown:()=>{this._mouseDown()},mouseLeave:()=>{this._mouseTouchFinish()},mouseMove:e=>{this._mouseTouchMove(e)},mouseUp:e=>{this._mouseTouchClick(e)},touchStart:e=>{this._touchStart(e)},touchMove:e=>{this._mouseTouchMove(e)},touchEnd:e=>{this._touchEnd(e)},touchCancel:e=>{this._touchEnd(e)},touchEndClick:e=>{this._touchEndClick(e)},visibilityChange:()=>{this._handleVisibilityChange()}}}addListeners(){this._manageListeners(!0)}init(){for(let e of(this._clickPositionPlugins.length=0,this._container.plugins.filter(e=>!!e.clickPositionValid)))this._clickPositionPlugins.push(e)}removeListeners(){this._manageListeners(!1)}_doMouseTouchClick=e=>{let t=this._container,i=this._interactionManager,s=t.actualOptions;if(this._canPush){let e=i.interactivityData.mouse,t=e.position;if(!t)return;e.clickPosition={...t},e.clickTime=performance.now();let a=s.interactivity?.events.onClick;if(!a?.mode)return;(0,n.executeOnSingleOrMultiple)(a.mode,e=>{i.handleClickMode(e)})}"touchend"===e.type&&setTimeout(()=>{this._mouseTouchFinish()},n.touchDelay)};_handleVisibilityChange=()=>{this._mouseTouchFinish()};_manageInteractivityListeners=(e,t)=>{let i=this._handlers,a=this._container,r=this._interactionManager,o=a.actualOptions,c=r.interactivityData.element;if(!c)return;let l=a.canvas;l.setPointerEvents(c===l.element?"initial":"none"),(o.interactivity?.events.onHover.enable||o.interactivity?.events.onClick.enable)&&((0,n.manageListener)(c,s.Rb,i.mouseMove,t),(0,n.manageListener)(c,s.s7,i.touchStart,t),(0,n.manageListener)(c,s.DG,i.touchMove,t),o.interactivity.events.onClick.enable?((0,n.manageListener)(c,s.Bp,i.touchEndClick,t),(0,n.manageListener)(c,s.vo,i.mouseUp,t),(0,n.manageListener)(c,s.ms,i.mouseDown,t)):(0,n.manageListener)(c,s.Bp,i.touchEnd,t),(0,n.manageListener)(c,e,i.mouseLeave,t),(0,n.manageListener)(c,s.G3,i.touchCancel,t))};_manageListeners=e=>{let t=this._handlers,i=this._container,r=this._interactionManager,o=i.actualOptions,c=o.interactivity?.detectsOn,l=i.canvas.element,h=s.Z0;c===a.h.window?(r.interactivityData.element=globalThis,h=s.sf):c===a.h.parent&&l?r.interactivityData.element=l.parentElement??l.parentNode:r.interactivityData.element=l,this._manageInteractivityListeners(h,e),(0,n.manageListener)(document,n.visibilityChangeEvent,t.visibilityChange,e,!1)};_mouseDown=()=>{let{interactivityData:e}=this._interactionManager,{mouse:t}=e;t.clicking=!0,t.downPosition=t.position};_mouseTouchClick=e=>{let t=this._container,i=this._interactionManager,n=t.actualOptions,{mouse:s}=i.interactivityData;s.inside=!0;let a=!1,r=s.position;if(r&&n.interactivity?.events.onClick.enable){for(let e of this._clickPositionPlugins)if(a=e.clickPositionValid?.(r)??!1)break;a||this._doMouseTouchClick(e),s.clicking=!1}};_mouseTouchFinish=()=>{let{interactivityData:e}=this._interactionManager,{mouse:t}=e;delete t.position,delete t.clickPosition,delete t.downPosition,e.status=s.Z0,t.inside=!1,t.clicking=!1};_mouseTouchMove=e=>{let t,i=this._container,r=this._interactionManager,o=i.actualOptions,c=r.interactivityData,l=i.canvas.element;if(!c.element)return;if(c.mouse.inside=!0,e.type.startsWith("pointer"))if(this._canPush=!0,c.element===globalThis){if(l){let i=l.getBoundingClientRect();t={x:e.clientX-i.left,y:e.clientY-i.top}}}else if(o.interactivity?.detectsOn===a.h.parent){let i=e.target,s=e.currentTarget;if(l){let a=i.getBoundingClientRect(),r=s.getBoundingClientRect(),o=l.getBoundingClientRect();t={x:e.offsetX+n.double*a.left-(r.left+o.left),y:e.offsetY+n.double*a.top-(r.top+o.top)}}else t={x:e.offsetX,y:e.offsetY}}else e.target===l&&(t={x:e.offsetX,y:e.offsetY});else if(this._canPush="touchmove"!==e.type,l){let i=e.touches[e.touches.length-n.lengthOffset],s=l.getBoundingClientRect();if(!i)return;t={x:i.clientX-s.left,y:i.clientY-s.top}}let h=i.retina.pixelRatio;t&&(t.x*=h,t.y*=h),c.mouse.position=t,c.status=s.Rb};_touchEnd=e=>{for(let t of Array.from(e.changedTouches))this._touches.delete(t.identifier);this._mouseTouchFinish()};_touchEndClick=e=>{for(let t of Array.from(e.changedTouches))this._touches.delete(t.identifier);this._mouseTouchClick(e)};_touchStart=e=>{for(let t of Array.from(e.changedTouches))this._touches.set(t.identifier,performance.now());this._mouseTouchMove(e)}}var o=i(520);class c{container;interactivityData;_clickHandlers;_engine;_eventListeners;_externalInteractors;_interactors;_intersectionObserver;_particleInteractors;constructor(e,t){this.container=t,this._engine=e,this._interactors=[],this._externalInteractors=[],this._particleInteractors=[],this._clickHandlers=new Map,this._eventListeners=new r(t,this),this.interactivityData={mouse:{clicking:!1,inside:!1}},this._intersectionObserver=(0,n.safeIntersectionObserver)(e=>{this._intersectionManager(e)})}addClickHandler(e){let{container:t,interactivityData:i}=this;if(t.destroyed)return;let a=i.element;if(!a)return;let r=(i,n,s)=>{if(t.destroyed)return;let a=t.retina.pixelRatio,r={x:n.x*a,y:n.y*a};e(i,t.particles.quadTree.queryCircle(r,s*a))},o=!1,c=!1;for(let[e,i]of(this._clickHandlers.set(s.xO,e=>{if(t.destroyed)return;let i={x:e.offsetX,y:e.offsetY};r(e,i,n.clickRadius)}),this._clickHandlers.set(s.s7,()=>{t.destroyed||(o=!0,c=!1)}),this._clickHandlers.set(s.DG,()=>{t.destroyed||(c=!0)}),this._clickHandlers.set(s.Bp,e=>{if(!t.destroyed){if(o&&!c){let i=e.touches[e.touches.length-n.touchEndLengthOffset];if(!i)return;let s=t.canvas.element,a=s?s.getBoundingClientRect():void 0;r(e,{x:i.clientX-(a?a.left:n.minCoordinate),y:i.clientY-(a?a.top:n.minCoordinate)},Math.max(i.radiusX,i.radiusY))}o=!1,c=!1}}),this._clickHandlers.set(s.G3,()=>{t.destroyed||(o=!1,c=!1)}),this._clickHandlers))a.addEventListener(e,i)}addListeners(){this._eventListeners.addListeners()}clearClickHandlers(){let{container:e,interactivityData:t}=this;if(!e.destroyed){for(let[e,i]of this._clickHandlers)t.element?.removeEventListener(e,i);this._clickHandlers.clear()}}externalInteract(e){for(let t of this._externalInteractors){let{interactivityData:i}=this;t.isEnabled(i)&&t.interact(i,e)}}handleClickMode(e){if(this.container.destroyed)return;let{interactivityData:t}=this;for(let i of this._externalInteractors)i.handleClickMode?.(e,t)}async init(){let e=await this._engine.getInteractors?.(this.container,!0);if(e)for(let t of(this._interactors=e,this._externalInteractors=[],this._particleInteractors=[],this._eventListeners.init(),this._interactors)){switch(t.type){case o.e.external:this._externalInteractors.push(t);break;case o.e.particles:this._particleInteractors.push(t)}t.init()}}particlesInteract(e,t){let{interactivityData:i}=this;for(let i of this._externalInteractors)i.clear(e,t);for(let n of this._particleInteractors)n.isEnabled(e,i)&&n.interact(e,i,t)}removeListeners(){this._eventListeners.removeListeners()}reset(e){let{interactivityData:t}=this;for(let i of this._externalInteractors)i.isEnabled(t)&&i.reset(t,e);for(let i of this._particleInteractors)i.isEnabled(e,t)&&i.reset(t,e)}startObserving(){let{interactivityData:e}=this;e.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.observe(e.element)}stopObserving(){let{interactivityData:e}=this;e.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.unobserve(e.element)}_intersectionManager=e=>{let{container:t}=this;if(!t.destroyed&&t.actualOptions.pauseOnOutsideViewport)for(let i of e)i.target===this.interactivityData.element&&(i.isIntersecting?t.play():t.pause())}}var l=i(210);class h{interactionManager;_container;_engine;constructor(e,t){this._container=t,this._engine=e,this.interactionManager=new c(e,t),this._container.addClickHandler=e=>{this.interactionManager.addClickHandler(e)}}addClickHandler(e){this.interactionManager.addClickHandler(e)}clearClickHandlers(){this.interactionManager.clearClickHandlers()}destroy(){this.clearClickHandlers(),this._engine.interactors?.delete(this._container)}particleCreated(e){let t=new l.k(this._engine,this._container);t.load(this._container.actualOptions.interactivity),t.load(e.options.interactivity),e.interactivity=t}particleReset(e){this.interactionManager.reset(e)}postParticleUpdate(e,t){this.interactionManager.particlesInteract(e,t)}postUpdate(e){this.interactionManager.externalInteract(e)}async preInit(){await this.interactionManager.init()}async redrawInit(){await this.interactionManager.init()}start(){return this.interactionManager.addListeners(),this.interactionManager.startObserving(),Promise.resolve()}stop(){this.interactionManager.removeListeners(),this.interactionManager.stopObserving()}}}}]);
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Matteo Bruni
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ [![banner](https://particles.js.org/images/banner2.png)](https://particles.js.org)
2
+
3
+ # tsParticles Interactivity Plugin
4
+
5
+ [![jsDelivr](https://data.jsdelivr.com/v1/package/npm/@tsparticles/plugin-interactivity/badge)](https://www.jsdelivr.com/package/npm/@tsparticles/plugin-interactivity)
6
+ [![npmjs](https://badge.fury.io/js/@tsparticles/plugin-interactivity.svg)](https://www.npmjs.com/package/@tsparticles/plugin-interactivity)
7
+ [![npmjs](https://img.shields.io/npm/dt/@tsparticles/plugin-interactivity)](https://www.npmjs.com/package/@tsparticles/plugin-interactivity) [![GitHub Sponsors](https://img.shields.io/github/sponsors/matteobruni)](https://github.com/sponsors/matteobruni)
8
+
9
+ [tsParticles](https://github.com/tsparticles/tsparticles) plugin for handling interactivity sickness CSS value.
10
+
11
+ ## How to use it
12
+
13
+ ### CDN / Vanilla JS / jQuery
14
+
15
+ The CDN/Vanilla version JS has one required file in vanilla configuration:
16
+
17
+ Including the `tsparticles.plugin.interactivity.min.js` file will export the function to load the plugin:
18
+
19
+ ```javascript
20
+ loadInteractivityPlugin;
21
+ ```
22
+
23
+ ### Usage
24
+
25
+ Once the scripts are loaded you can set up `tsParticles` and the plugin like this:
26
+
27
+ ```javascript
28
+ (async () => {
29
+ await loadInteractivityPlugin(tsParticles);
30
+
31
+ await tsParticles.load({
32
+ id: "tsparticles",
33
+ options: {
34
+ /* options */
35
+ },
36
+ });
37
+ })();
38
+ ```
39
+
40
+ ### ESM / CommonJS
41
+
42
+ This package is compatible also with ES or CommonJS modules, firstly this needs to be installed, like this:
43
+
44
+ ```shell
45
+ $ npm install @tsparticles/plugin-interactivity
46
+ ```
47
+
48
+ or
49
+
50
+ ```shell
51
+ $ yarn add @tsparticles/plugin-interactivity
52
+ ```
53
+
54
+ Then you need to import it in the app, like this:
55
+
56
+ ```javascript
57
+ const { tsParticles } = require("@tsparticles/engine");
58
+ const { loadInteractivityPlugin } = require("@tsparticles/plugin-interactivity");
59
+
60
+ (async () => {
61
+ await loadInteractivityPlugin(tsParticles);
62
+ })();
63
+ ```
64
+
65
+ or
66
+
67
+ ```javascript
68
+ import { tsParticles } from "@tsparticles/engine";
69
+ import { loadInteractivityPlugin } from "@tsparticles/plugin-interactivity";
70
+
71
+ (async () => {
72
+ await loadInteractivityPlugin(tsParticles);
73
+ })();
74
+ ```
@@ -0,0 +1,5 @@
1
+ export var DivType;
2
+ (function (DivType) {
3
+ DivType["circle"] = "circle";
4
+ DivType["rectangle"] = "rectangle";
5
+ })(DivType || (DivType = {}));
@@ -0,0 +1,8 @@
1
+ import { InteractorType } from "./InteractorType.js";
2
+ export class ExternalInteractorBase {
3
+ type = InteractorType.external;
4
+ container;
5
+ constructor(container) {
6
+ this.container = container;
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,212 @@
1
+ import { clickRadius, minCoordinate, safeIntersectionObserver, touchEndLengthOffset, } from "@tsparticles/engine";
2
+ import { clickEvent, touchCancelEvent, touchEndEvent, touchMoveEvent, touchStartEvent, } from "./InteractivityConstants.js";
3
+ import { InteractivityEventListeners } from "./InteractivityEventListeners.js";
4
+ import { InteractorType } from "./InteractorType.js";
5
+ export class InteractionManager {
6
+ container;
7
+ interactivityData;
8
+ _clickHandlers;
9
+ _engine;
10
+ _eventListeners;
11
+ _externalInteractors;
12
+ _interactors;
13
+ _intersectionObserver;
14
+ _particleInteractors;
15
+ constructor(engine, container) {
16
+ this.container = container;
17
+ this._engine = engine;
18
+ this._interactors = [];
19
+ this._externalInteractors = [];
20
+ this._particleInteractors = [];
21
+ this._clickHandlers = new Map();
22
+ this._eventListeners = new InteractivityEventListeners(container, this);
23
+ this.interactivityData = {
24
+ mouse: {
25
+ clicking: false,
26
+ inside: false,
27
+ },
28
+ };
29
+ this._intersectionObserver = safeIntersectionObserver(entries => {
30
+ this._intersectionManager(entries);
31
+ });
32
+ }
33
+ addClickHandler(callback) {
34
+ const { container, interactivityData } = this;
35
+ if (container.destroyed) {
36
+ return;
37
+ }
38
+ const el = interactivityData.element;
39
+ if (!el) {
40
+ return;
41
+ }
42
+ const clickOrTouchHandler = (e, pos, radius) => {
43
+ if (container.destroyed) {
44
+ return;
45
+ }
46
+ const pxRatio = container.retina.pixelRatio, posRetina = {
47
+ x: pos.x * pxRatio,
48
+ y: pos.y * pxRatio,
49
+ }, particles = container.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
50
+ callback(e, particles);
51
+ }, clickHandler = (e) => {
52
+ if (container.destroyed) {
53
+ return;
54
+ }
55
+ const mouseEvent = e, pos = {
56
+ x: mouseEvent.offsetX,
57
+ y: mouseEvent.offsetY,
58
+ };
59
+ clickOrTouchHandler(e, pos, clickRadius);
60
+ }, touchStartHandler = () => {
61
+ if (container.destroyed) {
62
+ return;
63
+ }
64
+ touched = true;
65
+ touchMoved = false;
66
+ }, touchMoveHandler = () => {
67
+ if (container.destroyed) {
68
+ return;
69
+ }
70
+ touchMoved = true;
71
+ }, touchEndHandler = (e) => {
72
+ if (container.destroyed) {
73
+ return;
74
+ }
75
+ if (touched && !touchMoved) {
76
+ const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - touchEndLengthOffset];
77
+ if (!lastTouch) {
78
+ return;
79
+ }
80
+ const element = container.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
81
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
82
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
83
+ };
84
+ clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
85
+ }
86
+ touched = false;
87
+ touchMoved = false;
88
+ }, touchCancelHandler = () => {
89
+ if (container.destroyed) {
90
+ return;
91
+ }
92
+ touched = false;
93
+ touchMoved = false;
94
+ };
95
+ let touched = false, touchMoved = false;
96
+ this._clickHandlers.set(clickEvent, clickHandler);
97
+ this._clickHandlers.set(touchStartEvent, touchStartHandler);
98
+ this._clickHandlers.set(touchMoveEvent, touchMoveHandler);
99
+ this._clickHandlers.set(touchEndEvent, touchEndHandler);
100
+ this._clickHandlers.set(touchCancelEvent, touchCancelHandler);
101
+ for (const [key, handler] of this._clickHandlers) {
102
+ el.addEventListener(key, handler);
103
+ }
104
+ }
105
+ addListeners() {
106
+ this._eventListeners.addListeners();
107
+ }
108
+ clearClickHandlers() {
109
+ const { container, interactivityData } = this;
110
+ if (container.destroyed) {
111
+ return;
112
+ }
113
+ for (const [key, handler] of this._clickHandlers) {
114
+ interactivityData.element?.removeEventListener(key, handler);
115
+ }
116
+ this._clickHandlers.clear();
117
+ }
118
+ externalInteract(delta) {
119
+ for (const interactor of this._externalInteractors) {
120
+ const { interactivityData } = this;
121
+ if (interactor.isEnabled(interactivityData)) {
122
+ interactor.interact(interactivityData, delta);
123
+ }
124
+ }
125
+ }
126
+ handleClickMode(mode) {
127
+ if (this.container.destroyed) {
128
+ return;
129
+ }
130
+ const { interactivityData } = this;
131
+ for (const interactor of this._externalInteractors) {
132
+ interactor.handleClickMode?.(mode, interactivityData);
133
+ }
134
+ }
135
+ async init() {
136
+ const interactors = await this._engine.getInteractors?.(this.container, true);
137
+ if (!interactors) {
138
+ return;
139
+ }
140
+ this._interactors = interactors;
141
+ this._externalInteractors = [];
142
+ this._particleInteractors = [];
143
+ this._eventListeners.init();
144
+ for (const interactor of this._interactors) {
145
+ switch (interactor.type) {
146
+ case InteractorType.external:
147
+ this._externalInteractors.push(interactor);
148
+ break;
149
+ case InteractorType.particles:
150
+ this._particleInteractors.push(interactor);
151
+ break;
152
+ }
153
+ interactor.init();
154
+ }
155
+ }
156
+ particlesInteract(particle, delta) {
157
+ const { interactivityData } = this;
158
+ for (const interactor of this._externalInteractors) {
159
+ interactor.clear(particle, delta);
160
+ }
161
+ for (const interactor of this._particleInteractors) {
162
+ if (interactor.isEnabled(particle, interactivityData)) {
163
+ interactor.interact(particle, interactivityData, delta);
164
+ }
165
+ }
166
+ }
167
+ removeListeners() {
168
+ this._eventListeners.removeListeners();
169
+ }
170
+ reset(particle) {
171
+ const { interactivityData } = this;
172
+ for (const interactor of this._externalInteractors) {
173
+ if (interactor.isEnabled(interactivityData)) {
174
+ interactor.reset(interactivityData, particle);
175
+ }
176
+ }
177
+ for (const interactor of this._particleInteractors) {
178
+ if (interactor.isEnabled(particle, interactivityData)) {
179
+ interactor.reset(interactivityData, particle);
180
+ }
181
+ }
182
+ }
183
+ startObserving() {
184
+ const { interactivityData } = this;
185
+ if (interactivityData.element instanceof HTMLElement && this._intersectionObserver) {
186
+ this._intersectionObserver.observe(interactivityData.element);
187
+ }
188
+ }
189
+ stopObserving() {
190
+ const { interactivityData } = this;
191
+ if (interactivityData.element instanceof HTMLElement && this._intersectionObserver) {
192
+ this._intersectionObserver.unobserve(interactivityData.element);
193
+ }
194
+ }
195
+ _intersectionManager = entries => {
196
+ const { container } = this;
197
+ if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
198
+ return;
199
+ }
200
+ for (const entry of entries) {
201
+ if (entry.target !== this.interactivityData.element) {
202
+ continue;
203
+ }
204
+ if (entry.isIntersecting) {
205
+ container.play();
206
+ }
207
+ else {
208
+ container.pause();
209
+ }
210
+ }
211
+ };
212
+ }
@@ -0,0 +1 @@
1
+ export const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseOutEvent = "pointerout", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
@@ -0,0 +1,6 @@
1
+ export var InteractivityDetect;
2
+ (function (InteractivityDetect) {
3
+ InteractivityDetect["canvas"] = "canvas";
4
+ InteractivityDetect["parent"] = "parent";
5
+ InteractivityDetect["window"] = "window";
6
+ })(InteractivityDetect || (InteractivityDetect = {}));
@@ -0,0 +1,244 @@
1
+ import { double, executeOnSingleOrMultiple, lengthOffset, manageListener, touchDelay, visibilityChangeEvent, } from "@tsparticles/engine";
2
+ import { mouseDownEvent, mouseLeaveEvent, mouseMoveEvent, mouseOutEvent, mouseUpEvent, touchCancelEvent, touchEndEvent, touchMoveEvent, touchStartEvent, } from "./InteractivityConstants.js";
3
+ import { InteractivityDetect } from "./InteractivityDetect.js";
4
+ export class InteractivityEventListeners {
5
+ _canPush = true;
6
+ _clickPositionPlugins;
7
+ _container;
8
+ _handlers;
9
+ _interactionManager;
10
+ _touches;
11
+ constructor(container, interactionManager) {
12
+ this._container = container;
13
+ this._clickPositionPlugins = [];
14
+ this._interactionManager = interactionManager;
15
+ this._touches = new Map();
16
+ this._handlers = {
17
+ mouseDown: () => {
18
+ this._mouseDown();
19
+ },
20
+ mouseLeave: () => {
21
+ this._mouseTouchFinish();
22
+ },
23
+ mouseMove: (e) => {
24
+ this._mouseTouchMove(e);
25
+ },
26
+ mouseUp: (e) => {
27
+ this._mouseTouchClick(e);
28
+ },
29
+ touchStart: (e) => {
30
+ this._touchStart(e);
31
+ },
32
+ touchMove: (e) => {
33
+ this._mouseTouchMove(e);
34
+ },
35
+ touchEnd: (e) => {
36
+ this._touchEnd(e);
37
+ },
38
+ touchCancel: (e) => {
39
+ this._touchEnd(e);
40
+ },
41
+ touchEndClick: (e) => {
42
+ this._touchEndClick(e);
43
+ },
44
+ visibilityChange: () => {
45
+ this._handleVisibilityChange();
46
+ },
47
+ };
48
+ }
49
+ addListeners() {
50
+ this._manageListeners(true);
51
+ }
52
+ init() {
53
+ this._clickPositionPlugins.length = 0;
54
+ for (const plugin of this._container.plugins.filter(p => !!p.clickPositionValid)) {
55
+ this._clickPositionPlugins.push(plugin);
56
+ }
57
+ }
58
+ removeListeners() {
59
+ this._manageListeners(false);
60
+ }
61
+ _doMouseTouchClick = e => {
62
+ const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions;
63
+ if (this._canPush) {
64
+ const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
65
+ if (!mousePos) {
66
+ return;
67
+ }
68
+ mouseInteractivity.clickPosition = { ...mousePos };
69
+ mouseInteractivity.clickTime = performance.now();
70
+ const onClick = options.interactivity?.events.onClick;
71
+ if (!onClick?.mode) {
72
+ return;
73
+ }
74
+ executeOnSingleOrMultiple(onClick.mode, mode => {
75
+ interactionManager.handleClickMode(mode);
76
+ });
77
+ }
78
+ if (e.type === "touchend") {
79
+ setTimeout(() => {
80
+ this._mouseTouchFinish();
81
+ }, touchDelay);
82
+ }
83
+ };
84
+ _handleVisibilityChange = () => {
85
+ this._mouseTouchFinish();
86
+ };
87
+ _manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
88
+ const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
89
+ if (!interactivityEl) {
90
+ return;
91
+ }
92
+ const html = interactivityEl, canvas = container.canvas;
93
+ canvas.setPointerEvents(html === canvas.element ? "initial" : "none");
94
+ if (!(options.interactivity?.events.onHover.enable || options.interactivity?.events.onClick.enable)) {
95
+ return;
96
+ }
97
+ manageListener(interactivityEl, mouseMoveEvent, handlers.mouseMove, add);
98
+ manageListener(interactivityEl, touchStartEvent, handlers.touchStart, add);
99
+ manageListener(interactivityEl, touchMoveEvent, handlers.touchMove, add);
100
+ if (options.interactivity.events.onClick.enable) {
101
+ manageListener(interactivityEl, touchEndEvent, handlers.touchEndClick, add);
102
+ manageListener(interactivityEl, mouseUpEvent, handlers.mouseUp, add);
103
+ manageListener(interactivityEl, mouseDownEvent, handlers.mouseDown, add);
104
+ }
105
+ else {
106
+ manageListener(interactivityEl, touchEndEvent, handlers.touchEnd, add);
107
+ }
108
+ manageListener(interactivityEl, mouseLeaveTmpEvent, handlers.mouseLeave, add);
109
+ manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
110
+ };
111
+ _manageListeners = add => {
112
+ const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.element;
113
+ let mouseLeaveTmpEvent = mouseLeaveEvent;
114
+ if (detectType === InteractivityDetect.window) {
115
+ interactionManager.interactivityData.element = globalThis;
116
+ mouseLeaveTmpEvent = mouseOutEvent;
117
+ }
118
+ else if (detectType === InteractivityDetect.parent && canvasEl) {
119
+ interactionManager.interactivityData.element = canvasEl.parentElement ?? canvasEl.parentNode;
120
+ }
121
+ else {
122
+ interactionManager.interactivityData.element = canvasEl;
123
+ }
124
+ this._manageInteractivityListeners(mouseLeaveTmpEvent, add);
125
+ manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
126
+ };
127
+ _mouseDown = () => {
128
+ const { interactivityData } = this._interactionManager, { mouse } = interactivityData;
129
+ mouse.clicking = true;
130
+ mouse.downPosition = mouse.position;
131
+ };
132
+ _mouseTouchClick = e => {
133
+ const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
134
+ mouse.inside = true;
135
+ let handled = false;
136
+ const mousePosition = mouse.position;
137
+ if (!mousePosition || !options.interactivity?.events.onClick.enable) {
138
+ return;
139
+ }
140
+ for (const plugin of this._clickPositionPlugins) {
141
+ handled = plugin.clickPositionValid?.(mousePosition) ?? false;
142
+ if (handled) {
143
+ break;
144
+ }
145
+ }
146
+ if (!handled) {
147
+ this._doMouseTouchClick(e);
148
+ }
149
+ mouse.clicking = false;
150
+ };
151
+ _mouseTouchFinish = () => {
152
+ const { interactivityData } = this._interactionManager, { mouse } = interactivityData;
153
+ delete mouse.position;
154
+ delete mouse.clickPosition;
155
+ delete mouse.downPosition;
156
+ interactivityData.status = mouseLeaveEvent;
157
+ mouse.inside = false;
158
+ mouse.clicking = false;
159
+ };
160
+ _mouseTouchMove = e => {
161
+ const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.element;
162
+ if (!interactivity.element) {
163
+ return;
164
+ }
165
+ interactivity.mouse.inside = true;
166
+ let pos;
167
+ if (e.type.startsWith("pointer")) {
168
+ this._canPush = true;
169
+ const mouseEvent = e;
170
+ if (interactivity.element === globalThis) {
171
+ if (canvasEl) {
172
+ const clientRect = canvasEl.getBoundingClientRect();
173
+ pos = {
174
+ x: mouseEvent.clientX - clientRect.left,
175
+ y: mouseEvent.clientY - clientRect.top,
176
+ };
177
+ }
178
+ }
179
+ else if (options.interactivity?.detectsOn === InteractivityDetect.parent) {
180
+ const source = mouseEvent.target, target = mouseEvent.currentTarget;
181
+ if (canvasEl) {
182
+ const sourceRect = source.getBoundingClientRect(), targetRect = target.getBoundingClientRect(), canvasRect = canvasEl.getBoundingClientRect();
183
+ pos = {
184
+ x: mouseEvent.offsetX + double * sourceRect.left - (targetRect.left + canvasRect.left),
185
+ y: mouseEvent.offsetY + double * sourceRect.top - (targetRect.top + canvasRect.top),
186
+ };
187
+ }
188
+ else {
189
+ pos = {
190
+ x: mouseEvent.offsetX,
191
+ y: mouseEvent.offsetY,
192
+ };
193
+ }
194
+ }
195
+ else if (mouseEvent.target === canvasEl) {
196
+ pos = {
197
+ x: mouseEvent.offsetX,
198
+ y: mouseEvent.offsetY,
199
+ };
200
+ }
201
+ }
202
+ else {
203
+ this._canPush = e.type !== "touchmove";
204
+ if (canvasEl) {
205
+ const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset], canvasRect = canvasEl.getBoundingClientRect();
206
+ if (!lastTouch) {
207
+ return;
208
+ }
209
+ pos = {
210
+ x: lastTouch.clientX - canvasRect.left,
211
+ y: lastTouch.clientY - canvasRect.top,
212
+ };
213
+ }
214
+ }
215
+ const pxRatio = container.retina.pixelRatio;
216
+ if (pos) {
217
+ pos.x *= pxRatio;
218
+ pos.y *= pxRatio;
219
+ }
220
+ interactivity.mouse.position = pos;
221
+ interactivity.status = mouseMoveEvent;
222
+ };
223
+ _touchEnd = e => {
224
+ const evt = e, touches = Array.from(evt.changedTouches);
225
+ for (const touch of touches) {
226
+ this._touches.delete(touch.identifier);
227
+ }
228
+ this._mouseTouchFinish();
229
+ };
230
+ _touchEndClick = e => {
231
+ const evt = e, touches = Array.from(evt.changedTouches);
232
+ for (const touch of touches) {
233
+ this._touches.delete(touch.identifier);
234
+ }
235
+ this._mouseTouchClick(e);
236
+ };
237
+ _touchStart = e => {
238
+ const evt = e, touches = Array.from(evt.changedTouches);
239
+ for (const touch of touches) {
240
+ this._touches.set(touch.identifier, performance.now());
241
+ }
242
+ this._mouseTouchMove(e);
243
+ };
244
+ }
@@ -0,0 +1,49 @@
1
+ import { deepExtend, } from "@tsparticles/engine";
2
+ import { Interactivity } from "./Options/Classes/Interactivity.js";
3
+ export class InteractivityPlugin {
4
+ id = "interactivity";
5
+ _engine;
6
+ constructor(engine) {
7
+ this._engine = engine;
8
+ }
9
+ async getPlugin(container) {
10
+ const { InteractivityPluginInstance } = await import("./InteractivityPluginInstance.js");
11
+ return new InteractivityPluginInstance(this._engine, container);
12
+ }
13
+ loadOptions(container, options, source) {
14
+ if (!this.needsPlugin()) {
15
+ return;
16
+ }
17
+ let interactivityOptions = options.interactivity;
18
+ if (!interactivityOptions?.load) {
19
+ options.interactivity = interactivityOptions = new Interactivity(this._engine, container);
20
+ }
21
+ interactivityOptions.load(source?.interactivity);
22
+ const interactors = this._engine.interactors?.get(container);
23
+ if (!interactors) {
24
+ return;
25
+ }
26
+ for (const interactor of interactors) {
27
+ if (interactor.loadOptions) {
28
+ interactor.loadOptions(options, source);
29
+ }
30
+ }
31
+ }
32
+ loadParticlesOptions(container, options, source) {
33
+ if (source?.interactivity) {
34
+ options.interactivity = deepExtend({}, source.interactivity);
35
+ }
36
+ const interactors = this._engine.interactors?.get(container);
37
+ if (!interactors) {
38
+ return;
39
+ }
40
+ for (const interactor of interactors) {
41
+ if (interactor.loadParticlesOptions) {
42
+ interactor.loadParticlesOptions(options, source);
43
+ }
44
+ }
45
+ }
46
+ needsPlugin() {
47
+ return true;
48
+ }
49
+ }