@tsparticles/interaction-external-attract 3.0.0-alpha.1 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.0-alpha.1
7
+ * v3.0.0-beta.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -91,8 +91,8 @@ __webpack_require__.r(__webpack_exports__);
91
91
 
92
92
  // EXPORTS
93
93
  __webpack_require__.d(__webpack_exports__, {
94
- "Attract": () => (/* reexport */ Attract),
95
- "loadExternalAttractInteraction": () => (/* binding */ loadExternalAttractInteraction)
94
+ Attract: () => (/* reexport */ Attract),
95
+ loadExternalAttractInteraction: () => (/* binding */ loadExternalAttractInteraction)
96
96
  });
97
97
 
98
98
  // EXTERNAL MODULE: external {"commonjs":"@tsparticles/engine","commonjs2":"@tsparticles/engine","amd":"@tsparticles/engine","root":"window"}
@@ -137,6 +137,65 @@ class Attract {
137
137
  class Attractor extends engine_root_window_.ExternalInteractorBase {
138
138
  constructor(engine, container) {
139
139
  super(container);
140
+ this._clickAttract = () => {
141
+ const container = this.container;
142
+ if (!container.attract) {
143
+ container.attract = {
144
+ particles: []
145
+ };
146
+ }
147
+ const {
148
+ attract
149
+ } = container;
150
+ if (!attract.finish) {
151
+ if (!attract.count) {
152
+ attract.count = 0;
153
+ }
154
+ attract.count++;
155
+ if (attract.count === container.particles.count) {
156
+ attract.finish = true;
157
+ }
158
+ }
159
+ if (attract.clicking) {
160
+ const mousePos = container.interactivity.mouse.clickPosition,
161
+ attractRadius = container.retina.attractModeDistance;
162
+ if (!attractRadius || attractRadius < 0 || !mousePos) {
163
+ return;
164
+ }
165
+ this._processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius));
166
+ } else if (attract.clicking === false) {
167
+ attract.particles = [];
168
+ }
169
+ return;
170
+ };
171
+ this._hoverAttract = () => {
172
+ const container = this.container,
173
+ mousePos = container.interactivity.mouse.position,
174
+ attractRadius = container.retina.attractModeDistance;
175
+ if (!attractRadius || attractRadius < 0 || !mousePos) {
176
+ return;
177
+ }
178
+ this._processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius));
179
+ };
180
+ this._processAttract = (position, attractRadius, area) => {
181
+ const container = this.container,
182
+ attractOptions = container.actualOptions.interactivity.modes.attract;
183
+ if (!attractOptions) {
184
+ return;
185
+ }
186
+ const query = container.particles.quadTree.query(area, p => this.isEnabled(p));
187
+ for (const particle of query) {
188
+ const {
189
+ dx,
190
+ dy,
191
+ distance
192
+ } = (0,engine_root_window_.getDistances)(particle.position, position);
193
+ const velocity = attractOptions.speed * attractOptions.factor;
194
+ const attractFactor = (0,engine_root_window_.clamp)((0,engine_root_window_.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
195
+ const normVec = engine_root_window_.Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
196
+ particle.position.subFrom(normVec);
197
+ }
198
+ };
140
199
  this._engine = engine;
141
200
  if (!container.attract) {
142
201
  container.attract = {
@@ -165,14 +224,15 @@ class Attractor extends engine_root_window_.ExternalInteractorBase {
165
224
  container.attract.particles = [];
166
225
  container.attract.finish = false;
167
226
  setTimeout(() => {
168
- if (!container.destroyed) {
169
- if (!container.attract) {
170
- container.attract = {
171
- particles: []
172
- };
173
- }
174
- container.attract.clicking = false;
227
+ if (container.destroyed) {
228
+ return;
229
+ }
230
+ if (!container.attract) {
231
+ container.attract = {
232
+ particles: []
233
+ };
175
234
  }
235
+ container.attract.clicking = false;
176
236
  }, attract.duration * 1000);
177
237
  };
178
238
  }
@@ -195,17 +255,16 @@ class Attractor extends engine_root_window_.ExternalInteractorBase {
195
255
  clickEnabled = events.onClick.enable,
196
256
  clickMode = events.onClick.mode;
197
257
  if (mouseMoveStatus && hoverEnabled && (0,engine_root_window_.isInArray)("attract", hoverMode)) {
198
- this.hoverAttract();
258
+ this._hoverAttract();
199
259
  } else if (clickEnabled && (0,engine_root_window_.isInArray)("attract", clickMode)) {
200
- this.clickAttract();
260
+ this._clickAttract();
201
261
  }
202
262
  }
203
263
  isEnabled(particle) {
204
- var _a;
205
264
  const container = this.container,
206
265
  options = container.actualOptions,
207
266
  mouse = container.interactivity.mouse,
208
- events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events;
267
+ events = (particle?.interactivity ?? options.interactivity).events;
209
268
  if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) {
210
269
  return false;
211
270
  }
@@ -218,71 +277,15 @@ class Attractor extends engine_root_window_.ExternalInteractorBase {
218
277
  options.attract = new Attract();
219
278
  }
220
279
  for (const source of sources) {
221
- options.attract.load(source === null || source === void 0 ? void 0 : source.attract);
280
+ options.attract.load(source?.attract);
222
281
  }
223
282
  }
224
283
  reset() {}
225
- clickAttract() {
226
- const container = this.container;
227
- if (!container.attract) {
228
- container.attract = {
229
- particles: []
230
- };
231
- }
232
- if (!container.attract.finish) {
233
- if (!container.attract.count) {
234
- container.attract.count = 0;
235
- }
236
- container.attract.count++;
237
- if (container.attract.count === container.particles.count) {
238
- container.attract.finish = true;
239
- }
240
- }
241
- if (container.attract.clicking) {
242
- const mousePos = container.interactivity.mouse.clickPosition,
243
- attractRadius = container.retina.attractModeDistance;
244
- if (!attractRadius || attractRadius < 0 || !mousePos) {
245
- return;
246
- }
247
- this.processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius));
248
- } else if (container.attract.clicking === false) {
249
- container.attract.particles = [];
250
- }
251
- return;
252
- }
253
- hoverAttract() {
254
- const container = this.container,
255
- mousePos = container.interactivity.mouse.position,
256
- attractRadius = container.retina.attractModeDistance;
257
- if (!attractRadius || attractRadius < 0 || !mousePos) {
258
- return;
259
- }
260
- this.processAttract(mousePos, attractRadius, new engine_root_window_.Circle(mousePos.x, mousePos.y, attractRadius));
261
- }
262
- processAttract(position, attractRadius, area) {
263
- const container = this.container,
264
- attractOptions = container.actualOptions.interactivity.modes.attract;
265
- if (!attractOptions) {
266
- return;
267
- }
268
- const query = container.particles.quadTree.query(area, p => this.isEnabled(p));
269
- for (const particle of query) {
270
- const {
271
- dx,
272
- dy,
273
- distance
274
- } = (0,engine_root_window_.getDistances)(particle.position, position);
275
- const velocity = attractOptions.speed * attractOptions.factor;
276
- const attractFactor = (0,engine_root_window_.clamp)((0,engine_root_window_.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
277
- const normVec = engine_root_window_.Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
278
- particle.position.subFrom(normVec);
279
- }
280
- }
281
284
  }
282
285
  ;// CONCATENATED MODULE: ./dist/browser/index.js
283
286
 
284
- async function loadExternalAttractInteraction(engine) {
285
- await engine.addInteractor("externalAttract", container => new Attractor(engine, container));
287
+ async function loadExternalAttractInteraction(engine, refresh = true) {
288
+ await engine.addInteractor("externalAttract", container => new Attractor(engine, container), refresh);
286
289
  }
287
290
 
288
291
 
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.interaction.external.attract.min.js.LICENSE.txt */
2
- !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var a="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var i in a)("object"==typeof exports?exports:t)[i]=a[i]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},a={};function i(t){var r=a[t];if(void 0!==r)return r.exports;var c=a[t]={exports:{}};return e[t](c,c.exports,i),c.exports}i.d=(t,e)=>{for(var a in e)i.o(e,a)&&!i.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{i.r(r),i.d(r,{Attract:()=>e,loadExternalAttractInteraction:()=>c});var t=i(533);class e{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class a extends t.ExternalInteractorBase{constructor(t,e){super(e),this._engine=t,e.attract||(e.attract={particles:[]}),this.handleClickMode=t=>{const a=this.container.actualOptions.interactivity.modes.attract;if(a&&"attract"===t){e.attract||(e.attract={particles:[]}),e.attract.clicking=!0,e.attract.count=0;for(const t of e.attract.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);e.attract.particles=[],e.attract.finish=!1,setTimeout((()=>{e.destroyed||(e.attract||(e.attract={particles:[]}),e.attract.clicking=!1)}),1e3*a.duration)}}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.attract;e&&(t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const e=this.container,a=e.actualOptions,i=e.interactivity.status===t.mouseMoveEvent,r=a.interactivity.events,c=r.onHover.enable,n=r.onHover.mode,o=r.onClick.enable,s=r.onClick.mode;i&&c&&(0,t.isInArray)("attract",n)?this.hoverAttract():o&&(0,t.isInArray)("attract",s)&&this.clickAttract()}isEnabled(e){var a;const i=this.container,r=i.actualOptions,c=i.interactivity.mouse,n=(null!==(a=null==e?void 0:e.interactivity)&&void 0!==a?a:r.interactivity).events;if(!(c.position&&n.onHover.enable||c.clickPosition&&n.onClick.enable))return!1;const o=n.onHover.mode,s=n.onClick.mode;return(0,t.isInArray)("attract",o)||(0,t.isInArray)("attract",s)}loadModeOptions(t,...a){t.attract||(t.attract=new e);for(const e of a)t.attract.load(null==e?void 0:e.attract)}reset(){}clickAttract(){const e=this.container;if(e.attract||(e.attract={particles:[]}),e.attract.finish||(e.attract.count||(e.attract.count=0),e.attract.count++,e.attract.count===e.particles.count&&(e.attract.finish=!0)),e.attract.clicking){const a=e.interactivity.mouse.clickPosition,i=e.retina.attractModeDistance;if(!i||i<0||!a)return;this.processAttract(a,i,new t.Circle(a.x,a.y,i))}else!1===e.attract.clicking&&(e.attract.particles=[])}hoverAttract(){const e=this.container,a=e.interactivity.mouse.position,i=e.retina.attractModeDistance;!i||i<0||!a||this.processAttract(a,i,new t.Circle(a.x,a.y,i))}processAttract(e,a,i){const r=this.container,c=r.actualOptions.interactivity.modes.attract;if(!c)return;const n=r.particles.quadTree.query(i,(t=>this.isEnabled(t)));for(const i of n){const{dx:r,dy:n,distance:o}=(0,t.getDistances)(i.position,e),s=c.speed*c.factor,d=(0,t.clamp)((0,t.getEasing)(c.easing)(1-o/a)*s,0,c.maxSpeed),l=t.Vector.create(0===o?s:r/o*d,0===o?s:n/o*d);i.position.subFrom(l)}}}async function c(t){await t.addInteractor("externalAttract",(e=>new a(t,e)))}})(),r})()));
2
+ !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var i="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var a in i)("object"==typeof exports?exports:t)[a]=i[a]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},i={};function a(t){var r=i[t];if(void 0!==r)return r.exports;var n=i[t]={exports:{}};return e[t](n,n.exports,a),n.exports}a.d=(t,e)=>{for(var i in e)a.o(e,i)&&!a.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},a.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),a.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{a.r(r),a.d(r,{Attract:()=>e,loadExternalAttractInteraction:()=>n});var t=a(533);class e{constructor(){this.distance=200,this.duration=.4,this.easing="ease-out-quad",this.factor=1,this.maxSpeed=50,this.speed=1}load(t){t&&(void 0!==t.distance&&(this.distance=t.distance),void 0!==t.duration&&(this.duration=t.duration),void 0!==t.easing&&(this.easing=t.easing),void 0!==t.factor&&(this.factor=t.factor),void 0!==t.maxSpeed&&(this.maxSpeed=t.maxSpeed),void 0!==t.speed&&(this.speed=t.speed))}}class i extends t.ExternalInteractorBase{constructor(e,i){super(i),this._clickAttract=()=>{const e=this.container;e.attract||(e.attract={particles:[]});const{attract:i}=e;if(i.finish||(i.count||(i.count=0),i.count++,i.count===e.particles.count&&(i.finish=!0)),i.clicking){const i=e.interactivity.mouse.clickPosition,a=e.retina.attractModeDistance;if(!a||a<0||!i)return;this._processAttract(i,a,new t.Circle(i.x,i.y,a))}else!1===i.clicking&&(i.particles=[])},this._hoverAttract=()=>{const e=this.container,i=e.interactivity.mouse.position,a=e.retina.attractModeDistance;!a||a<0||!i||this._processAttract(i,a,new t.Circle(i.x,i.y,a))},this._processAttract=(e,i,a)=>{const r=this.container,n=r.actualOptions.interactivity.modes.attract;if(!n)return;const c=r.particles.quadTree.query(a,(t=>this.isEnabled(t)));for(const a of c){const{dx:r,dy:c,distance:o}=(0,t.getDistances)(a.position,e),s=n.speed*n.factor,d=(0,t.clamp)((0,t.getEasing)(n.easing)(1-o/i)*s,0,n.maxSpeed),l=t.Vector.create(0===o?s:r/o*d,0===o?s:c/o*d);a.position.subFrom(l)}},this._engine=e,i.attract||(i.attract={particles:[]}),this.handleClickMode=t=>{const e=this.container.actualOptions.interactivity.modes.attract;if(e&&"attract"===t){i.attract||(i.attract={particles:[]}),i.attract.clicking=!0,i.attract.count=0;for(const t of i.attract.particles)this.isEnabled(t)&&t.velocity.setTo(t.initialVelocity);i.attract.particles=[],i.attract.finish=!1,setTimeout((()=>{i.destroyed||(i.attract||(i.attract={particles:[]}),i.attract.clicking=!1)}),1e3*e.duration)}}}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity.modes.attract;e&&(t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}async interact(){const e=this.container,i=e.actualOptions,a=e.interactivity.status===t.mouseMoveEvent,r=i.interactivity.events,n=r.onHover.enable,c=r.onHover.mode,o=r.onClick.enable,s=r.onClick.mode;a&&n&&(0,t.isInArray)("attract",c)?this._hoverAttract():o&&(0,t.isInArray)("attract",s)&&this._clickAttract()}isEnabled(e){const i=this.container,a=i.actualOptions,r=i.interactivity.mouse,n=(e?.interactivity??a.interactivity).events;if(!(r.position&&n.onHover.enable||r.clickPosition&&n.onClick.enable))return!1;const c=n.onHover.mode,o=n.onClick.mode;return(0,t.isInArray)("attract",c)||(0,t.isInArray)("attract",o)}loadModeOptions(t,...i){t.attract||(t.attract=new e);for(const e of i)t.attract.load(e?.attract)}reset(){}}async function n(t,e=!0){await t.addInteractor("externalAttract",(e=>new i(t,e)),e)}})(),r})()));
@@ -1,8 +1 @@
1
- /*!
2
- * Author : Matteo Bruni
3
- * MIT license: https://opensource.org/licenses/MIT
4
- * Demo / Generator : https://particles.js.org/
5
- * GitHub : https://www.github.com/matteobruni/tsparticles
6
- * How to use? : Check the GitHub README
7
- * v3.0.0-alpha.1
8
- */
1
+ /*! tsParticles Attract External Interaction v3.0.0-beta.0 by Matteo Bruni */
@@ -1,6 +1,5 @@
1
1
  import type { AttractContainer, AttractMode, IAttractMode } from "./Types";
2
- import { ExternalInteractorBase } from "@tsparticles/engine";
3
- import type { Engine, IModes, Modes, Particle, RecursivePartial } from "@tsparticles/engine";
2
+ import { type Engine, ExternalInteractorBase, type IModes, type Modes, type Particle, type RecursivePartial } from "@tsparticles/engine";
4
3
  export declare class Attractor extends ExternalInteractorBase<AttractContainer> {
5
4
  handleClickMode: (mode: string) => void;
6
5
  private readonly _engine;
@@ -11,7 +10,7 @@ export declare class Attractor extends ExternalInteractorBase<AttractContainer>
11
10
  isEnabled(particle?: Particle): boolean;
12
11
  loadModeOptions(options: Modes & AttractMode, ...sources: RecursivePartial<(IModes & IAttractMode) | undefined>[]): void;
13
12
  reset(): void;
14
- private clickAttract;
15
- private hoverAttract;
16
- private processAttract;
13
+ private readonly _clickAttract;
14
+ private readonly _hoverAttract;
15
+ private readonly _processAttract;
17
16
  }
@@ -1,5 +1,4 @@
1
- import type { EasingTypeAlt, IOptionLoader, RecursivePartial } from "@tsparticles/engine";
2
- import { EasingType } from "@tsparticles/engine";
1
+ import { EasingType, type EasingTypeAlt, type IOptionLoader, type RecursivePartial } from "@tsparticles/engine";
3
2
  import type { IAttract } from "../Interfaces/IAttract";
4
3
  export declare class Attract implements IAttract, IOptionLoader<IAttract> {
5
4
  distance: number;
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { Engine } from "@tsparticles/engine";
2
- export declare function loadExternalAttractInteraction(engine: Engine): Promise<void>;
2
+ export declare function loadExternalAttractInteraction(engine: Engine, refresh?: boolean): Promise<void>;
3
3
  export * from "./Options/Classes/Attract";
4
4
  export * from "./Options/Interfaces/IAttract";
package/umd/Attractor.js CHANGED
@@ -15,6 +15,54 @@
15
15
  class Attractor extends engine_1.ExternalInteractorBase {
16
16
  constructor(engine, container) {
17
17
  super(container);
18
+ this._clickAttract = () => {
19
+ const container = this.container;
20
+ if (!container.attract) {
21
+ container.attract = { particles: [] };
22
+ }
23
+ const { attract } = container;
24
+ if (!attract.finish) {
25
+ if (!attract.count) {
26
+ attract.count = 0;
27
+ }
28
+ attract.count++;
29
+ if (attract.count === container.particles.count) {
30
+ attract.finish = true;
31
+ }
32
+ }
33
+ if (attract.clicking) {
34
+ const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance;
35
+ if (!attractRadius || attractRadius < 0 || !mousePos) {
36
+ return;
37
+ }
38
+ this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius));
39
+ }
40
+ else if (attract.clicking === false) {
41
+ attract.particles = [];
42
+ }
43
+ return;
44
+ };
45
+ this._hoverAttract = () => {
46
+ const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance;
47
+ if (!attractRadius || attractRadius < 0 || !mousePos) {
48
+ return;
49
+ }
50
+ this._processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius));
51
+ };
52
+ this._processAttract = (position, attractRadius, area) => {
53
+ const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract;
54
+ if (!attractOptions) {
55
+ return;
56
+ }
57
+ const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p));
58
+ for (const particle of query) {
59
+ const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position);
60
+ const velocity = attractOptions.speed * attractOptions.factor;
61
+ const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
62
+ const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor);
63
+ particle.position.subFrom(normVec);
64
+ }
65
+ };
18
66
  this._engine = engine;
