@tsparticles/interaction-external-attract 4.0.5 → 4.1.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.
- package/browser/Attractor.js +26 -26
- package/browser/index.js +1 -1
- package/browser/index.lazy.js +1 -1
- package/cjs/Attractor.js +26 -26
- package/cjs/index.js +1 -1
- package/cjs/index.lazy.js +1 -1
- package/esm/Attractor.js +26 -26
- package/esm/index.js +1 -1
- package/esm/index.lazy.js +1 -1
- package/package.json +3 -3
- package/tsparticles.interaction.external.attract.js +28 -28
- package/tsparticles.interaction.external.attract.min.js +1 -1
- package/types/Attractor.d.ts +1 -6
package/browser/Attractor.js
CHANGED
|
@@ -5,16 +5,16 @@ import { Attract } from "./Options/Classes/Attract.js";
|
|
|
5
5
|
const attractMode = "attract", minVelocityLengthSq = 0, minRestoreSpeed = 0.001, maxRestoreSpeed = 1, restoreEpsilon = 0.5;
|
|
6
6
|
export class Attractor extends ExternalInteractorBase {
|
|
7
7
|
handleClickMode;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
#interactedThisFrame;
|
|
9
|
+
#maxDistance;
|
|
10
|
+
#pluginManager;
|
|
11
|
+
#restoreData;
|
|
12
12
|
constructor(pluginManager, container) {
|
|
13
13
|
super(container);
|
|
14
|
-
this
|
|
15
|
-
this
|
|
16
|
-
this
|
|
17
|
-
this
|
|
14
|
+
this.#pluginManager = pluginManager;
|
|
15
|
+
this.#maxDistance = 0;
|
|
16
|
+
this.#interactedThisFrame = new Set();
|
|
17
|
+
this.#restoreData = new Map();
|
|
18
18
|
container.attract ??= { particles: [] };
|
|
19
19
|
this.handleClickMode = (mode, interactivityData) => {
|
|
20
20
|
const options = this.container.actualOptions, attract = options.interactivity?.modes.attract;
|
|
@@ -42,7 +42,7 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
get maxDistance() {
|
|
45
|
-
return this
|
|
45
|
+
return this.#maxDistance;
|
|
46
46
|
}
|
|
47
47
|
clear() {
|
|
48
48
|
}
|
|
@@ -51,27 +51,27 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
51
51
|
if (!attract) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
this
|
|
54
|
+
this.#maxDistance = attract.distance;
|
|
55
55
|
container.retina.attractModeDistance = attract.distance * container.retina.pixelRatio;
|
|
56
56
|
}
|
|
57
57
|
interact(interactivityData) {
|
|
58
|
-
this.
|
|
58
|
+
this.#interactedThisFrame.clear();
|
|
59
59
|
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
60
60
|
if (!events) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
const { enable: hoverEnabled, mode: hoverMode } = events.onHover, { enable: clickEnabled, mode: clickMode } = events.onClick;
|
|
64
64
|
if (mouseMoveStatus && hoverEnabled && isInArray(attractMode, hoverMode)) {
|
|
65
|
-
hoverAttract(this
|
|
66
|
-
this
|
|
65
|
+
hoverAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
66
|
+
this.#trackInteractedParticle(p);
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
else if (clickEnabled && isInArray(attractMode, clickMode)) {
|
|
70
|
-
clickAttract(this
|
|
71
|
-
this
|
|
70
|
+
clickAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
71
|
+
this.#trackInteractedParticle(p);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
-
this
|
|
74
|
+
this.#restoreParticles();
|
|
75
75
|
}
|
|
76
76
|
isEnabled(interactivityData, particle) {
|
|
77
77
|
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
@@ -89,18 +89,18 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
89
89
|
}
|
|
90
90
|
reset() {
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
#restoreParticles() {
|
|
93
93
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
94
|
-
if (!restore?.enable || !this.
|
|
94
|
+
if (!restore?.enable || !this.#restoreData.size) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
const now = Date.now(), restoreDelay = restore.delay * millisecondsToSeconds, restoreSpeed = Math.max(minRestoreSpeed, Math.min(maxRestoreSpeed, restore.speed));
|
|
98
|
-
for (const [particle, restoreData] of this
|
|
99
|
-
if (this.
|
|
98
|
+
for (const [particle, restoreData] of this.#restoreData) {
|
|
99
|
+
if (this.#interactedThisFrame.has(particle)) {
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
if (particle.destroyed) {
|
|
103
|
-
this.
|
|
103
|
+
this.#restoreData.delete(particle);
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
const target = restoreData.target;
|
|
@@ -124,25 +124,25 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
124
124
|
particle.position.x = target.x;
|
|
125
125
|
particle.position.y = target.y;
|
|
126
126
|
particle.position.z = target.z;
|
|
127
|
-
this.
|
|
127
|
+
this.#restoreData.delete(particle);
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
this.
|
|
132
|
+
#trackInteractedParticle(particle) {
|
|
133
|
+
this.#interactedThisFrame.add(particle);
|
|
134
134
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
135
135
|
if (!restore?.enable) {
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
138
|
const now = Date.now();
|
|
139
|
-
let restoreData = this.
|
|
139
|
+
let restoreData = this.#restoreData.get(particle);
|
|
140
140
|
if (!restoreData) {
|
|
141
141
|
restoreData = {
|
|
142
142
|
target: particle.position.copy(),
|
|
143
143
|
lastInteractionTime: now,
|
|
144
144
|
};
|
|
145
|
-
this.
|
|
145
|
+
this.#restoreData.set(particle, restoreData);
|
|
146
146
|
}
|
|
147
147
|
restoreData.lastInteractionTime = now;
|
|
148
148
|
}
|
package/browser/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ensureInteractivityPluginLoaded } from "@tsparticles/plugin-interactivity";
|
|
2
2
|
import { Attractor } from "./Attractor.js";
|
|
3
3
|
export async function loadExternalAttractInteraction(engine) {
|
|
4
|
-
engine.checkVersion("4.0
|
|
4
|
+
engine.checkVersion("4.1.0");
|
|
5
5
|
await engine.pluginManager.register((e) => {
|
|
6
6
|
ensureInteractivityPluginLoaded(e);
|
|
7
7
|
e.pluginManager.addInteractor?.("externalAttract", container => {
|
package/browser/index.lazy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalAttractInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0
|
|
2
|
+
engine.checkVersion("4.1.0");
|
|
3
3
|
await engine.pluginManager.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity/lazy");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
package/cjs/Attractor.js
CHANGED
|
@@ -5,16 +5,16 @@ import { Attract } from "./Options/Classes/Attract.js";
|
|
|
5
5
|
const attractMode = "attract", minVelocityLengthSq = 0, minRestoreSpeed = 0.001, maxRestoreSpeed = 1, restoreEpsilon = 0.5;
|
|
6
6
|
export class Attractor extends ExternalInteractorBase {
|
|
7
7
|
handleClickMode;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
#interactedThisFrame;
|
|
9
|
+
#maxDistance;
|
|
10
|
+
#pluginManager;
|
|
11
|
+
#restoreData;
|
|
12
12
|
constructor(pluginManager, container) {
|
|
13
13
|
super(container);
|
|
14
|
-
this
|
|
15
|
-
this
|
|
16
|
-
this
|
|
17
|
-
this
|
|
14
|
+
this.#pluginManager = pluginManager;
|
|
15
|
+
this.#maxDistance = 0;
|
|
16
|
+
this.#interactedThisFrame = new Set();
|
|
17
|
+
this.#restoreData = new Map();
|
|
18
18
|
container.attract ??= { particles: [] };
|
|
19
19
|
this.handleClickMode = (mode, interactivityData) => {
|
|
20
20
|
const options = this.container.actualOptions, attract = options.interactivity?.modes.attract;
|
|
@@ -42,7 +42,7 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
get maxDistance() {
|
|
45
|
-
return this
|
|
45
|
+
return this.#maxDistance;
|
|
46
46
|
}
|
|
47
47
|
clear() {
|
|
48
48
|
}
|
|
@@ -51,27 +51,27 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
51
51
|
if (!attract) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
this
|
|
54
|
+
this.#maxDistance = attract.distance;
|
|
55
55
|
container.retina.attractModeDistance = attract.distance * container.retina.pixelRatio;
|
|
56
56
|
}
|
|
57
57
|
interact(interactivityData) {
|
|
58
|
-
this.
|
|
58
|
+
this.#interactedThisFrame.clear();
|
|
59
59
|
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
60
60
|
if (!events) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
const { enable: hoverEnabled, mode: hoverMode } = events.onHover, { enable: clickEnabled, mode: clickMode } = events.onClick;
|
|
64
64
|
if (mouseMoveStatus && hoverEnabled && isInArray(attractMode, hoverMode)) {
|
|
65
|
-
hoverAttract(this
|
|
66
|
-
this
|
|
65
|
+
hoverAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
66
|
+
this.#trackInteractedParticle(p);
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
else if (clickEnabled && isInArray(attractMode, clickMode)) {
|
|
70
|
-
clickAttract(this
|
|
71
|
-
this
|
|
70
|
+
clickAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
71
|
+
this.#trackInteractedParticle(p);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
-
this
|
|
74
|
+
this.#restoreParticles();
|
|
75
75
|
}
|
|
76
76
|
isEnabled(interactivityData, particle) {
|
|
77
77
|
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
@@ -89,18 +89,18 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
89
89
|
}
|
|
90
90
|
reset() {
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
#restoreParticles() {
|
|
93
93
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
94
|
-
if (!restore?.enable || !this.
|
|
94
|
+
if (!restore?.enable || !this.#restoreData.size) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
const now = Date.now(), restoreDelay = restore.delay * millisecondsToSeconds, restoreSpeed = Math.max(minRestoreSpeed, Math.min(maxRestoreSpeed, restore.speed));
|
|
98
|
-
for (const [particle, restoreData] of this
|
|
99
|
-
if (this.
|
|
98
|
+
for (const [particle, restoreData] of this.#restoreData) {
|
|
99
|
+
if (this.#interactedThisFrame.has(particle)) {
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
if (particle.destroyed) {
|
|
103
|
-
this.
|
|
103
|
+
this.#restoreData.delete(particle);
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
const target = restoreData.target;
|
|
@@ -124,25 +124,25 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
124
124
|
particle.position.x = target.x;
|
|
125
125
|
particle.position.y = target.y;
|
|
126
126
|
particle.position.z = target.z;
|
|
127
|
-
this.
|
|
127
|
+
this.#restoreData.delete(particle);
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
this.
|
|
132
|
+
#trackInteractedParticle(particle) {
|
|
133
|
+
this.#interactedThisFrame.add(particle);
|
|
134
134
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
135
135
|
if (!restore?.enable) {
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
138
|
const now = Date.now();
|
|
139
|
-
let restoreData = this.
|
|
139
|
+
let restoreData = this.#restoreData.get(particle);
|
|
140
140
|
if (!restoreData) {
|
|
141
141
|
restoreData = {
|
|
142
142
|
target: particle.position.copy(),
|
|
143
143
|
lastInteractionTime: now,
|
|
144
144
|
};
|
|
145
|
-
this.
|
|
145
|
+
this.#restoreData.set(particle, restoreData);
|
|
146
146
|
}
|
|
147
147
|
restoreData.lastInteractionTime = now;
|
|
148
148
|
}
|
package/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ensureInteractivityPluginLoaded } from "@tsparticles/plugin-interactivity";
|
|
2
2
|
import { Attractor } from "./Attractor.js";
|
|
3
3
|
export async function loadExternalAttractInteraction(engine) {
|
|
4
|
-
engine.checkVersion("4.0
|
|
4
|
+
engine.checkVersion("4.1.0");
|
|
5
5
|
await engine.pluginManager.register((e) => {
|
|
6
6
|
ensureInteractivityPluginLoaded(e);
|
|
7
7
|
e.pluginManager.addInteractor?.("externalAttract", container => {
|
package/cjs/index.lazy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalAttractInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0
|
|
2
|
+
engine.checkVersion("4.1.0");
|
|
3
3
|
await engine.pluginManager.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity/lazy");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
package/esm/Attractor.js
CHANGED
|
@@ -5,16 +5,16 @@ import { Attract } from "./Options/Classes/Attract.js";
|
|
|
5
5
|
const attractMode = "attract", minVelocityLengthSq = 0, minRestoreSpeed = 0.001, maxRestoreSpeed = 1, restoreEpsilon = 0.5;
|
|
6
6
|
export class Attractor extends ExternalInteractorBase {
|
|
7
7
|
handleClickMode;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
#interactedThisFrame;
|
|
9
|
+
#maxDistance;
|
|
10
|
+
#pluginManager;
|
|
11
|
+
#restoreData;
|
|
12
12
|
constructor(pluginManager, container) {
|
|
13
13
|
super(container);
|
|
14
|
-
this
|
|
15
|
-
this
|
|
16
|
-
this
|
|
17
|
-
this
|
|
14
|
+
this.#pluginManager = pluginManager;
|
|
15
|
+
this.#maxDistance = 0;
|
|
16
|
+
this.#interactedThisFrame = new Set();
|
|
17
|
+
this.#restoreData = new Map();
|
|
18
18
|
container.attract ??= { particles: [] };
|
|
19
19
|
this.handleClickMode = (mode, interactivityData) => {
|
|
20
20
|
const options = this.container.actualOptions, attract = options.interactivity?.modes.attract;
|
|
@@ -42,7 +42,7 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
get maxDistance() {
|
|
45
|
-
return this
|
|
45
|
+
return this.#maxDistance;
|
|
46
46
|
}
|
|
47
47
|
clear() {
|
|
48
48
|
}
|
|
@@ -51,27 +51,27 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
51
51
|
if (!attract) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
this
|
|
54
|
+
this.#maxDistance = attract.distance;
|
|
55
55
|
container.retina.attractModeDistance = attract.distance * container.retina.pixelRatio;
|
|
56
56
|
}
|
|
57
57
|
interact(interactivityData) {
|
|
58
|
-
this.
|
|
58
|
+
this.#interactedThisFrame.clear();
|
|
59
59
|
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
60
60
|
if (!events) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
const { enable: hoverEnabled, mode: hoverMode } = events.onHover, { enable: clickEnabled, mode: clickMode } = events.onClick;
|
|
64
64
|
if (mouseMoveStatus && hoverEnabled && isInArray(attractMode, hoverMode)) {
|
|
65
|
-
hoverAttract(this
|
|
66
|
-
this
|
|
65
|
+
hoverAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
66
|
+
this.#trackInteractedParticle(p);
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
else if (clickEnabled && isInArray(attractMode, clickMode)) {
|
|
70
|
-
clickAttract(this
|
|
71
|
-
this
|
|
70
|
+
clickAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
71
|
+
this.#trackInteractedParticle(p);
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
-
this
|
|
74
|
+
this.#restoreParticles();
|
|
75
75
|
}
|
|
76
76
|
isEnabled(interactivityData, particle) {
|
|
77
77
|
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
@@ -89,18 +89,18 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
89
89
|
}
|
|
90
90
|
reset() {
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
#restoreParticles() {
|
|
93
93
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
94
|
-
if (!restore?.enable || !this.
|
|
94
|
+
if (!restore?.enable || !this.#restoreData.size) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
const now = Date.now(), restoreDelay = restore.delay * millisecondsToSeconds, restoreSpeed = Math.max(minRestoreSpeed, Math.min(maxRestoreSpeed, restore.speed));
|
|
98
|
-
for (const [particle, restoreData] of this
|
|
99
|
-
if (this.
|
|
98
|
+
for (const [particle, restoreData] of this.#restoreData) {
|
|
99
|
+
if (this.#interactedThisFrame.has(particle)) {
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
if (particle.destroyed) {
|
|
103
|
-
this.
|
|
103
|
+
this.#restoreData.delete(particle);
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
106
|
const target = restoreData.target;
|
|
@@ -124,25 +124,25 @@ export class Attractor extends ExternalInteractorBase {
|
|
|
124
124
|
particle.position.x = target.x;
|
|
125
125
|
particle.position.y = target.y;
|
|
126
126
|
particle.position.z = target.z;
|
|
127
|
-
this.
|
|
127
|
+
this.#restoreData.delete(particle);
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
this.
|
|
132
|
+
#trackInteractedParticle(particle) {
|
|
133
|
+
this.#interactedThisFrame.add(particle);
|
|
134
134
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
135
135
|
if (!restore?.enable) {
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
138
|
const now = Date.now();
|
|
139
|
-
let restoreData = this.
|
|
139
|
+
let restoreData = this.#restoreData.get(particle);
|
|
140
140
|
if (!restoreData) {
|
|
141
141
|
restoreData = {
|
|
142
142
|
target: particle.position.copy(),
|
|
143
143
|
lastInteractionTime: now,
|
|
144
144
|
};
|
|
145
|
-
this.
|
|
145
|
+
this.#restoreData.set(particle, restoreData);
|
|
146
146
|
}
|
|
147
147
|
restoreData.lastInteractionTime = now;
|
|
148
148
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ensureInteractivityPluginLoaded } from "@tsparticles/plugin-interactivity";
|
|
2
2
|
import { Attractor } from "./Attractor.js";
|
|
3
3
|
export async function loadExternalAttractInteraction(engine) {
|
|
4
|
-
engine.checkVersion("4.0
|
|
4
|
+
engine.checkVersion("4.1.0");
|
|
5
5
|
await engine.pluginManager.register((e) => {
|
|
6
6
|
ensureInteractivityPluginLoaded(e);
|
|
7
7
|
e.pluginManager.addInteractor?.("externalAttract", container => {
|
package/esm/index.lazy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalAttractInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0
|
|
2
|
+
engine.checkVersion("4.1.0");
|
|
3
3
|
await engine.pluginManager.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity/lazy");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/interaction-external-attract",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "tsParticles attract external interaction",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
},
|
|
98
98
|
"type": "module",
|
|
99
99
|
"peerDependencies": {
|
|
100
|
-
"@tsparticles/engine": "4.0
|
|
101
|
-
"@tsparticles/plugin-interactivity": "4.0
|
|
100
|
+
"@tsparticles/engine": "4.1.0",
|
|
101
|
+
"@tsparticles/plugin-interactivity": "4.1.0"
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
|
|
2
|
-
/* External Interaction v4.0
|
|
2
|
+
/* External Interaction v4.1.0 */
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tsparticles/plugin-interactivity'), require('@tsparticles/engine')) :
|
|
5
5
|
typeof define === 'function' && define.amd ? define(['exports', '@tsparticles/plugin-interactivity', '@tsparticles/engine'], factory) :
|
|
@@ -106,16 +106,16 @@
|
|
|
106
106
|
const attractMode = "attract", minVelocityLengthSq = 0, minRestoreSpeed = 0.001, maxRestoreSpeed = 1, restoreEpsilon = 0.5;
|
|
107
107
|
class Attractor extends pluginInteractivity.ExternalInteractorBase {
|
|
108
108
|
handleClickMode;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
#interactedThisFrame;
|
|
110
|
+
#maxDistance;
|
|
111
|
+
#pluginManager;
|
|
112
|
+
#restoreData;
|
|
113
113
|
constructor(pluginManager, container) {
|
|
114
114
|
super(container);
|
|
115
|
-
this
|
|
116
|
-
this
|
|
117
|
-
this
|
|
118
|
-
this
|
|
115
|
+
this.#pluginManager = pluginManager;
|
|
116
|
+
this.#maxDistance = 0;
|
|
117
|
+
this.#interactedThisFrame = new Set();
|
|
118
|
+
this.#restoreData = new Map();
|
|
119
119
|
container.attract ??= { particles: [] };
|
|
120
120
|
this.handleClickMode = (mode, interactivityData) => {
|
|
121
121
|
const options = this.container.actualOptions, attract = options.interactivity?.modes.attract;
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
get maxDistance() {
|
|
146
|
-
return this
|
|
146
|
+
return this.#maxDistance;
|
|
147
147
|
}
|
|
148
148
|
clear() {
|
|
149
149
|
}
|
|
@@ -152,27 +152,27 @@
|
|
|
152
152
|
if (!attract) {
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
this
|
|
155
|
+
this.#maxDistance = attract.distance;
|
|
156
156
|
container.retina.attractModeDistance = attract.distance * container.retina.pixelRatio;
|
|
157
157
|
}
|
|
158
158
|
interact(interactivityData) {
|
|
159
|
-
this.
|
|
159
|
+
this.#interactedThisFrame.clear();
|
|
160
160
|
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === pluginInteractivity.mouseMoveEvent, events = options.interactivity?.events;
|
|
161
161
|
if (!events) {
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
164
164
|
const { enable: hoverEnabled, mode: hoverMode } = events.onHover, { enable: clickEnabled, mode: clickMode } = events.onClick;
|
|
165
165
|
if (mouseMoveStatus && hoverEnabled && engine.isInArray(attractMode, hoverMode)) {
|
|
166
|
-
hoverAttract(this
|
|
167
|
-
this
|
|
166
|
+
hoverAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
167
|
+
this.#trackInteractedParticle(p);
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
170
|
else if (clickEnabled && engine.isInArray(attractMode, clickMode)) {
|
|
171
|
-
clickAttract(this
|
|
172
|
-
this
|
|
171
|
+
clickAttract(this.#pluginManager, this.container, interactivityData, p => this.isEnabled(interactivityData, p), p => {
|
|
172
|
+
this.#trackInteractedParticle(p);
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
|
-
this
|
|
175
|
+
this.#restoreParticles();
|
|
176
176
|
}
|
|
177
177
|
isEnabled(interactivityData, particle) {
|
|
178
178
|
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
@@ -190,18 +190,18 @@
|
|
|
190
190
|
}
|
|
191
191
|
reset() {
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
#restoreParticles() {
|
|
194
194
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
195
|
-
if (!restore?.enable || !this.
|
|
195
|
+
if (!restore?.enable || !this.#restoreData.size) {
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
198
|
const now = Date.now(), restoreDelay = restore.delay * engine.millisecondsToSeconds, restoreSpeed = Math.max(minRestoreSpeed, Math.min(maxRestoreSpeed, restore.speed));
|
|
199
|
-
for (const [particle, restoreData] of this
|
|
200
|
-
if (this.
|
|
199
|
+
for (const [particle, restoreData] of this.#restoreData) {
|
|
200
|
+
if (this.#interactedThisFrame.has(particle)) {
|
|
201
201
|
continue;
|
|
202
202
|
}
|
|
203
203
|
if (particle.destroyed) {
|
|
204
|
-
this.
|
|
204
|
+
this.#restoreData.delete(particle);
|
|
205
205
|
continue;
|
|
206
206
|
}
|
|
207
207
|
const target = restoreData.target;
|
|
@@ -225,32 +225,32 @@
|
|
|
225
225
|
particle.position.x = target.x;
|
|
226
226
|
particle.position.y = target.y;
|
|
227
227
|
particle.position.z = target.z;
|
|
228
|
-
this.
|
|
228
|
+
this.#restoreData.delete(particle);
|
|
229
229
|
continue;
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
-
|
|
234
|
-
this.
|
|
233
|
+
#trackInteractedParticle(particle) {
|
|
234
|
+
this.#interactedThisFrame.add(particle);
|
|
235
235
|
const restore = this.container.actualOptions.interactivity?.modes.attract?.restore;
|
|
236
236
|
if (!restore?.enable) {
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
const now = Date.now();
|
|
240
|
-
let restoreData = this.
|
|
240
|
+
let restoreData = this.#restoreData.get(particle);
|
|
241
241
|
if (!restoreData) {
|
|
242
242
|
restoreData = {
|
|
243
243
|
target: particle.position.copy(),
|
|
244
244
|
lastInteractionTime: now,
|
|
245
245
|
};
|
|
246
|
-
this.
|
|
246
|
+
this.#restoreData.set(particle, restoreData);
|
|
247
247
|
}
|
|
248
248
|
restoreData.lastInteractionTime = now;
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
async function loadExternalAttractInteraction(engine) {
|
|
253
|
-
engine.checkVersion("4.0
|
|
253
|
+
engine.checkVersion("4.1.0");
|
|
254
254
|
await engine.pluginManager.register((e) => {
|
|
255
255
|
pluginInteractivity.ensureInteractivityPluginLoaded(e);
|
|
256
256
|
e.pluginManager.addInteractor?.("externalAttract", container => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t){t.__tsParticlesInternals=t.__tsParticlesInternals||{},t.__tsParticlesInternals.bundles=t.__tsParticlesInternals.bundles||{},t.__tsParticlesInternals.effects=t.__tsParticlesInternals.effects||{},t.__tsParticlesInternals.engine=t.__tsParticlesInternals.engine||{},t.__tsParticlesInternals.interactions=t.__tsParticlesInternals.interactions||{},t.__tsParticlesInternals.palettes=t.__tsParticlesInternals.palettes||{},t.__tsParticlesInternals.paths=t.__tsParticlesInternals.paths||{},t.__tsParticlesInternals.plugins=t.__tsParticlesInternals.plugins||{},t.__tsParticlesInternals.plugins=t.__tsParticlesInternals.plugins||{},t.__tsParticlesInternals.plugins.emittersShapes=t.__tsParticlesInternals.plugins.emittersShapes||{},t.__tsParticlesInternals.presets=t.__tsParticlesInternals.presets||{},t.__tsParticlesInternals.shapes=t.__tsParticlesInternals.shapes||{},t.__tsParticlesInternals.updaters=t.__tsParticlesInternals.updaters||{},t.__tsParticlesInternals.utils=t.__tsParticlesInternals.utils||{},t.__tsParticlesInternals.canvas=t.__tsParticlesInternals.canvas||{},t.__tsParticlesInternals.canvas=t.__tsParticlesInternals.canvas||{},t.__tsParticlesInternals.canvas.utils=t.__tsParticlesInternals.canvas.utils||{},t.__tsParticlesInternals.path=t.__tsParticlesInternals.path||{},t.__tsParticlesInternals.path=t.__tsParticlesInternals.path||{},t.__tsParticlesInternals.path.utils=t.__tsParticlesInternals.path.utils||{};var e="undefined"!=typeof Proxy?function(t){return new Proxy(t,{get:function(t,e){return e in t||(t[e]={}),t[e]}})}:function(t){return t};t.__tsParticlesInternals.bundles=e(t.__tsParticlesInternals.bundles),t.__tsParticlesInternals.effects=e(t.__tsParticlesInternals.effects),t.__tsParticlesInternals.interactions=e(t.__tsParticlesInternals.interactions),t.__tsParticlesInternals.palettes=e(t.__tsParticlesInternals.palettes),t.__tsParticlesInternals.paths=e(t.__tsParticlesInternals.paths),t.__tsParticlesInternals.plugins=e(t.__tsParticlesInternals.plugins),t.__tsParticlesInternals.plugins.emittersShapes=e(t.__tsParticlesInternals.plugins.emittersShapes),t.__tsParticlesInternals.presets=e(t.__tsParticlesInternals.presets),t.__tsParticlesInternals.shapes=e(t.__tsParticlesInternals.shapes),t.__tsParticlesInternals.updaters=e(t.__tsParticlesInternals.updaters),t.__tsParticlesInternals.utils=e(t.__tsParticlesInternals.utils),t.__tsParticlesInternals.canvas=e(t.__tsParticlesInternals.canvas),t.__tsParticlesInternals.path=e(t.__tsParticlesInternals.path),t.tsparticlesInternalExports=t.tsparticlesInternalExports||{}}("undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:this),function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@tsparticles/plugin-interactivity"),require("@tsparticles/engine")):"function"==typeof define&&define.amd?define(["exports","@tsparticles/plugin-interactivity","@tsparticles/engine"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).__tsParticlesInternals=t.__tsParticlesInternals||{},t.__tsParticlesInternals.interactions=t.__tsParticlesInternals.interactions||{},t.__tsParticlesInternals.interactions.externalAttract=t.__tsParticlesInternals.interactions.externalAttract||{}),t.__tsParticlesInternals.plugins.interactivity,t.__tsParticlesInternals.engine)}(this,function(t,e,s){"use strict";const a=s.Vector.origin;function n(t,e,n,i,r,l,c){const o=e.actualOptions.interactivity?.modes.attract;if(!o)return;const _=e.particles.grid.query(r,l);for(const e of _){const{dx:r,dy:l,distance:_}=s.getDistances(e.position,n),d=o.speed*o.factor,p=s.clamp(t.getEasing(o.easing)(s.identity-_/i)*d,1,o.maxSpeed);a.x=_?r/_*p:d,a.y=_?l/_*p:d,c?.(e),e.position.subFrom(a)}}class i{distance;duration;easing;factor;maxSpeed;restore;speed;constructor(){this.distance=200,this.duration=.4,this.easing=s.EasingType.easeOutQuad,this.factor=1,this.maxSpeed=50,this.speed=1,this.restore={enable:!1,delay:0,speed:.08,follow:!0}}load(t){s.isNull(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),void 0!==t.restore&&(this.restore.enable=t.restore.enable??this.restore.enable,this.restore.delay=t.restore.delay??this.restore.delay,this.restore.speed=t.restore.speed??this.restore.speed,this.restore.follow=t.restore.follow??this.restore.follow))}}const r="attract";class l extends e.ExternalInteractorBase{handleClickMode;
|
|
1
|
+
!function(t){t.__tsParticlesInternals=t.__tsParticlesInternals||{},t.__tsParticlesInternals.bundles=t.__tsParticlesInternals.bundles||{},t.__tsParticlesInternals.effects=t.__tsParticlesInternals.effects||{},t.__tsParticlesInternals.engine=t.__tsParticlesInternals.engine||{},t.__tsParticlesInternals.interactions=t.__tsParticlesInternals.interactions||{},t.__tsParticlesInternals.palettes=t.__tsParticlesInternals.palettes||{},t.__tsParticlesInternals.paths=t.__tsParticlesInternals.paths||{},t.__tsParticlesInternals.plugins=t.__tsParticlesInternals.plugins||{},t.__tsParticlesInternals.plugins=t.__tsParticlesInternals.plugins||{},t.__tsParticlesInternals.plugins.emittersShapes=t.__tsParticlesInternals.plugins.emittersShapes||{},t.__tsParticlesInternals.presets=t.__tsParticlesInternals.presets||{},t.__tsParticlesInternals.shapes=t.__tsParticlesInternals.shapes||{},t.__tsParticlesInternals.updaters=t.__tsParticlesInternals.updaters||{},t.__tsParticlesInternals.utils=t.__tsParticlesInternals.utils||{},t.__tsParticlesInternals.canvas=t.__tsParticlesInternals.canvas||{},t.__tsParticlesInternals.canvas=t.__tsParticlesInternals.canvas||{},t.__tsParticlesInternals.canvas.utils=t.__tsParticlesInternals.canvas.utils||{},t.__tsParticlesInternals.path=t.__tsParticlesInternals.path||{},t.__tsParticlesInternals.path=t.__tsParticlesInternals.path||{},t.__tsParticlesInternals.path.utils=t.__tsParticlesInternals.path.utils||{};var e="undefined"!=typeof Proxy?function(t){return new Proxy(t,{get:function(t,e){return e in t||(t[e]={}),t[e]}})}:function(t){return t};t.__tsParticlesInternals.bundles=e(t.__tsParticlesInternals.bundles),t.__tsParticlesInternals.effects=e(t.__tsParticlesInternals.effects),t.__tsParticlesInternals.interactions=e(t.__tsParticlesInternals.interactions),t.__tsParticlesInternals.palettes=e(t.__tsParticlesInternals.palettes),t.__tsParticlesInternals.paths=e(t.__tsParticlesInternals.paths),t.__tsParticlesInternals.plugins=e(t.__tsParticlesInternals.plugins),t.__tsParticlesInternals.plugins.emittersShapes=e(t.__tsParticlesInternals.plugins.emittersShapes),t.__tsParticlesInternals.presets=e(t.__tsParticlesInternals.presets),t.__tsParticlesInternals.shapes=e(t.__tsParticlesInternals.shapes),t.__tsParticlesInternals.updaters=e(t.__tsParticlesInternals.updaters),t.__tsParticlesInternals.utils=e(t.__tsParticlesInternals.utils),t.__tsParticlesInternals.canvas=e(t.__tsParticlesInternals.canvas),t.__tsParticlesInternals.path=e(t.__tsParticlesInternals.path),t.tsparticlesInternalExports=t.tsparticlesInternalExports||{}}("undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:this),function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@tsparticles/plugin-interactivity"),require("@tsparticles/engine")):"function"==typeof define&&define.amd?define(["exports","@tsparticles/plugin-interactivity","@tsparticles/engine"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).__tsParticlesInternals=t.__tsParticlesInternals||{},t.__tsParticlesInternals.interactions=t.__tsParticlesInternals.interactions||{},t.__tsParticlesInternals.interactions.externalAttract=t.__tsParticlesInternals.interactions.externalAttract||{}),t.__tsParticlesInternals.plugins.interactivity,t.__tsParticlesInternals.engine)}(this,function(t,e,s){"use strict";const a=s.Vector.origin;function n(t,e,n,i,r,l,c){const o=e.actualOptions.interactivity?.modes.attract;if(!o)return;const _=e.particles.grid.query(r,l);for(const e of _){const{dx:r,dy:l,distance:_}=s.getDistances(e.position,n),d=o.speed*o.factor,p=s.clamp(t.getEasing(o.easing)(s.identity-_/i)*d,1,o.maxSpeed);a.x=_?r/_*p:d,a.y=_?l/_*p:d,c?.(e),e.position.subFrom(a)}}class i{distance;duration;easing;factor;maxSpeed;restore;speed;constructor(){this.distance=200,this.duration=.4,this.easing=s.EasingType.easeOutQuad,this.factor=1,this.maxSpeed=50,this.speed=1,this.restore={enable:!1,delay:0,speed:.08,follow:!0}}load(t){s.isNull(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),void 0!==t.restore&&(this.restore.enable=t.restore.enable??this.restore.enable,this.restore.delay=t.restore.delay??this.restore.delay,this.restore.speed=t.restore.speed??this.restore.speed,this.restore.follow=t.restore.follow??this.restore.follow))}}const r="attract";class l extends e.ExternalInteractorBase{handleClickMode;#t;#e;#s;#a;constructor(t,e){super(e),this.#s=t,this.#e=0,this.#t=new Set,this.#a=new Map,e.attract??={particles:[]},this.handleClickMode=(t,a)=>{const n=this.container.actualOptions,i=n.interactivity?.modes.attract;if(i&&t===r){e.attract??={particles:[]},e.attract.clicking=!0,e.attract.count=0;for(const t of e.attract.particles)this.isEnabled(a,t)&&t.velocity.setTo(t.initialVelocity);e.attract.particles=[],e.attract.finish=!1,setTimeout(()=>{e.destroyed||(e.attract??={particles:[]},e.attract.clicking=!1)},i.duration*s.millisecondsToSeconds)}}}get maxDistance(){return this.#e}clear(){}init(){const t=this.container,e=t.actualOptions.interactivity?.modes.attract;e&&(this.#e=e.distance,t.retina.attractModeDistance=e.distance*t.retina.pixelRatio)}interact(t){this.#t.clear();const a=this.container.actualOptions,i=t.status===e.mouseMoveEvent,l=a.interactivity?.events;if(!l)return;const{enable:c,mode:o}=l.onHover,{enable:_,mode:d}=l.onClick;i&&c&&s.isInArray(r,o)?function(t,e,a,i,r){const l=a.mouse.position,c=e.retina.attractModeDistance;!c||c<0||!l||n(t,e,l,c,new s.Circle(l.x,l.y,c),t=>i(t),r)}(this.#s,this.container,t,e=>this.isEnabled(t,e),t=>{this.#n(t)}):_&&s.isInArray(r,d)&&function(t,e,a,i,r){e.attract??={particles:[]};const{attract:l}=e;if(l.finish||(l.count??=0,l.count++,l.count===e.particles.count&&(l.finish=!0)),l.clicking){const l=a.mouse.clickPosition,c=e.retina.attractModeDistance;if(!c||c<0||!l)return;n(t,e,l,c,new s.Circle(l.x,l.y,c),t=>i(t),r)}else!1===l.clicking&&(l.particles=[])}(this.#s,this.container,t,e=>this.isEnabled(t,e),t=>{this.#n(t)}),this.#i()}isEnabled(t,e){const a=this.container.actualOptions,n=t.mouse,i=(e?.interactivity??a.interactivity)?.events;if(!(n.position&&i?.onHover.enable||n.clickPosition&&i?.onClick.enable))return!1;const l=i.onHover.mode,c=i.onClick.mode;return s.isInArray(r,l)||s.isInArray(r,c)}loadModeOptions(t,...e){t.attract??=new i;for(const s of e)t.attract.load(s?.attract)}reset(){}#i(){const t=this.container.actualOptions.interactivity?.modes.attract?.restore;if(!t?.enable||!this.#a.size)return;const e=Date.now(),a=t.delay*s.millisecondsToSeconds,n=Math.max(.001,Math.min(1,t.speed));for(const[s,i]of this.#a){if(this.#t.has(s))continue;if(s.destroyed){this.#a.delete(s);continue}const r=i.target;if(e-i.lastInteractionTime<a)continue;let l=r.x-s.position.x,c=r.y-s.position.y,o=r.z-s.position.z;if(t.follow&&s.options.move.enable){const{x:t,y:e,z:a}=s.velocity,n=t*t+e*e+a*a;if(n>0){const s=(l*t+c*e+o*a)/n;l-=t*s,c-=e*s,o-=a*s}}s.position.x+=l*n,s.position.y+=c*n,s.position.z+=o*n,Math.abs(l)<=.5&&Math.abs(c)<=.5&&(s.position.x=r.x,s.position.y=r.y,s.position.z=r.z,this.#a.delete(s))}}#n(t){this.#t.add(t);const e=this.container.actualOptions.interactivity?.modes.attract?.restore;if(!e?.enable)return;const s=Date.now();let a=this.#a.get(t);a||(a={target:t.position.copy(),lastInteractionTime:s},this.#a.set(t,a)),a.lastInteractionTime=s}}async function c(t){t.checkVersion("4.1.0"),await t.pluginManager.register(t=>{e.ensureInteractivityPluginLoaded(t),t.pluginManager.addInteractor?.("externalAttract",e=>Promise.resolve(new l(t.pluginManager,e)))})}const o=globalThis;o.__tsParticlesInternals=o.__tsParticlesInternals??{},o.loadExternalAttractInteraction=c,t.Attract=i,t.loadExternalAttractInteraction=c}),Object.assign(globalThis.window||globalThis,{loadExternalAttractInteraction:(globalThis.__tsParticlesInternals.interactions.externalAttract||{}).loadExternalAttractInteraction}),delete(globalThis.window||globalThis).tsparticlesInternalExports;
|
package/types/Attractor.d.ts
CHANGED
|
@@ -2,11 +2,8 @@ import type { AttractContainer, AttractMode, IAttractMode } from "./Types.js";
|
|
|
2
2
|
import { ExternalInteractorBase, type IInteractivityData, type IModes, type InteractivityParticle, type Modes } from "@tsparticles/plugin-interactivity";
|
|
3
3
|
import { type PluginManager, type RecursivePartial } from "@tsparticles/engine";
|
|
4
4
|
export declare class Attractor extends ExternalInteractorBase<AttractContainer> {
|
|
5
|
+
#private;
|
|
5
6
|
handleClickMode: (mode: string, interactivityData: IInteractivityData) => void;
|
|
6
|
-
private readonly _interactedThisFrame;
|
|
7
|
-
private _maxDistance;
|
|
8
|
-
private readonly _pluginManager;
|
|
9
|
-
private readonly _restoreData;
|
|
10
7
|
constructor(pluginManager: PluginManager, container: AttractContainer);
|
|
11
8
|
get maxDistance(): number;
|
|
12
9
|
clear(): void;
|
|
@@ -15,6 +12,4 @@ export declare class Attractor extends ExternalInteractorBase<AttractContainer>
|
|
|
15
12
|
isEnabled(interactivityData: IInteractivityData, particle?: InteractivityParticle): boolean;
|
|
16
13
|
loadModeOptions(options: Modes & AttractMode, ...sources: RecursivePartial<(IModes & IAttractMode) | undefined>[]): void;
|
|
17
14
|
reset(): void;
|
|
18
|
-
private _restoreParticles;
|
|
19
|
-
private _trackInteractedParticle;
|
|
20
15
|
}
|