@tsparticles/plugin-interactivity 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.
- package/284.min.js +2 -0
- package/284.min.js.LICENSE.txt +1 -0
- package/721.min.js +2 -0
- package/721.min.js.LICENSE.txt +1 -0
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/browser/DivType.js +5 -0
- package/browser/ExternalInteractorBase.js +7 -0
- package/browser/IExternalInteractor.js +1 -0
- package/browser/IInteractivityData.js +1 -0
- package/browser/IInteractor.js +1 -0
- package/browser/IMouseData.js +1 -0
- package/browser/IParticlesInteractor.js +1 -0
- package/browser/InteractionManager.js +202 -0
- package/browser/InteractivityConstants.js +1 -0
- package/browser/InteractivityDetect.js +6 -0
- package/browser/InteractivityEventListeners.js +235 -0
- package/browser/InteractivityPlugin.js +48 -0
- package/browser/InteractivityPluginInstance.js +52 -0
- package/browser/InteractorType.js +5 -0
- package/browser/Options/Classes/Events/ClickEvent.js +18 -0
- package/browser/Options/Classes/Events/DivEvent.js +27 -0
- package/browser/Options/Classes/Events/Events.js +26 -0
- package/browser/Options/Classes/Events/HoverEvent.js +18 -0
- package/browser/Options/Classes/Interactivity.js +22 -0
- package/browser/Options/Classes/Modes/Modes.js +25 -0
- package/browser/Options/Interfaces/Events/IClickEvent.js +1 -0
- package/browser/Options/Interfaces/Events/IDivEvent.js +1 -0
- package/browser/Options/Interfaces/Events/IEvents.js +1 -0
- package/browser/Options/Interfaces/Events/IHoverEvent.js +1 -0
- package/browser/Options/Interfaces/IInteractivity.js +1 -0
- package/browser/Options/Interfaces/Modes/IModeDiv.js +1 -0
- package/browser/Options/Interfaces/Modes/IModes.js +1 -0
- package/browser/ParticlesInteractorBase.js +7 -0
- package/browser/index.js +38 -0
- package/browser/package.json +1 -0
- package/browser/types.js +1 -0
- package/browser/utils.js +32 -0
- package/cjs/DivType.js +5 -0
- package/cjs/ExternalInteractorBase.js +7 -0
- package/cjs/IExternalInteractor.js +1 -0
- package/cjs/IInteractivityData.js +1 -0
- package/cjs/IInteractor.js +1 -0
- package/cjs/IMouseData.js +1 -0
- package/cjs/IParticlesInteractor.js +1 -0
- package/cjs/InteractionManager.js +202 -0
- package/cjs/InteractivityConstants.js +1 -0
- package/cjs/InteractivityDetect.js +6 -0
- package/cjs/InteractivityEventListeners.js +235 -0
- package/cjs/InteractivityPlugin.js +48 -0
- package/cjs/InteractivityPluginInstance.js +52 -0
- package/cjs/InteractorType.js +5 -0
- package/cjs/Options/Classes/Events/ClickEvent.js +18 -0
- package/cjs/Options/Classes/Events/DivEvent.js +27 -0
- package/cjs/Options/Classes/Events/Events.js +26 -0
- package/cjs/Options/Classes/Events/HoverEvent.js +18 -0
- package/cjs/Options/Classes/Interactivity.js +22 -0
- package/cjs/Options/Classes/Modes/Modes.js +25 -0
- package/cjs/Options/Interfaces/Events/IClickEvent.js +1 -0
- package/cjs/Options/Interfaces/Events/IDivEvent.js +1 -0
- package/cjs/Options/Interfaces/Events/IEvents.js +1 -0
- package/cjs/Options/Interfaces/Events/IHoverEvent.js +1 -0
- package/cjs/Options/Interfaces/IInteractivity.js +1 -0
- package/cjs/Options/Interfaces/Modes/IModeDiv.js +1 -0
- package/cjs/Options/Interfaces/Modes/IModes.js +1 -0
- package/cjs/ParticlesInteractorBase.js +7 -0
- package/cjs/index.js +38 -0
- package/cjs/package.json +1 -0
- package/cjs/types.js +1 -0
- package/cjs/utils.js +32 -0
- package/dist_browser_InteractivityPluginInstance_js.js +50 -0
- package/dist_browser_InteractivityPlugin_js.js +70 -0
- package/esm/DivType.js +5 -0
- package/esm/ExternalInteractorBase.js +7 -0
- package/esm/IExternalInteractor.js +1 -0
- package/esm/IInteractivityData.js +1 -0
- package/esm/IInteractor.js +1 -0
- package/esm/IMouseData.js +1 -0
- package/esm/IParticlesInteractor.js +1 -0
- package/esm/InteractionManager.js +202 -0
- package/esm/InteractivityConstants.js +1 -0
- package/esm/InteractivityDetect.js +6 -0
- package/esm/InteractivityEventListeners.js +235 -0
- package/esm/InteractivityPlugin.js +48 -0
- package/esm/InteractivityPluginInstance.js +52 -0
- package/esm/InteractorType.js +5 -0
- package/esm/Options/Classes/Events/ClickEvent.js +18 -0
- package/esm/Options/Classes/Events/DivEvent.js +27 -0
- package/esm/Options/Classes/Events/Events.js +26 -0
- package/esm/Options/Classes/Events/HoverEvent.js +18 -0
- package/esm/Options/Classes/Interactivity.js +22 -0
- package/esm/Options/Classes/Modes/Modes.js +25 -0
- package/esm/Options/Interfaces/Events/IClickEvent.js +1 -0
- package/esm/Options/Interfaces/Events/IDivEvent.js +1 -0
- package/esm/Options/Interfaces/Events/IEvents.js +1 -0
- package/esm/Options/Interfaces/Events/IHoverEvent.js +1 -0
- package/esm/Options/Interfaces/IInteractivity.js +1 -0
- package/esm/Options/Interfaces/Modes/IModeDiv.js +1 -0
- package/esm/Options/Interfaces/Modes/IModes.js +1 -0
- package/esm/ParticlesInteractorBase.js +7 -0
- package/esm/index.js +38 -0
- package/esm/package.json +1 -0
- package/esm/types.js +1 -0
- package/esm/utils.js +32 -0
- package/package.json +95 -0
- package/report.html +40 -0
- package/tsparticles.plugin.interactivity.js +395 -0
- package/tsparticles.plugin.interactivity.min.js +2 -0
- package/tsparticles.plugin.interactivity.min.js.LICENSE.txt +1 -0
- package/types/DivType.d.ts +4 -0
- package/types/ExternalInteractorBase.d.ts +15 -0
- package/types/IExternalInteractor.d.ts +11 -0
- package/types/IInteractivityData.d.ts +6 -0
- package/types/IInteractor.d.ts +12 -0
- package/types/IMouseData.d.ts +9 -0
- package/types/IParticlesInteractor.d.ts +7 -0
- package/types/InteractionManager.d.ts +27 -0
- package/types/InteractivityConstants.d.ts +1 -0
- package/types/InteractivityDetect.d.ts +5 -0
- package/types/InteractivityEventListeners.d.ts +23 -0
- package/types/InteractivityPlugin.d.ts +11 -0
- package/types/InteractivityPluginInstance.d.ts +20 -0
- package/types/InteractorType.d.ts +4 -0
- package/types/Options/Classes/Events/ClickEvent.d.ts +8 -0
- package/types/Options/Classes/Events/DivEvent.d.ts +11 -0
- package/types/Options/Classes/Events/Events.d.ts +12 -0
- package/types/Options/Classes/Events/HoverEvent.d.ts +8 -0
- package/types/Options/Classes/Interactivity.d.ts +14 -0
- package/types/Options/Classes/Modes/Modes.d.ts +10 -0
- package/types/Options/Interfaces/Events/IClickEvent.d.ts +5 -0
- package/types/Options/Interfaces/Events/IDivEvent.d.ts +8 -0
- package/types/Options/Interfaces/Events/IEvents.d.ts +9 -0
- package/types/Options/Interfaces/Events/IHoverEvent.d.ts +5 -0
- package/types/Options/Interfaces/IInteractivity.d.ts +9 -0
- package/types/Options/Interfaces/Modes/IModeDiv.d.ts +4 -0
- package/types/Options/Interfaces/Modes/IModes.d.ts +1 -0
- package/types/ParticlesInteractorBase.d.ts +15 -0
- package/types/index.d.ts +19 -0
- package/types/types.d.ts +32 -0
- package/types/utils.d.ts +7 -0
- package/umd/DivType.js +18 -0
- package/umd/ExternalInteractorBase.js +21 -0
- package/umd/IExternalInteractor.js +12 -0
- package/umd/IInteractivityData.js +12 -0
- package/umd/IInteractor.js +12 -0
- package/umd/IMouseData.js +12 -0
- package/umd/IParticlesInteractor.js +12 -0
- package/umd/InteractionManager.js +216 -0
- package/umd/InteractivityConstants.js +14 -0
- package/umd/InteractivityDetect.js +19 -0
- package/umd/InteractivityEventListeners.js +249 -0
- package/umd/InteractivityPlugin.js +96 -0
- package/umd/InteractivityPluginInstance.js +66 -0
- package/umd/InteractorType.js +18 -0
- package/umd/Options/Classes/Events/ClickEvent.js +32 -0
- package/umd/Options/Classes/Events/DivEvent.js +41 -0
- package/umd/Options/Classes/Events/Events.js +40 -0
- package/umd/Options/Classes/Events/HoverEvent.js +32 -0
- package/umd/Options/Classes/Interactivity.js +36 -0
- package/umd/Options/Classes/Modes/Modes.js +39 -0
- package/umd/Options/Interfaces/Events/IClickEvent.js +12 -0
- package/umd/Options/Interfaces/Events/IDivEvent.js +12 -0
- package/umd/Options/Interfaces/Events/IEvents.js +12 -0
- package/umd/Options/Interfaces/Events/IHoverEvent.js +12 -0
- package/umd/Options/Interfaces/IInteractivity.js +12 -0
- package/umd/Options/Interfaces/Modes/IModeDiv.js +12 -0
- package/umd/Options/Interfaces/Modes/IModes.js +12 -0
- package/umd/ParticlesInteractorBase.js +21 -0
- package/umd/index.js +88 -0
- package/umd/types.js +12 -0
- package/umd/utils.js +48 -0
package/284.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 284.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_plugin_interactivity=this.webpackChunk_tsparticles_plugin_interactivity||[]).push([[284],{284(t,i,e){e.d(i,{InteractivityPlugin:()=>o});var n=e(303),s=e(688);class o{constructor(t){this._engine=t,this.id="interactivity"}async getPlugin(t){const{InteractivityPluginInstance:i}=await e.e(721).then(e.bind(e,721));return new i(this._engine,t)}loadOptions(t,i,e){if(!this.needsPlugin())return;let n=i.interactivity;n?.load||(i.interactivity=n=new s.k(this._engine,t)),n.load(e?.interactivity);const o=this._engine.interactors?.get(t);if(o)for(const t of o)t.loadOptions&&t.loadOptions(i,e)}loadParticlesOptions(t,i,e){e?.interactivity&&(i.interactivity=(0,n.deepExtend)({},e.interactivity));const s=this._engine.interactors?.get(t);if(s)for(const t of s)t.loadParticlesOptions&&t.loadParticlesOptions(i,e)}needsPlugin(){return!0}}},688(t,i,e){e.d(i,{k:()=>d});var n=e(303);class s{constructor(){this.enable=!1,this.mode=[]}load(t){(0,n.isNull)(t)||(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode))}}var o=e(897);class a{constructor(){this.enable=!1,this.mode=[]}load(t){(0,n.isNull)(t)||(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.mode&&(this.mode=t.mode))}}class l{constructor(){this.onClick=new s,this.onDiv=new o.G,this.onHover=new a}load(t){if((0,n.isNull)(t))return;this.onClick.load(t.onClick);const i=t.onDiv;void 0!==i&&(this.onDiv=(0,n.executeOnSingleOrMultiple)(i,(t=>{const i=new o.G;return i.load(t),i}))),this.onHover.load(t.onHover)}}var c=e(784),r=e(617);class d{constructor(t,i){this.detectsOn=c.h.window,this.events=new l,this.modes=new r.d(t,i)}load(t){if((0,n.isNull)(t))return;const i=t.detectsOn;void 0!==i&&(this.detectsOn=i),this.events.load(t.events),this.modes.load(t.modes)}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Interactivity Plugin v4.0.0-alpha.4 by Matteo Bruni */
|
package/721.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 721.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_plugin_interactivity=this.webpackChunk_tsparticles_plugin_interactivity||[]).push([[721],{721(t,e,i){i.d(e,{InteractivityPluginInstance:()=>l});var n=i(303),s=i(170),a=i(784);class r{constructor(t,e){this._canPush=!0,this._doMouseTouchClick=t=>{const e=this._container,i=this._interactionManager,s=e.actualOptions;if(this._canPush){const t=i.interactivityData.mouse,e=t.position;if(!e)return;t.clickPosition={...e},t.clickTime=Date.now();const a=s.interactivity?.events.onClick;if(!a?.mode)return;(0,n.executeOnSingleOrMultiple)(a.mode,(t=>{i.handleClickMode(t)}))}"touchend"===t.type&&setTimeout((()=>{this._mouseTouchFinish()}),n.touchDelay)},this._handleVisibilityChange=()=>{this._mouseTouchFinish()},this._manageInteractivityListeners=(t,e)=>{const i=this._handlers,a=this._container,r=this._interactionManager,o=a.actualOptions,c=r.interactivityData.element;if(!c)return;const h=c,l=a.canvas;l.setPointerEvents(h===l.element?"initial":"none"),(o.interactivity?.events.onHover.enable||o.interactivity?.events.onClick.enable)&&((0,n.manageListener)(c,s.Rb,i.mouseMove,e),(0,n.manageListener)(c,s.s7,i.touchStart,e),(0,n.manageListener)(c,s.DG,i.touchMove,e),o.interactivity.events.onClick.enable?((0,n.manageListener)(c,s.Bp,i.touchEndClick,e),(0,n.manageListener)(c,s.vo,i.mouseUp,e),(0,n.manageListener)(c,s.ms,i.mouseDown,e)):(0,n.manageListener)(c,s.Bp,i.touchEnd,e),(0,n.manageListener)(c,t,i.mouseLeave,e),(0,n.manageListener)(c,s.G3,i.touchCancel,e))},this._manageListeners=t=>{const e=this._handlers,i=this._container,r=this._interactionManager,o=i.actualOptions,c=o.interactivity?.detectsOn,h=i.canvas.element;let l=s.Z0;c===a.h.window?(r.interactivityData.element=globalThis,l=s.sf):c===a.h.parent&&h?r.interactivityData.element=h.parentElement??h.parentNode:r.interactivityData.element=h,this._manageInteractivityListeners(l,t),(0,n.manageListener)(document,n.visibilityChangeEvent,e.visibilityChange,t,!1)},this._mouseDown=()=>{const{interactivityData:t}=this._interactionManager,{mouse:e}=t;e.clicking=!0,e.downPosition=e.position},this._mouseTouchClick=t=>{const e=this._container,i=this._interactionManager,n=e.actualOptions,{mouse:s}=i.interactivityData;s.inside=!0;let a=!1;const r=s.position;if(r&&n.interactivity?.events.onClick.enable){for(const t of e.plugins)if(t.clickPositionValid&&(a=t.clickPositionValid(r),a))break;a||this._doMouseTouchClick(t),s.clicking=!1}},this._mouseTouchFinish=()=>{const{interactivityData:t}=this._interactionManager,{mouse:e}=t;delete e.position,delete e.clickPosition,delete e.downPosition,t.status=s.Z0,e.inside=!1,e.clicking=!1},this._mouseTouchMove=t=>{const e=this._container,i=this._interactionManager,r=e.actualOptions,o=i.interactivityData,c=e.canvas.element;if(!o.element)return;let h;if(o.mouse.inside=!0,t.type.startsWith("pointer")){this._canPush=!0;const e=t;if(o.element===globalThis){if(c){const t=c.getBoundingClientRect();h={x:e.clientX-t.left,y:e.clientY-t.top}}}else if(r.interactivity?.detectsOn===a.h.parent){const t=e.target,i=e.currentTarget;if(c){const s=t.getBoundingClientRect(),a=i.getBoundingClientRect(),r=c.getBoundingClientRect();h={x:e.offsetX+n.double*s.left-(a.left+r.left),y:e.offsetY+n.double*s.top-(a.top+r.top)}}else h={x:e.offsetX,y:e.offsetY}}else e.target===c&&(h={x:e.offsetX,y:e.offsetY})}else if(this._canPush="touchmove"!==t.type,c){const e=t,i=e.touches[e.touches.length-n.lengthOffset],s=c.getBoundingClientRect();if(!i)return;h={x:i.clientX-s.left,y:i.clientY-s.top}}const l=e.retina.pixelRatio;h&&(h.x*=l,h.y*=l),o.mouse.position=h,o.status=s.Rb},this._touchEnd=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.delete(t.identifier);this._mouseTouchFinish()},this._touchEndClick=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.delete(t.identifier);this._mouseTouchClick(t)},this._touchStart=t=>{const e=t,i=Array.from(e.changedTouches);for(const t of i)this._touches.set(t.identifier,performance.now());this._mouseTouchMove(t)},this._container=t,this._interactionManager=e,this._touches=new Map,this._handlers={mouseDown:()=>{this._mouseDown()},mouseLeave:()=>{this._mouseTouchFinish()},mouseMove:t=>{this._mouseTouchMove(t)},mouseUp:t=>{this._mouseTouchClick(t)},touchStart:t=>{this._touchStart(t)},touchMove:t=>{this._mouseTouchMove(t)},touchEnd:t=>{this._touchEnd(t)},touchCancel:t=>{this._touchEnd(t)},touchEndClick:t=>{this._touchEndClick(t)},visibilityChange:()=>{this._handleVisibilityChange()}}}addListeners(){this._manageListeners(!0)}removeListeners(){this._manageListeners(!1)}}var o=i(309);class c{constructor(t,e){this.container=e,this._intersectionManager=t=>{const{container:e}=this;if(!e.destroyed&&e.actualOptions.pauseOnOutsideViewport)for(const i of t)i.target===this.interactivityData.element&&(i.isIntersecting?e.play():e.pause())},this._engine=t,this._interactors=[],this._externalInteractors=[],this._particleInteractors=[],this._clickHandlers=new Map,this._eventListeners=new r(e,this),this.interactivityData={mouse:{clicking:!1,inside:!1}},this._intersectionObserver=(0,n.safeIntersectionObserver)((t=>{this._intersectionManager(t)}))}addClickHandler(t){const{container:e,interactivityData:i}=this;if(e.destroyed)return;const a=i.element;if(!a)return;const r=(i,n,s)=>{if(e.destroyed)return;const a=e.retina.pixelRatio,r={x:n.x*a,y:n.y*a},o=e.particles.quadTree.queryCircle(r,s*a);t(i,o)};let o=!1,c=!1;this._clickHandlers.set(s.xO,(t=>{if(e.destroyed)return;const i=t,s={x:i.offsetX,y:i.offsetY};r(t,s,n.clickRadius)})),this._clickHandlers.set(s.s7,(()=>{e.destroyed||(o=!0,c=!1)})),this._clickHandlers.set(s.DG,(()=>{e.destroyed||(c=!0)})),this._clickHandlers.set(s.Bp,(t=>{if(!e.destroyed){if(o&&!c){const i=t,s=i.touches[i.touches.length-n.touchEndLengthOffset];if(!s)return;const a=e.canvas.element,o=a?a.getBoundingClientRect():void 0,c={x:s.clientX-(o?o.left:n.minCoordinate),y:s.clientY-(o?o.top:n.minCoordinate)};r(t,c,Math.max(s.radiusX,s.radiusY))}o=!1,c=!1}})),this._clickHandlers.set(s.G3,(()=>{e.destroyed||(o=!1,c=!1)}));for(const[t,e]of this._clickHandlers)a.addEventListener(t,e)}addListeners(){this._eventListeners.addListeners()}clearClickHandlers(){const{container:t,interactivityData:e}=this;if(!t.destroyed){for(const[t,i]of this._clickHandlers)e.element?.removeEventListener(t,i);this._clickHandlers.clear()}}externalInteract(t){for(const e of this._externalInteractors){const{interactivityData:i}=this;e.isEnabled(i)&&e.interact(i,t)}}handleClickMode(t){if(this.container.destroyed)return;const{interactivityData:e}=this;for(const i of this._externalInteractors)i.handleClickMode?.(t,e)}async init(){const t=await(this._engine.getInteractors?.(this.container,!0));if(t){this._interactors=t,this._externalInteractors=[],this._particleInteractors=[];for(const t of 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(t,e){const{interactivityData:i}=this;for(const i of this._externalInteractors)i.clear(t,e);for(const n of this._particleInteractors)n.isEnabled(t,i)&&n.interact(t,i,e)}removeListeners(){this._eventListeners.removeListeners()}reset(t){const{interactivityData:e}=this;for(const i of this._externalInteractors)i.isEnabled(e)&&i.reset(e,t);for(const i of this._particleInteractors)i.isEnabled(t,e)&&i.reset(e,t)}startObserving(){const{interactivityData:t}=this;t.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.observe(t.element)}stopObserving(){const{interactivityData:t}=this;t.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.unobserve(t.element)}}var h=i(688);class l{constructor(t,e){this._container=e,this._engine=t,this.interactionManager=new c(t,e),this._container.addClickHandler=t=>{this.interactionManager.addClickHandler(t)}}addClickHandler(t){this.interactionManager.addClickHandler(t)}clearClickHandlers(){this.interactionManager.clearClickHandlers()}destroy(){this.clearClickHandlers(),this._engine.interactors?.delete(this._container)}particleCreated(t){const e=t,i=new h.k(this._engine,this._container);i.load(this._container.actualOptions.interactivity),i.load(e.options.interactivity),e.interactivity=i}particleReset(t){this.interactionManager.reset(t)}postParticleUpdate(t,e){this.interactionManager.particlesInteract(t,e)}postUpdate(t){this.interactionManager.externalInteract(t)}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()}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Interactivity Plugin v4.0.0-alpha.4 by Matteo Bruni */
|
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
|
+
[](https://particles.js.org)
|
|
2
|
+
|
|
3
|
+
# tsParticles Interactivity Plugin
|
|
4
|
+
|
|
5
|
+
[](https://www.jsdelivr.com/package/npm/@tsparticles/plugin-interactivity)
|
|
6
|
+
[](https://www.npmjs.com/package/@tsparticles/plugin-interactivity)
|
|
7
|
+
[](https://www.npmjs.com/package/@tsparticles/plugin-interactivity) [](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 @@
|
|
|
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,202 @@
|
|
|
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
|
+
constructor(engine, container) {
|
|
7
|
+
this.container = container;
|
|
8
|
+
this._intersectionManager = entries => {
|
|
9
|
+
const { container } = this;
|
|
10
|
+
if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
if (entry.target !== this.interactivityData.element) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (entry.isIntersecting) {
|
|
18
|
+
container.play();
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
container.pause();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
this._engine = engine;
|
|
26
|
+
this._interactors = [];
|
|
27
|
+
this._externalInteractors = [];
|
|
28
|
+
this._particleInteractors = [];
|
|
29
|
+
this._clickHandlers = new Map();
|
|
30
|
+
this._eventListeners = new InteractivityEventListeners(container, this);
|
|
31
|
+
this.interactivityData = {
|
|
32
|
+
mouse: {
|
|
33
|
+
clicking: false,
|
|
34
|
+
inside: false,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
this._intersectionObserver = safeIntersectionObserver(entries => {
|
|
38
|
+
this._intersectionManager(entries);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
addClickHandler(callback) {
|
|
42
|
+
const { container, interactivityData } = this;
|
|
43
|
+
if (container.destroyed) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const el = interactivityData.element;
|
|
47
|
+
if (!el) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const clickOrTouchHandler = (e, pos, radius) => {
|
|
51
|
+
if (container.destroyed) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const pxRatio = container.retina.pixelRatio, posRetina = {
|
|
55
|
+
x: pos.x * pxRatio,
|
|
56
|
+
y: pos.y * pxRatio,
|
|
57
|
+
}, particles = container.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
|
|
58
|
+
callback(e, particles);
|
|
59
|
+
}, clickHandler = (e) => {
|
|
60
|
+
if (container.destroyed) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const mouseEvent = e, pos = {
|
|
64
|
+
x: mouseEvent.offsetX,
|
|
65
|
+
y: mouseEvent.offsetY,
|
|
66
|
+
};
|
|
67
|
+
clickOrTouchHandler(e, pos, clickRadius);
|
|
68
|
+
}, touchStartHandler = () => {
|
|
69
|
+
if (container.destroyed) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
touched = true;
|
|
73
|
+
touchMoved = false;
|
|
74
|
+
}, touchMoveHandler = () => {
|
|
75
|
+
if (container.destroyed) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
touchMoved = true;
|
|
79
|
+
}, touchEndHandler = (e) => {
|
|
80
|
+
if (container.destroyed) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (touched && !touchMoved) {
|
|
84
|
+
const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - touchEndLengthOffset];
|
|
85
|
+
if (!lastTouch) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const element = container.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
|
|
89
|
+
x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
|
|
90
|
+
y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
|
|
91
|
+
};
|
|
92
|
+
clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
|
|
93
|
+
}
|
|
94
|
+
touched = false;
|
|
95
|
+
touchMoved = false;
|
|
96
|
+
}, touchCancelHandler = () => {
|
|
97
|
+
if (container.destroyed) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
touched = false;
|
|
101
|
+
touchMoved = false;
|
|
102
|
+
};
|
|
103
|
+
let touched = false, touchMoved = false;
|
|
104
|
+
this._clickHandlers.set(clickEvent, clickHandler);
|
|
105
|
+
this._clickHandlers.set(touchStartEvent, touchStartHandler);
|
|
106
|
+
this._clickHandlers.set(touchMoveEvent, touchMoveHandler);
|
|
107
|
+
this._clickHandlers.set(touchEndEvent, touchEndHandler);
|
|
108
|
+
this._clickHandlers.set(touchCancelEvent, touchCancelHandler);
|
|
109
|
+
for (const [key, handler] of this._clickHandlers) {
|
|
110
|
+
el.addEventListener(key, handler);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
addListeners() {
|
|
114
|
+
this._eventListeners.addListeners();
|
|
115
|
+
}
|
|
116
|
+
clearClickHandlers() {
|
|
117
|
+
const { container, interactivityData } = this;
|
|
118
|
+
if (container.destroyed) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
for (const [key, handler] of this._clickHandlers) {
|
|
122
|
+
interactivityData.element?.removeEventListener(key, handler);
|
|
123
|
+
}
|
|
124
|
+
this._clickHandlers.clear();
|
|
125
|
+
}
|
|
126
|
+
externalInteract(delta) {
|
|
127
|
+
for (const interactor of this._externalInteractors) {
|
|
128
|
+
const { interactivityData } = this;
|
|
129
|
+
if (interactor.isEnabled(interactivityData)) {
|
|
130
|
+
interactor.interact(interactivityData, delta);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
handleClickMode(mode) {
|
|
135
|
+
if (this.container.destroyed) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const { interactivityData } = this;
|
|
139
|
+
for (const interactor of this._externalInteractors) {
|
|
140
|
+
interactor.handleClickMode?.(mode, interactivityData);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async init() {
|
|
144
|
+
const interactors = await this._engine.getInteractors?.(this.container, true);
|
|
145
|
+
if (!interactors) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this._interactors = interactors;
|
|
149
|
+
this._externalInteractors = [];
|
|
150
|
+
this._particleInteractors = [];
|
|
151
|
+
for (const interactor of this._interactors) {
|
|
152
|
+
switch (interactor.type) {
|
|
153
|
+
case InteractorType.external:
|
|
154
|
+
this._externalInteractors.push(interactor);
|
|
155
|
+
break;
|
|
156
|
+
case InteractorType.particles:
|
|
157
|
+
this._particleInteractors.push(interactor);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
interactor.init();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
particlesInteract(particle, delta) {
|
|
164
|
+
const { interactivityData } = this;
|
|
165
|
+
for (const interactor of this._externalInteractors) {
|
|
166
|
+
interactor.clear(particle, delta);
|
|
167
|
+
}
|
|
168
|
+
for (const interactor of this._particleInteractors) {
|
|
169
|
+
if (interactor.isEnabled(particle, interactivityData)) {
|
|
170
|
+
interactor.interact(particle, interactivityData, delta);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
removeListeners() {
|
|
175
|
+
this._eventListeners.removeListeners();
|
|
176
|
+
}
|
|
177
|
+
reset(particle) {
|
|
178
|
+
const { interactivityData } = this;
|
|
179
|
+
for (const interactor of this._externalInteractors) {
|
|
180
|
+
if (interactor.isEnabled(interactivityData)) {
|
|
181
|
+
interactor.reset(interactivityData, particle);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const interactor of this._particleInteractors) {
|
|
185
|
+
if (interactor.isEnabled(particle, interactivityData)) {
|
|
186
|
+
interactor.reset(interactivityData, particle);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
startObserving() {
|
|
191
|
+
const { interactivityData } = this;
|
|
192
|
+
if (interactivityData.element instanceof HTMLElement && this._intersectionObserver) {
|
|
193
|
+
this._intersectionObserver.observe(interactivityData.element);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
stopObserving() {
|
|
197
|
+
const { interactivityData } = this;
|
|
198
|
+
if (interactivityData.element instanceof HTMLElement && this._intersectionObserver) {
|
|
199
|
+
this._intersectionObserver.unobserve(interactivityData.element);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -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,235 @@
|
|
|
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
|
+
constructor(container, interactionManager) {
|
|
6
|
+
this._canPush = true;
|
|
7
|
+
this._doMouseTouchClick = e => {
|
|
8
|
+
const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions;
|
|
9
|
+
if (this._canPush) {
|
|
10
|
+
const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
|
|
11
|
+
if (!mousePos) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
mouseInteractivity.clickPosition = { ...mousePos };
|
|
15
|
+
mouseInteractivity.clickTime = Date.now();
|
|
16
|
+
const onClick = options.interactivity?.events.onClick;
|
|
17
|
+
if (!onClick?.mode) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
executeOnSingleOrMultiple(onClick.mode, mode => {
|
|
21
|
+
interactionManager.handleClickMode(mode);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (e.type === "touchend") {
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
this._mouseTouchFinish();
|
|
27
|
+
}, touchDelay);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
this._handleVisibilityChange = () => {
|
|
31
|
+
this._mouseTouchFinish();
|
|
32
|
+
};
|
|
33
|
+
this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
|
|
34
|
+
const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
|
|
35
|
+
if (!interactivityEl) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const html = interactivityEl, canvas = container.canvas;
|
|
39
|
+
canvas.setPointerEvents(html === canvas.element ? "initial" : "none");
|
|
40
|
+
if (!(options.interactivity?.events.onHover.enable || options.interactivity?.events.onClick.enable)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
manageListener(interactivityEl, mouseMoveEvent, handlers.mouseMove, add);
|
|
44
|
+
manageListener(interactivityEl, touchStartEvent, handlers.touchStart, add);
|
|
45
|
+
manageListener(interactivityEl, touchMoveEvent, handlers.touchMove, add);
|
|
46
|
+
if (options.interactivity.events.onClick.enable) {
|
|
47
|
+
manageListener(interactivityEl, touchEndEvent, handlers.touchEndClick, add);
|
|
48
|
+
manageListener(interactivityEl, mouseUpEvent, handlers.mouseUp, add);
|
|
49
|
+
manageListener(interactivityEl, mouseDownEvent, handlers.mouseDown, add);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
manageListener(interactivityEl, touchEndEvent, handlers.touchEnd, add);
|
|
53
|
+
}
|
|
54
|
+
manageListener(interactivityEl, mouseLeaveTmpEvent, handlers.mouseLeave, add);
|
|
55
|
+
manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
|
|
56
|
+
};
|
|
57
|
+
this._manageListeners = add => {
|
|
58
|
+
const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.element;
|
|
59
|
+
let mouseLeaveTmpEvent = mouseLeaveEvent;
|
|
60
|
+
if (detectType === InteractivityDetect.window) {
|
|
61
|
+
interactionManager.interactivityData.element = globalThis;
|
|
62
|
+
mouseLeaveTmpEvent = mouseOutEvent;
|
|
63
|
+
}
|
|
64
|
+
else if (detectType === InteractivityDetect.parent && canvasEl) {
|
|
65
|
+
interactionManager.interactivityData.element = canvasEl.parentElement ?? canvasEl.parentNode;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
interactionManager.interactivityData.element = canvasEl;
|
|
69
|
+
}
|
|
70
|
+
this._manageInteractivityListeners(mouseLeaveTmpEvent, add);
|
|
71
|
+
manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
|
|
72
|
+
};
|
|
73
|
+
this._mouseDown = () => {
|
|
74
|
+
const { interactivityData } = this._interactionManager, { mouse } = interactivityData;
|
|
75
|
+
mouse.clicking = true;
|
|
76
|
+
mouse.downPosition = mouse.position;
|
|
77
|
+
};
|
|
78
|
+
this._mouseTouchClick = e => {
|
|
79
|
+
const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
|
|
80
|
+
mouse.inside = true;
|
|
81
|
+
let handled = false;
|
|
82
|
+
const mousePosition = mouse.position;
|
|
83
|
+
if (!mousePosition || !options.interactivity?.events.onClick.enable) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
for (const plugin of container.plugins) {
|
|
87
|
+
if (!plugin.clickPositionValid) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
handled = plugin.clickPositionValid(mousePosition);
|
|
91
|
+
if (handled) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!handled) {
|
|
96
|
+
this._doMouseTouchClick(e);
|
|
97
|
+
}
|
|
98
|
+
mouse.clicking = false;
|
|
99
|
+
};
|
|
100
|
+
this._mouseTouchFinish = () => {
|
|
101
|
+
const { interactivityData } = this._interactionManager, { mouse } = interactivityData;
|
|
102
|
+
delete mouse.position;
|
|
103
|
+
delete mouse.clickPosition;
|
|
104
|
+
delete mouse.downPosition;
|
|
105
|
+
interactivityData.status = mouseLeaveEvent;
|
|
106
|
+
mouse.inside = false;
|
|
107
|
+
mouse.clicking = false;
|
|
108
|
+
};
|
|
109
|
+
this._mouseTouchMove = e => {
|
|
110
|
+
const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.element;
|
|
111
|
+
if (!interactivity.element) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
interactivity.mouse.inside = true;
|
|
115
|
+
let pos;
|
|
116
|
+
if (e.type.startsWith("pointer")) {
|
|
117
|
+
this._canPush = true;
|
|
118
|
+
const mouseEvent = e;
|
|
119
|
+
if (interactivity.element === globalThis) {
|
|
120
|
+
if (canvasEl) {
|
|
121
|
+
const clientRect = canvasEl.getBoundingClientRect();
|
|
122
|
+
pos = {
|
|
123
|
+
x: mouseEvent.clientX - clientRect.left,
|
|
124
|
+
y: mouseEvent.clientY - clientRect.top,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (options.interactivity?.detectsOn === InteractivityDetect.parent) {
|
|
129
|
+
const source = mouseEvent.target, target = mouseEvent.currentTarget;
|
|
130
|
+
if (canvasEl) {
|
|
131
|
+
const sourceRect = source.getBoundingClientRect(), targetRect = target.getBoundingClientRect(), canvasRect = canvasEl.getBoundingClientRect();
|
|
132
|
+
pos = {
|
|
133
|
+
x: mouseEvent.offsetX + double * sourceRect.left - (targetRect.left + canvasRect.left),
|
|
134
|
+
y: mouseEvent.offsetY + double * sourceRect.top - (targetRect.top + canvasRect.top),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
pos = {
|
|
139
|
+
x: mouseEvent.offsetX,
|
|
140
|
+
y: mouseEvent.offsetY,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (mouseEvent.target === canvasEl) {
|
|
145
|
+
pos = {
|
|
146
|
+
x: mouseEvent.offsetX,
|
|
147
|
+
y: mouseEvent.offsetY,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
this._canPush = e.type !== "touchmove";
|
|
153
|
+
if (canvasEl) {
|
|
154
|
+
const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset], canvasRect = canvasEl.getBoundingClientRect();
|
|
155
|
+
if (!lastTouch) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
pos = {
|
|
159
|
+
x: lastTouch.clientX - canvasRect.left,
|
|
160
|
+
y: lastTouch.clientY - canvasRect.top,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const pxRatio = container.retina.pixelRatio;
|
|
165
|
+
if (pos) {
|
|
166
|
+
pos.x *= pxRatio;
|
|
167
|
+
pos.y *= pxRatio;
|
|
168
|
+
}
|
|
169
|
+
interactivity.mouse.position = pos;
|
|
170
|
+
interactivity.status = mouseMoveEvent;
|
|
171
|
+
};
|
|
172
|
+
this._touchEnd = e => {
|
|
173
|
+
const evt = e, touches = Array.from(evt.changedTouches);
|
|
174
|
+
for (const touch of touches) {
|
|
175
|
+
this._touches.delete(touch.identifier);
|
|
176
|
+
}
|
|
177
|
+
this._mouseTouchFinish();
|
|
178
|
+
};
|
|
179
|
+
this._touchEndClick = e => {
|
|
180
|
+
const evt = e, touches = Array.from(evt.changedTouches);
|
|
181
|
+
for (const touch of touches) {
|
|
182
|
+
this._touches.delete(touch.identifier);
|
|
183
|
+
}
|
|
184
|
+
this._mouseTouchClick(e);
|
|
185
|
+
};
|
|
186
|
+
this._touchStart = e => {
|
|
187
|
+
const evt = e, touches = Array.from(evt.changedTouches);
|
|
188
|
+
for (const touch of touches) {
|
|
189
|
+
this._touches.set(touch.identifier, performance.now());
|
|
190
|
+
}
|
|
191
|
+
this._mouseTouchMove(e);
|
|
192
|
+
};
|
|
193
|
+
this._container = container;
|
|
194
|
+
this._interactionManager = interactionManager;
|
|
195
|
+
this._touches = new Map();
|
|
196
|
+
this._handlers = {
|
|
197
|
+
mouseDown: () => {
|
|
198
|
+
this._mouseDown();
|
|
199
|
+
},
|
|
200
|
+
mouseLeave: () => {
|
|
201
|
+
this._mouseTouchFinish();
|
|
202
|
+
},
|
|
203
|
+
mouseMove: (e) => {
|
|
204
|
+
this._mouseTouchMove(e);
|
|
205
|
+
},
|
|
206
|
+
mouseUp: (e) => {
|
|
207
|
+
this._mouseTouchClick(e);
|
|
208
|
+
},
|
|
209
|
+
touchStart: (e) => {
|
|
210
|
+
this._touchStart(e);
|
|
211
|
+
},
|
|
212
|
+
touchMove: (e) => {
|
|
213
|
+
this._mouseTouchMove(e);
|
|
214
|
+
},
|
|
215
|
+
touchEnd: (e) => {
|
|
216
|
+
this._touchEnd(e);
|
|
217
|
+
},
|
|
218
|
+
touchCancel: (e) => {
|
|
219
|
+
this._touchEnd(e);
|
|
220
|
+
},
|
|
221
|
+
touchEndClick: (e) => {
|
|
222
|
+
this._touchEndClick(e);
|
|
223
|
+
},
|
|
224
|
+
visibilityChange: () => {
|
|
225
|
+
this._handleVisibilityChange();
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
addListeners() {
|
|
230
|
+
this._manageListeners(true);
|
|
231
|
+
}
|
|
232
|
+
removeListeners() {
|
|
233
|
+
this._manageListeners(false);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { deepExtend, } from "@tsparticles/engine";
|
|
2
|
+
import { Interactivity } from "./Options/Classes/Interactivity.js";
|
|
3
|
+
export class InteractivityPlugin {
|
|
4
|
+
constructor(engine) {
|
|
5
|
+
this._engine = engine;
|
|
6
|
+
this.id = "interactivity";
|
|
7
|
+
}
|
|
8
|
+
async getPlugin(container) {
|
|
9
|
+
const { InteractivityPluginInstance } = await import("./InteractivityPluginInstance.js");
|
|
10
|
+
return new InteractivityPluginInstance(this._engine, container);
|
|
11
|
+
}
|
|
12
|
+
loadOptions(container, options, source) {
|
|
13
|
+
if (!this.needsPlugin()) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let interactivityOptions = options.interactivity;
|
|
17
|
+
if (!interactivityOptions?.load) {
|
|
18
|
+
options.interactivity = interactivityOptions = new Interactivity(this._engine, container);
|
|
19
|
+
}
|
|
20
|
+
interactivityOptions.load(source?.interactivity);
|
|
21
|
+
const interactors = this._engine.interactors?.get(container);
|
|
22
|
+
if (!interactors) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const interactor of interactors) {
|
|
26
|
+
if (interactor.loadOptions) {
|
|
27
|
+
interactor.loadOptions(options, source);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
loadParticlesOptions(container, options, source) {
|
|
32
|
+
if (source?.interactivity) {
|
|
33
|
+
options.interactivity = deepExtend({}, source.interactivity);
|
|
34
|
+
}
|
|
35
|
+
const interactors = this._engine.interactors?.get(container);
|
|
36
|
+
if (!interactors) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const interactor of interactors) {
|
|
40
|
+
if (interactor.loadParticlesOptions) {
|
|
41
|
+
interactor.loadParticlesOptions(options, source);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
needsPlugin() {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|