19
67
  if (!container.attract) {
20
68
  container.attract = { particles: [] };
@@ -38,12 +86,13 @@
38
86
  container.attract.particles = [];
39
87
  container.attract.finish = false;
40
88
  setTimeout(() => {
41
- if (!container.destroyed) {
42
- if (!container.attract) {
43
- container.attract = { particles: [] };
44
- }
45
- container.attract.clicking = false;
89
+ if (container.destroyed) {
90
+ return;
91
+ }
92
+ if (!container.attract) {
93
+ container.attract = { particles: [] };
46
94
  }
95
+ container.attract.clicking = false;
47
96
  }, attract.duration * 1000);
48
97
  };
49
98
  }
@@ -59,15 +108,14 @@
59
108
  async interact() {
60
109
  const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === engine_1.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode;
61
110
  if (mouseMoveStatus && hoverEnabled && (0, engine_1.isInArray)("attract", hoverMode)) {
62
- this.hoverAttract();
111
+ this._hoverAttract();
63
112
  }
64
113
  else if (clickEnabled && (0, engine_1.isInArray)("attract", clickMode)) {
65
- this.clickAttract();
114
+ this._clickAttract();
66
115
  }
67
116
  }
68
117
  isEnabled(particle) {
69
- var _a;
70
- const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events;
118
+ const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events;
71
119
  if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) {
72
120
  return false;
73
121
  }
@@ -79,58 +127,11 @@
79
127
  options.attract = new Attract_1.Attract();
80
128
  }
81
129
  for (const source of sources) {
82
- options.attract.load(source === null || source === void 0 ? void 0 : source.attract);
130
+ options.attract.load(source?.attract);
83
131
  }
84
132
  }
85
133
  reset() {
86
134
  }
87
- clickAttract() {
88
- const container = this.container;
89
- if (!container.attract) {
90
- container.attract = { particles: [] };
91
- }
92
- if (!container.attract.finish) {
93
- if (!container.attract.count) {
94
- container.attract.count = 0;
95
- }
96
- container.attract.count++;
97
- if (container.attract.count === container.particles.count) {
98
- container.attract.finish = true;
99
- }
100
- }
101
- if (container.attract.clicking) {
102
- const mousePos = container.interactivity.mouse.clickPosition, attractRadius = container.retina.attractModeDistance;
103
- if (!attractRadius || attractRadius < 0 || !mousePos) {
104
- return;
105
- }
106
- this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius));
107
- }
108
- else if (container.attract.clicking === false) {
109
- container.attract.particles = [];
110
- }
111
- return;
112
- }
113
- hoverAttract() {
114
- const container = this.container, mousePos = container.interactivity.mouse.position, attractRadius = container.retina.attractModeDistance;
115
- if (!attractRadius || attractRadius < 0 || !mousePos) {
116
- return;
117
- }
118
- this.processAttract(mousePos, attractRadius, new engine_1.Circle(mousePos.x, mousePos.y, attractRadius));
119
- }
120
- processAttract(position, attractRadius, area) {
121
- const container = this.container, attractOptions = container.actualOptions.interactivity.modes.attract;
122
- if (!attractOptions) {
123
- return;
124
- }
125
- const query = container.particles.quadTree.query(area, (p) => this.isEnabled(p));
126
- for (const particle of query) {
127
- const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position);
128
- const velocity = attractOptions.speed * attractOptions.factor;
129
- const attractFactor = (0, engine_1.clamp)((0, engine_1.getEasing)(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
130
- const normVec = engine_1.Vector.create(distance === 0 ? velocity : (dx / distance) * attractFactor, distance === 0 ? velocity : (dy / distance) * attractFactor);
131
- particle.position.subFrom(normVec);
132
- }
133
- }
134
135
  }
135
136
  exports.Attractor = Attractor;
136
137
  });
package/umd/index.js CHANGED
@@ -25,8 +25,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.loadExternalAttractInteraction = void 0;
27
27
  const Attractor_1 = require("./Attractor");
28
- async function loadExternalAttractInteraction(engine) {
29
- await engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container));
28
+ async function loadExternalAttractInteraction(engine, refresh = true) {
29
+ await engine.addInteractor("externalAttract", (container) => new Attractor_1.Attractor(engine, container), refresh);
30
30
  }
31
31
  exports.loadExternalAttractInteraction = loadExternalAttractInteraction;
32
32
  __exportStar(require("./Options/Classes/Attract"), exports);