@tsparticles/interaction-external-repulse 4.0.0-alpha.24 → 4.0.0-alpha.26
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/504.min.js +1 -0
- package/browser/Repulser.js +20 -7
- package/browser/index.js +1 -1
- package/cjs/Repulser.js +20 -7
- package/cjs/index.js +1 -1
- package/dist_browser_Repulser_js.js +2 -2
- package/esm/Repulser.js +20 -7
- package/esm/index.js +1 -1
- package/package.json +3 -3
- package/report.html +1 -1
- package/tsparticles.interaction.external.repulse.js +2 -2
- package/tsparticles.interaction.external.repulse.min.js +2 -2
- package/types/Repulser.d.ts +4 -0
- package/umd/Repulser.js +20 -7
- package/umd/index.js +1 -1
- package/780.min.js +0 -1
package/504.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).push([[504],{504(e,t,i){i.d(t,{Repulser:()=>c});var s=i(303),n=i(702),l=i(686);let r="repulse";class c extends n.ExternalInteractorBase{handleClickMode;_clickVec;_engine;_maxDistance;_normVec;constructor(e,t){super(t),this._engine=e,this._maxDistance=0,this._normVec=s.Vector.origin,this._clickVec=s.Vector.origin,t.repulse??={particles:[]},this.handleClickMode=(e,i)=>{let n=this.container.actualOptions,l=n.interactivity?.modes.repulse;if(!l||e!==r)return;t.repulse??={particles:[]};let c=t.repulse;for(let e of(c.clicking=!0,c.count=0,t.repulse.particles))this.isEnabled(i,e)&&e.velocity.setTo(e.initialVelocity);c.particles=[],c.finish=!1,setTimeout(()=>{t.destroyed||(c.clicking=!1)},l.duration*s.millisecondsToSeconds)}}get maxDistance(){return this._maxDistance}clear(){}init(){let e=this.container,t=e.actualOptions.interactivity?.modes.repulse;t&&(this._maxDistance=t.distance,e.retina.repulseModeDistance=t.distance*e.retina.pixelRatio)}interact(e){let t=this.container.actualOptions,i=e.status===n.mouseMoveEvent,l=t.interactivity?.events;if(!l)return;let c=l.onHover,o=c.enable,a=c.mode,p=l.onClick,u=p.enable,h=p.mode,d=l.onDiv;i&&o&&(0,s.isInArray)(r,a)?this._hoverRepulse(e):u&&(0,s.isInArray)(r,h)?this._clickRepulse(e):(0,n.divModeExecute)(r,d,(t,i)=>{this._singleSelectorRepulse(e,t,i)})}isEnabled(e,t){let i=this.container.actualOptions,l=e.mouse,c=(t?.interactivity??i.interactivity)?.events;if(!c)return!1;let o=c.onDiv,a=c.onHover,p=c.onClick,u=(0,n.isDivModeEnabled)(r,o);if(!(u||a.enable&&l.position||p.enable&&l.clickPosition))return!1;let h=a.mode,d=p.mode;return(0,s.isInArray)(r,h)||(0,s.isInArray)(r,d)||u}loadModeOptions(e,...t){for(let i of(e.repulse??=new l.Z,t))e.repulse.load(i?.repulse)}reset(){}_clickRepulse=e=>{let t=this.container,i=t.actualOptions.interactivity?.modes.repulse;if(!i)return;let n=t.repulse??{particles:[]};if(n.finish||(n.count??=0,n.count++,n.count===t.particles.count&&(n.finish=!0)),n.clicking){let l=t.retina.repulseModeDistance;if(!l||l<0)return;let r=Math.pow(l/6,3),c=e.mouse.clickPosition;if(void 0===c)return;let o=new s.Circle(c.x,c.y,r);for(let l of t.particles.grid.query(o,t=>this.isEnabled(e,t))){let{dx:e,dy:t,distance:o}=(0,s.getDistances)(c,l.position),a=o**2,p=-r*i.speed/a;a<=r&&(n.particles.push(l),this._clickVec.x=e,this._clickVec.y=t,this._clickVec.length=p,l.velocity.setTo(this._clickVec))}}else if(!1===n.clicking){for(let e of n.particles)e.velocity.setTo(e.initialVelocity);n.particles=[]}};_hoverRepulse=e=>{let t=this.container,i=e.mouse.position,n=t.retina.repulseModeDistance;n&&!(n<0)&&i&&this._processRepulse(e,i,n,new s.Circle(i.x,i.y,n))};_processRepulse=(e,t,i,n,l)=>{let r=this.container,c=r.particles.grid.query(n,t=>this.isEnabled(e,t)),o=r.actualOptions.interactivity?.modes.repulse;if(!o)return;let{easing:a,speed:p,factor:u,maxSpeed:h}=o,d=this._engine.getEasing(a),f=(l?.speed??p)*u;for(let e of c){let{dx:n,dy:l,distance:r}=(0,s.getDistances)(e.position,t),c=(0,s.clamp)(d(1-r/i)*f,0,h);this._normVec.x=r?n/r*c:f,this._normVec.y=r?l/r*c:f,e.position.addTo(this._normVec)}};_singleSelectorRepulse=(e,t,i)=>{let l=this.container,r=l.actualOptions.interactivity?.modes.repulse;if(!r)return;let c=(0,s.safeDocument)().querySelectorAll(t);c.length&&c.forEach(t=>{let c=l.retina.pixelRatio,o={x:(t.offsetLeft+t.offsetWidth*s.half)*c,y:(t.offsetTop+t.offsetHeight*s.half)*c},a=t.offsetWidth*s.half*c,p=i.type===n.DivType.circle?new s.Circle(o.x,o.y,a):new s.Rectangle(t.offsetLeft*c,t.offsetTop*c,t.offsetWidth*c,t.offsetHeight*c),u=r.divs,h=(0,n.divMode)(u,t);this._processRepulse(e,o,a,p,h)})}}}}]);
|
package/browser/Repulser.js
CHANGED
|
@@ -4,10 +4,16 @@ import { Repulse } from "./Options/Classes/Repulse.js";
|
|
|
4
4
|
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
5
5
|
export class Repulser extends ExternalInteractorBase {
|
|
6
6
|
handleClickMode;
|
|
7
|
+
_clickVec;
|
|
7
8
|
_engine;
|
|
9
|
+
_maxDistance;
|
|
10
|
+
_normVec;
|
|
8
11
|
constructor(engine, container) {
|
|
9
12
|
super(container);
|
|
10
13
|
this._engine = engine;
|
|
14
|
+
this._maxDistance = 0;
|
|
15
|
+
this._normVec = Vector.origin;
|
|
16
|
+
this._clickVec = Vector.origin;
|
|
11
17
|
container.repulse ??= { particles: [] };
|
|
12
18
|
this.handleClickMode = (mode, interactivityData) => {
|
|
13
19
|
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
@@ -34,6 +40,9 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
34
40
|
}, repulseOpts.duration * millisecondsToSeconds);
|
|
35
41
|
};
|
|
36
42
|
}
|
|
43
|
+
get maxDistance() {
|
|
44
|
+
return this._maxDistance;
|
|
45
|
+
}
|
|
37
46
|
clear() {
|
|
38
47
|
}
|
|
39
48
|
init() {
|
|
@@ -41,6 +50,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
41
50
|
if (!repulse) {
|
|
42
51
|
return;
|
|
43
52
|
}
|
|
53
|
+
this._maxDistance = repulse.distance;
|
|
44
54
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
45
55
|
}
|
|
46
56
|
interact(interactivityData) {
|
|
@@ -103,14 +113,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
103
113
|
if (mouseClickPos === undefined) {
|
|
104
114
|
return;
|
|
105
115
|
}
|
|
106
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.
|
|
116
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.grid.query(range, p => this.isEnabled(interactivityData, p));
|
|
107
117
|
for (const particle of query) {
|
|
108
118
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
109
119
|
if (d <= repulseRadius) {
|
|
110
120
|
repulse.particles.push(particle);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
this._clickVec.x = dx;
|
|
122
|
+
this._clickVec.y = dy;
|
|
123
|
+
this._clickVec.length = force;
|
|
124
|
+
particle.velocity.setTo(this._clickVec);
|
|
114
125
|
}
|
|
115
126
|
}
|
|
116
127
|
}
|
|
@@ -129,14 +140,16 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
129
140
|
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
130
141
|
};
|
|
131
142
|
_processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
132
|
-
const container = this.container, query = container.particles.
|
|
143
|
+
const container = this.container, query = container.particles.grid.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
133
144
|
if (!repulseOptions) {
|
|
134
145
|
return;
|
|
135
146
|
}
|
|
136
147
|
const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;
|
|
137
148
|
for (const particle of query) {
|
|
138
|
-
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed)
|
|
139
|
-
|
|
149
|
+
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed);
|
|
150
|
+
this._normVec.x = !distance ? velocity : (dx / distance) * repulseFactor;
|
|
151
|
+
this._normVec.y = !distance ? velocity : (dy / distance) * repulseFactor;
|
|
152
|
+
particle.position.addTo(this._normVec);
|
|
140
153
|
}
|
|
141
154
|
};
|
|
142
155
|
_singleSelectorRepulse = (interactivityData, selector, div) => {
|
package/browser/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
package/cjs/Repulser.js
CHANGED
|
@@ -4,10 +4,16 @@ import { Repulse } from "./Options/Classes/Repulse.js";
|
|
|
4
4
|
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
5
5
|
export class Repulser extends ExternalInteractorBase {
|
|
6
6
|
handleClickMode;
|
|
7
|
+
_clickVec;
|
|
7
8
|
_engine;
|
|
9
|
+
_maxDistance;
|
|
10
|
+
_normVec;
|
|
8
11
|
constructor(engine, container) {
|
|
9
12
|
super(container);
|
|
10
13
|
this._engine = engine;
|
|
14
|
+
this._maxDistance = 0;
|
|
15
|
+
this._normVec = Vector.origin;
|
|
16
|
+
this._clickVec = Vector.origin;
|
|
11
17
|
container.repulse ??= { particles: [] };
|
|
12
18
|
this.handleClickMode = (mode, interactivityData) => {
|
|
13
19
|
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
@@ -34,6 +40,9 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
34
40
|
}, repulseOpts.duration * millisecondsToSeconds);
|
|
35
41
|
};
|
|
36
42
|
}
|
|
43
|
+
get maxDistance() {
|
|
44
|
+
return this._maxDistance;
|
|
45
|
+
}
|
|
37
46
|
clear() {
|
|
38
47
|
}
|
|
39
48
|
init() {
|
|
@@ -41,6 +50,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
41
50
|
if (!repulse) {
|
|
42
51
|
return;
|
|
43
52
|
}
|
|
53
|
+
this._maxDistance = repulse.distance;
|
|
44
54
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
45
55
|
}
|
|
46
56
|
interact(interactivityData) {
|
|
@@ -103,14 +113,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
103
113
|
if (mouseClickPos === undefined) {
|
|
104
114
|
return;
|
|
105
115
|
}
|
|
106
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.
|
|
116
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.grid.query(range, p => this.isEnabled(interactivityData, p));
|
|
107
117
|
for (const particle of query) {
|
|
108
118
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
109
119
|
if (d <= repulseRadius) {
|
|
110
120
|
repulse.particles.push(particle);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
this._clickVec.x = dx;
|
|
122
|
+
this._clickVec.y = dy;
|
|
123
|
+
this._clickVec.length = force;
|
|
124
|
+
particle.velocity.setTo(this._clickVec);
|
|
114
125
|
}
|
|
115
126
|
}
|
|
116
127
|
}
|
|
@@ -129,14 +140,16 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
129
140
|
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
130
141
|
};
|
|
131
142
|
_processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
132
|
-
const container = this.container, query = container.particles.
|
|
143
|
+
const container = this.container, query = container.particles.grid.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
133
144
|
if (!repulseOptions) {
|
|
134
145
|
return;
|
|
135
146
|
}
|
|
136
147
|
const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;
|
|
137
148
|
for (const particle of query) {
|
|
138
|
-
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed)
|
|
139
|
-
|
|
149
|
+
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed);
|
|
150
|
+
this._normVec.x = !distance ? velocity : (dx / distance) * repulseFactor;
|
|
151
|
+
this._normVec.y = !distance ? velocity : (dy / distance) * repulseFactor;
|
|
152
|
+
particle.position.addTo(this._normVec);
|
|
140
153
|
}
|
|
141
154
|
};
|
|
142
155
|
_singleSelectorRepulse = (interactivityData, selector, div) => {
|
package/cjs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
|
@@ -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
|
-
* v4.0.0-alpha.
|
|
7
|
+
* v4.0.0-alpha.26
|
|
8
8
|
*/
|
|
9
9
|
"use strict";
|
|
10
10
|
/*
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
\**********************************/
|
|
24
24
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
25
25
|
|
|
26
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Repulser: () => (/* binding */ Repulser)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\");\n/* harmony import */ var _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Repulse.js */ \"./dist/browser/Options/Classes/Repulse.js\");\n\n\n\nconst repulseMode = \"repulse\", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;\nclass Repulser extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.ExternalInteractorBase {\n handleClickMode;\n _engine;\n constructor(engine, container){\n super(container);\n this._engine = engine;\n container.repulse ??= {\n particles: []\n };\n this.handleClickMode = (mode, interactivityData)=>{\n const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;\n if (!repulseOpts || mode !== repulseMode) {\n return;\n }\n container.repulse ??= {\n particles: []\n };\n const repulse = container.repulse;\n repulse.clicking = true;\n repulse.count = 0;\n for (const particle of container.repulse.particles){\n if (!this.isEnabled(interactivityData, particle)) {\n continue;\n }\n particle.velocity.setTo(particle.initialVelocity);\n }\n repulse.particles = [];\n repulse.finish = false;\n setTimeout(()=>{\n if (container.destroyed) {\n return;\n }\n repulse.clicking = false;\n }, repulseOpts.duration * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.millisecondsToSeconds);\n };\n }\n clear() {}\n init() {\n const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;\n if (!repulse) {\n return;\n }\n container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;\n }\n interact(interactivityData) {\n const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.mouseMoveEvent, events = options.interactivity?.events;\n if (!events) {\n return;\n }\n const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;\n if (mouseMoveStatus && hoverEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, hoverMode)) {\n this._hoverRepulse(interactivityData);\n } else if (clickEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, clickMode)) {\n this._clickRepulse(interactivityData);\n } else {\n (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divModeExecute)(repulseMode, divs, (selector, div)=>{\n this._singleSelectorRepulse(interactivityData, selector, div);\n });\n }\n }\n isEnabled(interactivityData, particle) {\n const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;\n if (!events) {\n return false;\n }\n const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.isDivModeEnabled)(repulseMode, divs);\n if (!(divRepulse || hover.enable && !!mouse.position || click.enable && mouse.clickPosition)) {\n return false;\n }\n const hoverMode = hover.mode, clickMode = click.mode;\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, hoverMode) || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, clickMode) || divRepulse;\n }\n loadModeOptions(options, ...sources) {\n options.repulse ??= new _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__.Repulse();\n for (const source of sources){\n options.repulse.load(source?.repulse);\n }\n }\n reset() {}\n _clickRepulse = (interactivityData)=>{\n const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const repulse = container.repulse ?? {\n particles: []\n };\n if (!repulse.finish) {\n repulse.count ??= 0;\n repulse.count++;\n if (repulse.count === container.particles.count) {\n repulse.finish = true;\n }\n }\n if (repulse.clicking) {\n const repulseDistance = container.retina.repulseModeDistance;\n if (!repulseDistance || repulseDistance < minDistance) {\n return;\n }\n const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;\n if (mouseClickPos === undefined) {\n return;\n }\n const range = new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, (p)=>this.isEnabled(interactivityData, p));\n for (const particle of query){\n const { dx, dy, distance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = -repulseRadius * velocity / d;\n if (d <= repulseRadius) {\n repulse.particles.push(particle);\n const vect = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(dx, dy);\n vect.length = force;\n particle.velocity.setTo(vect);\n }\n }\n } else if (repulse.clicking === false) {\n for (const particle of repulse.particles){\n particle.velocity.setTo(particle.initialVelocity);\n }\n repulse.particles = [];\n }\n };\n _hoverRepulse = (interactivityData)=>{\n const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;\n if (!repulseRadius || repulseRadius < minRadius || !mousePos) {\n return;\n }\n this._processRepulse(interactivityData, mousePos, repulseRadius, new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(mousePos.x, mousePos.y, repulseRadius));\n };\n _processRepulse = (interactivityData, position, repulseRadius, area, divRepulse)=>{\n const container = this.container, query = container.particles.quadTree.query(area, (p)=>this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;\n for (const particle of query){\n const { dx, dy, distance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(particle.position, position), repulseFactor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed), normVec = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(!distance ? velocity : dx / distance * repulseFactor, !distance ? velocity : dy / distance * repulseFactor);\n particle.position.addTo(normVec);\n }\n };\n _singleSelectorRepulse = (interactivityData, selector, div)=>{\n const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;\n if (!repulse) {\n return;\n }\n const query = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().querySelectorAll(selector);\n if (!query.length) {\n return;\n }\n query.forEach((item)=>{\n const elem = item, pxRatio = container.retina.pixelRatio, pos = {\n x: (elem.offsetLeft + elem.offsetWidth * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) * pxRatio,\n y: (elem.offsetTop + elem.offsetHeight * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) * pxRatio\n }, repulseRadius = elem.offsetWidth * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half * pxRatio, area = div.type === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.DivType.circle ? new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(pos.x, pos.y, repulseRadius) : new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divMode)(divs, elem);\n this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);\n });\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-external-repulse/./dist/browser/Repulser.js?\n}");
|
|
26
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Repulser: () => (/* binding */ Repulser)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\");\n/* harmony import */ var _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Repulse.js */ \"./dist/browser/Options/Classes/Repulse.js\");\n\n\n\nconst repulseMode = \"repulse\", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;\nclass Repulser extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.ExternalInteractorBase {\n handleClickMode;\n _clickVec;\n _engine;\n _maxDistance;\n _normVec;\n constructor(engine, container){\n super(container);\n this._engine = engine;\n this._maxDistance = 0;\n this._normVec = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n this._clickVec = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n container.repulse ??= {\n particles: []\n };\n this.handleClickMode = (mode, interactivityData)=>{\n const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;\n if (!repulseOpts || mode !== repulseMode) {\n return;\n }\n container.repulse ??= {\n particles: []\n };\n const repulse = container.repulse;\n repulse.clicking = true;\n repulse.count = 0;\n for (const particle of container.repulse.particles){\n if (!this.isEnabled(interactivityData, particle)) {\n continue;\n }\n particle.velocity.setTo(particle.initialVelocity);\n }\n repulse.particles = [];\n repulse.finish = false;\n setTimeout(()=>{\n if (container.destroyed) {\n return;\n }\n repulse.clicking = false;\n }, repulseOpts.duration * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.millisecondsToSeconds);\n };\n }\n get maxDistance() {\n return this._maxDistance;\n }\n clear() {}\n init() {\n const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;\n if (!repulse) {\n return;\n }\n this._maxDistance = repulse.distance;\n container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;\n }\n interact(interactivityData) {\n const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.mouseMoveEvent, events = options.interactivity?.events;\n if (!events) {\n return;\n }\n const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;\n if (mouseMoveStatus && hoverEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, hoverMode)) {\n this._hoverRepulse(interactivityData);\n } else if (clickEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, clickMode)) {\n this._clickRepulse(interactivityData);\n } else {\n (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divModeExecute)(repulseMode, divs, (selector, div)=>{\n this._singleSelectorRepulse(interactivityData, selector, div);\n });\n }\n }\n isEnabled(interactivityData, particle) {\n const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;\n if (!events) {\n return false;\n }\n const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.isDivModeEnabled)(repulseMode, divs);\n if (!(divRepulse || hover.enable && !!mouse.position || click.enable && mouse.clickPosition)) {\n return false;\n }\n const hoverMode = hover.mode, clickMode = click.mode;\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, hoverMode) || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, clickMode) || divRepulse;\n }\n loadModeOptions(options, ...sources) {\n options.repulse ??= new _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__.Repulse();\n for (const source of sources){\n options.repulse.load(source?.repulse);\n }\n }\n reset() {}\n _clickRepulse = (interactivityData)=>{\n const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const repulse = container.repulse ?? {\n particles: []\n };\n if (!repulse.finish) {\n repulse.count ??= 0;\n repulse.count++;\n if (repulse.count === container.particles.count) {\n repulse.finish = true;\n }\n }\n if (repulse.clicking) {\n const repulseDistance = container.retina.repulseModeDistance;\n if (!repulseDistance || repulseDistance < minDistance) {\n return;\n }\n const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;\n if (mouseClickPos === undefined) {\n return;\n }\n const range = new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.grid.query(range, (p)=>this.isEnabled(interactivityData, p));\n for (const particle of query){\n const { dx, dy, distance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = -repulseRadius * velocity / d;\n if (d <= repulseRadius) {\n repulse.particles.push(particle);\n this._clickVec.x = dx;\n this._clickVec.y = dy;\n this._clickVec.length = force;\n particle.velocity.setTo(this._clickVec);\n }\n }\n } else if (repulse.clicking === false) {\n for (const particle of repulse.particles){\n particle.velocity.setTo(particle.initialVelocity);\n }\n repulse.particles = [];\n }\n };\n _hoverRepulse = (interactivityData)=>{\n const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;\n if (!repulseRadius || repulseRadius < minRadius || !mousePos) {\n return;\n }\n this._processRepulse(interactivityData, mousePos, repulseRadius, new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(mousePos.x, mousePos.y, repulseRadius));\n };\n _processRepulse = (interactivityData, position, repulseRadius, area, divRepulse)=>{\n const container = this.container, query = container.particles.grid.query(area, (p)=>this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;\n for (const particle of query){\n const { dx, dy, distance } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(particle.position, position), repulseFactor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed);\n this._normVec.x = !distance ? velocity : dx / distance * repulseFactor;\n this._normVec.y = !distance ? velocity : dy / distance * repulseFactor;\n particle.position.addTo(this._normVec);\n }\n };\n _singleSelectorRepulse = (interactivityData, selector, div)=>{\n const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;\n if (!repulse) {\n return;\n }\n const query = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().querySelectorAll(selector);\n if (!query.length) {\n return;\n }\n query.forEach((item)=>{\n const elem = item, pxRatio = container.retina.pixelRatio, pos = {\n x: (elem.offsetLeft + elem.offsetWidth * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) * pxRatio,\n y: (elem.offsetTop + elem.offsetHeight * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) * pxRatio\n }, repulseRadius = elem.offsetWidth * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half * pxRatio, area = div.type === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.DivType.circle ? new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(pos.x, pos.y, repulseRadius) : new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divMode)(divs, elem);\n this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);\n });\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-external-repulse/./dist/browser/Repulser.js?\n}");
|
|
27
27
|
|
|
28
28
|
/***/ }
|
|
29
29
|
|
package/esm/Repulser.js
CHANGED
|
@@ -4,10 +4,16 @@ import { Repulse } from "./Options/Classes/Repulse.js";
|
|
|
4
4
|
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
5
5
|
export class Repulser extends ExternalInteractorBase {
|
|
6
6
|
handleClickMode;
|
|
7
|
+
_clickVec;
|
|
7
8
|
_engine;
|
|
9
|
+
_maxDistance;
|
|
10
|
+
_normVec;
|
|
8
11
|
constructor(engine, container) {
|
|
9
12
|
super(container);
|
|
10
13
|
this._engine = engine;
|
|
14
|
+
this._maxDistance = 0;
|
|
15
|
+
this._normVec = Vector.origin;
|
|
16
|
+
this._clickVec = Vector.origin;
|
|
11
17
|
container.repulse ??= { particles: [] };
|
|
12
18
|
this.handleClickMode = (mode, interactivityData) => {
|
|
13
19
|
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
@@ -34,6 +40,9 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
34
40
|
}, repulseOpts.duration * millisecondsToSeconds);
|
|
35
41
|
};
|
|
36
42
|
}
|
|
43
|
+
get maxDistance() {
|
|
44
|
+
return this._maxDistance;
|
|
45
|
+
}
|
|
37
46
|
clear() {
|
|
38
47
|
}
|
|
39
48
|
init() {
|
|
@@ -41,6 +50,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
41
50
|
if (!repulse) {
|
|
42
51
|
return;
|
|
43
52
|
}
|
|
53
|
+
this._maxDistance = repulse.distance;
|
|
44
54
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
45
55
|
}
|
|
46
56
|
interact(interactivityData) {
|
|
@@ -103,14 +113,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
103
113
|
if (mouseClickPos === undefined) {
|
|
104
114
|
return;
|
|
105
115
|
}
|
|
106
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.
|
|
116
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.grid.query(range, p => this.isEnabled(interactivityData, p));
|
|
107
117
|
for (const particle of query) {
|
|
108
118
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
109
119
|
if (d <= repulseRadius) {
|
|
110
120
|
repulse.particles.push(particle);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
this._clickVec.x = dx;
|
|
122
|
+
this._clickVec.y = dy;
|
|
123
|
+
this._clickVec.length = force;
|
|
124
|
+
particle.velocity.setTo(this._clickVec);
|
|
114
125
|
}
|
|
115
126
|
}
|
|
116
127
|
}
|
|
@@ -129,14 +140,16 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
129
140
|
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
130
141
|
};
|
|
131
142
|
_processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
132
|
-
const container = this.container, query = container.particles.
|
|
143
|
+
const container = this.container, query = container.particles.grid.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
133
144
|
if (!repulseOptions) {
|
|
134
145
|
return;
|
|
135
146
|
}
|
|
136
147
|
const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;
|
|
137
148
|
for (const particle of query) {
|
|
138
|
-
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed)
|
|
139
|
-
|
|
149
|
+
const { dx, dy, distance } = getDistances(particle.position, position), repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed);
|
|
150
|
+
this._normVec.x = !distance ? velocity : (dx / distance) * repulseFactor;
|
|
151
|
+
this._normVec.y = !distance ? velocity : (dy / distance) * repulseFactor;
|
|
152
|
+
particle.position.addTo(this._normVec);
|
|
140
153
|
}
|
|
141
154
|
};
|
|
142
155
|
_singleSelectorRepulse = (interactivityData, selector, div) => {
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { ensureInteractivityPluginLoaded } = await import("@tsparticles/plugin-interactivity");
|
|
5
5
|
ensureInteractivityPluginLoaded(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/interaction-external-repulse",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.26",
|
|
4
4
|
"description": "tsParticles repulse external interaction",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"./package.json": "./package.json"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@tsparticles/engine": "4.0.0-alpha.
|
|
91
|
-
"@tsparticles/plugin-interactivity": "4.0.0-alpha.
|
|
90
|
+
"@tsparticles/engine": "4.0.0-alpha.26",
|
|
91
|
+
"@tsparticles/plugin-interactivity": "4.0.0-alpha.26"
|
|
92
92
|
},
|
|
93
93
|
"publishConfig": {
|
|
94
94
|
"access": "public"
|
package/report.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8"/>
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
6
|
-
<title>@tsparticles/interaction-external-repulse [
|
|
6
|
+
<title>@tsparticles/interaction-external-repulse [26 Feb 2026 at 18:07]</title>
|
|
7
7
|
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
|
|
8
8
|
|
|
9
9
|
<script>
|
|
@@ -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
|
-
* v4.0.0-alpha.
|
|
7
|
+
* v4.0.0-alpha.26
|
|
8
8
|
*/
|
|
9
9
|
/*
|
|
10
10
|
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
@@ -84,7 +84,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
84
84
|
\*******************************/
|
|
85
85
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
86
86
|
|
|
87
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Repulse: () => (/* reexport safe */ _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__.Repulse),\n/* harmony export */ RepulseBase: () => (/* reexport safe */ _Options_Classes_RepulseBase_js__WEBPACK_IMPORTED_MODULE_0__.RepulseBase),\n/* harmony export */ RepulseDiv: () => (/* reexport safe */ _Options_Classes_RepulseDiv_js__WEBPACK_IMPORTED_MODULE_1__.RepulseDiv),\n/* harmony export */ loadExternalRepulseInteraction: () => (/* binding */ loadExternalRepulseInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_RepulseBase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/RepulseBase.js */ \"./dist/browser/Options/Classes/RepulseBase.js\");\n/* harmony import */ var _Options_Classes_RepulseDiv_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/RepulseDiv.js */ \"./dist/browser/Options/Classes/RepulseDiv.js\");\n/* harmony import */ var _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Repulse.js */ \"./dist/browser/Options/Classes/Repulse.js\");\nasync function loadExternalRepulseInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.
|
|
87
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Repulse: () => (/* reexport safe */ _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__.Repulse),\n/* harmony export */ RepulseBase: () => (/* reexport safe */ _Options_Classes_RepulseBase_js__WEBPACK_IMPORTED_MODULE_0__.RepulseBase),\n/* harmony export */ RepulseDiv: () => (/* reexport safe */ _Options_Classes_RepulseDiv_js__WEBPACK_IMPORTED_MODULE_1__.RepulseDiv),\n/* harmony export */ loadExternalRepulseInteraction: () => (/* binding */ loadExternalRepulseInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_RepulseBase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/RepulseBase.js */ \"./dist/browser/Options/Classes/RepulseBase.js\");\n/* harmony import */ var _Options_Classes_RepulseDiv_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/RepulseDiv.js */ \"./dist/browser/Options/Classes/RepulseDiv.js\");\n/* harmony import */ var _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Repulse.js */ \"./dist/browser/Options/Classes/Repulse.js\");\nasync function loadExternalRepulseInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.26\");\n await engine.register(async (e)=>{\n const { ensureInteractivityPluginLoaded } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\", 19));\n ensureInteractivityPluginLoaded(e);\n e.addInteractor?.(\"externalRepulse\", async (container)=>{\n const { Repulser } = await __webpack_require__.e(/*! import() */ \"dist_browser_Repulser_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./Repulser.js */ \"./dist/browser/Repulser.js\"));\n return new Repulser(engine, container);\n });\n });\n}\n\n\n\n\n\n//# sourceURL=webpack://@tsparticles/interaction-external-repulse/./dist/browser/index.js?\n}");
|
|
88
88
|
|
|
89
89
|
/***/ }
|
|
90
90
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/plugin-interactivity"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity")):t(e.window,e.window);for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,(e,t)=>(()=>{"use strict";var r,i,o,n={303(t){t.exports=e},702(e){e.exports=t},
|
|
2
|
-
(`+o+": "+n+")",s.name="ChunkLoadError",s.type=o,s.request=n,i[1](s)}},"chunk-"+e,e)}},i=(e,t)=>{var i,o,[n,s,l]=t,c=0;if(n.some(e=>0!==r[e])){for(i in s)a.o(s,i)&&(a.m[i]=s[i]);l&&l(a)}for(e&&e(t);c<n.length;c++)o=n[c],a.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(o=this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).forEach(i.bind(null,0)),o.push=i.bind(null,o.push.bind(o));var v={};a.r(v),a.d(v,{Repulse:()=>m.Z,RepulseBase:()=>g._,RepulseDiv:()=>b.W,loadExternalRepulseInteraction:()=>y});var g=a(
|
|
1
|
+
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/plugin-interactivity"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity")):t(e.window,e.window);for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,(e,t)=>(()=>{"use strict";var r,i,o,n={303(t){t.exports=e},702(e){e.exports=t},686(e,t,r){r.d(t,{Z:()=>s});var i=r(303),o=r(247),n=r(215);class s extends o._{divs;load(e){super.load(e),(0,i.isNull)(e)||(this.divs=(0,i.executeOnSingleOrMultiple)(e.divs,e=>{let t=new n.W;return t.load(e),t}))}}},247(e,t,r){r.d(t,{_:()=>o});var i=r(303);class o{distance;duration;easing;factor;maxSpeed;speed;constructor(){this.distance=200,this.duration=.4,this.factor=100,this.speed=1,this.maxSpeed=50,this.easing=i.EasingType.easeOutQuad}load(e){(0,i.isNull)(e)||(void 0!==e.distance&&(this.distance=e.distance),void 0!==e.duration&&(this.duration=e.duration),void 0!==e.easing&&(this.easing=e.easing),void 0!==e.factor&&(this.factor=e.factor),void 0!==e.speed&&(this.speed=e.speed),void 0!==e.maxSpeed&&(this.maxSpeed=e.maxSpeed))}}},215(e,t,r){r.d(t,{W:()=>n});var i=r(303),o=r(247);class n extends o._{selectors;constructor(){super(),this.selectors=[]}load(e){super.load(e),(0,i.isNull)(e)||void 0!==e.selectors&&(this.selectors=e.selectors)}}}},s={};function a(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}};return n[e](r,r.exports,a),r.exports}a.m=n,c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(e,t){if(1&t&&(e=this(e)),8&t||"object"==typeof e&&e&&(4&t&&e.__esModule||16&t&&"function"==typeof e.then))return e;var r=Object.create(null);a.r(r);var i={};l=l||[null,c({}),c([]),c(c)];for(var o=2&t&&e;("object"==typeof o||"function"==typeof o)&&!~l.indexOf(o);o=c(o))Object.getOwnPropertyNames(o).forEach(t=>i[t]=()=>e[t]);return i.default=()=>e,a.d(r,i),r},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce((t,r)=>(a.f[r](e,t),t),[])),a.u=e=>""+e+".min.js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),p={},a.l=(e,t,r,i)=>{if(p[e])return void p[e].push(t);if(void 0!==r)for(var o,n,s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var c=s[l];if(c.getAttribute("src")==e||c.getAttribute("data-webpack")=="@tsparticles/interaction-external-repulse:"+r){o=c;break}}o||(n=!0,(o=document.createElement("script")).charset="utf-8",a.nc&&o.setAttribute("nonce",a.nc),o.setAttribute("data-webpack","@tsparticles/interaction-external-repulse:"+r),o.src=e),p[e]=[t];var u=(t,r)=>{o.onerror=o.onload=null,clearTimeout(d);var i=p[e];if(delete p[e],o.parentNode&&o.parentNode.removeChild(o),i&&i.forEach(e=>e(r)),t)return t(r)},d=setTimeout(u.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=u.bind(null,o.onerror),o.onload=u.bind(null,o.onload),n&&document.head.appendChild(o)},a.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.g.importScripts&&(u=a.g.location+"");var l,c,p,u,d=a.g.document;if(!u&&d&&(d.currentScript&&"SCRIPT"===d.currentScript.tagName.toUpperCase()&&(u=d.currentScript.src),!u)){var f=d.getElementsByTagName("script");if(f.length)for(var h=f.length-1;h>-1&&(!u||!/^http(s?):/.test(u));)u=f[h--].src}if(!u)throw Error("Automatic publicPath is not supported in this browser");a.p=u=u.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={64:0},a.f.j=(e,t)=>{var i=a.o(r,e)?r[e]:void 0;if(0!==i)if(i)t.push(i[2]);else{var o=new Promise((t,o)=>i=r[e]=[t,o]);t.push(i[2]=o);var n=a.p+a.u(e),s=Error();a.l(n,t=>{if(a.o(r,e)&&(0!==(i=r[e])&&(r[e]=void 0),i)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;s.message="Loading chunk "+e+` failed.
|
|
2
|
+
(`+o+": "+n+")",s.name="ChunkLoadError",s.type=o,s.request=n,i[1](s)}},"chunk-"+e,e)}},i=(e,t)=>{var i,o,[n,s,l]=t,c=0;if(n.some(e=>0!==r[e])){for(i in s)a.o(s,i)&&(a.m[i]=s[i]);l&&l(a)}for(e&&e(t);c<n.length;c++)o=n[c],a.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(o=this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).forEach(i.bind(null,0)),o.push=i.bind(null,o.push.bind(o));var v={};a.r(v),a.d(v,{Repulse:()=>m.Z,RepulseBase:()=>g._,RepulseDiv:()=>b.W,loadExternalRepulseInteraction:()=>y});var g=a(247),b=a(215),m=a(686);async function y(e){e.checkVersion("4.0.0-alpha.26"),await e.register(async t=>{let{ensureInteractivityPluginLoaded:r}=await Promise.resolve().then(a.t.bind(a,702,19));r(t),t.addInteractor?.("externalRepulse",async t=>{let{Repulser:r}=await a.e(504).then(a.bind(a,504));return new r(e,t)})})}return v})());
|
package/types/Repulser.d.ts
CHANGED
|
@@ -3,8 +3,12 @@ import { ExternalInteractorBase, type IInteractivityData, type IModes, type Inte
|
|
|
3
3
|
import type { IRepulseMode, RepulseContainer, RepulseMode } from "./Types.js";
|
|
4
4
|
export declare class Repulser extends ExternalInteractorBase<RepulseContainer> {
|
|
5
5
|
handleClickMode: (mode: string, interactivityData: IInteractivityData) => void;
|
|
6
|
+
private readonly _clickVec;
|
|
6
7
|
private readonly _engine;
|
|
8
|
+
private _maxDistance;
|
|
9
|
+
private readonly _normVec;
|
|
7
10
|
constructor(engine: Engine, container: RepulseContainer);
|
|
11
|
+
get maxDistance(): number;
|
|
8
12
|
clear(): void;
|
|
9
13
|
init(): void;
|
|
10
14
|
interact(interactivityData: IInteractivityData): void;
|
package/umd/Repulser.js
CHANGED
|
@@ -16,10 +16,16 @@
|
|
|
16
16
|
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
17
17
|
class Repulser extends plugin_interactivity_1.ExternalInteractorBase {
|
|
18
18
|
handleClickMode;
|
|
19
|
+
_clickVec;
|
|
19
20
|
_engine;
|
|
21
|
+
_maxDistance;
|
|
22
|
+
_normVec;
|
|
20
23
|
constructor(engine, container) {
|
|
21
24
|
super(container);
|
|
22
25
|
this._engine = engine;
|
|
26
|
+
this._maxDistance = 0;
|
|
27
|
+
this._normVec = engine_1.Vector.origin;
|
|
28
|
+
this._clickVec = engine_1.Vector.origin;
|
|
23
29
|
container.repulse ??= { particles: [] };
|
|
24
30
|
this.handleClickMode = (mode, interactivityData) => {
|
|
25
31
|
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
@@ -46,6 +52,9 @@
|
|
|
46
52
|
}, repulseOpts.duration * engine_1.millisecondsToSeconds);
|
|
47
53
|
};
|
|
48
54
|
}
|
|
55
|
+
get maxDistance() {
|
|
56
|
+
return this._maxDistance;
|
|
57
|
+
}
|
|
49
58
|
clear() {
|
|
50
59
|
}
|
|
51
60
|
init() {
|
|
@@ -53,6 +62,7 @@
|
|
|
53
62
|
if (!repulse) {
|
|
54
63
|
return;
|
|
55
64
|
}
|
|
65
|
+
this._maxDistance = repulse.distance;
|
|
56
66
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
57
67
|
}
|
|
58
68
|
interact(interactivityData) {
|
|
@@ -115,14 +125,15 @@
|
|
|
115
125
|
if (mouseClickPos === undefined) {
|
|
116
126
|
return;
|
|
117
127
|
}
|
|
118
|
-
const range = new engine_1.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.
|
|
128
|
+
const range = new engine_1.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.grid.query(range, p => this.isEnabled(interactivityData, p));
|
|
119
129
|
for (const particle of query) {
|
|
120
130
|
const { dx, dy, distance } = (0, engine_1.getDistances)(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
121
131
|
if (d <= repulseRadius) {
|
|
122
132
|
repulse.particles.push(particle);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
this._clickVec.x = dx;
|
|
134
|
+
this._clickVec.y = dy;
|
|
135
|
+
this._clickVec.length = force;
|
|
136
|
+
particle.velocity.setTo(this._clickVec);
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
}
|
|
@@ -141,14 +152,16 @@
|
|
|
141
152
|
this._processRepulse(interactivityData, mousePos, repulseRadius, new engine_1.Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
142
153
|
};
|
|
143
154
|
_processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
144
|
-
const container = this.container, query = container.particles.
|
|
155
|
+
const container = this.container, query = container.particles.grid.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
145
156
|
if (!repulseOptions) {
|
|
146
157
|
return;
|
|
147
158
|
}
|
|
148
159
|
const { easing, speed, factor, maxSpeed } = repulseOptions, easingFunc = this._engine.getEasing(easing), velocity = (divRepulse?.speed ?? speed) * factor;
|
|
149
160
|
for (const particle of query) {
|
|
150
|
-
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position), repulseFactor = (0, engine_1.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed)
|
|
151
|
-
|
|
161
|
+
const { dx, dy, distance } = (0, engine_1.getDistances)(particle.position, position), repulseFactor = (0, engine_1.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed);
|
|
162
|
+
this._normVec.x = !distance ? velocity : (dx / distance) * repulseFactor;
|
|
163
|
+
this._normVec.y = !distance ? velocity : (dy / distance) * repulseFactor;
|
|
164
|
+
particle.position.addTo(this._normVec);
|
|
152
165
|
}
|
|
153
166
|
};
|
|
154
167
|
_singleSelectorRepulse = (interactivityData, selector, div) => {
|
package/umd/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.loadExternalRepulseInteraction = loadExternalRepulseInteraction;
|
|
50
50
|
async function loadExternalRepulseInteraction(engine) {
|
|
51
|
-
engine.checkVersion("4.0.0-alpha.
|
|
51
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
52
52
|
await engine.register(async (e) => {
|
|
53
53
|
const { ensureInteractivityPluginLoaded } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("@tsparticles/plugin-interactivity"))) : new Promise((resolve_1, reject_1) => { require(["@tsparticles/plugin-interactivity"], resolve_1, reject_1); }).then(__importStar));
|
|
54
54
|
ensureInteractivityPluginLoaded(e);
|
package/780.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).push([[780],{780(e,t,i){i.d(t,{Repulser:()=>o});var s=i(303),l=i(702),n=i(498);let r="repulse";class o extends l.ExternalInteractorBase{handleClickMode;_engine;constructor(e,t){super(t),this._engine=e,t.repulse??={particles:[]},this.handleClickMode=(e,i)=>{let l=this.container.actualOptions,n=l.interactivity?.modes.repulse;if(!n||e!==r)return;t.repulse??={particles:[]};let o=t.repulse;for(let e of(o.clicking=!0,o.count=0,t.repulse.particles))this.isEnabled(i,e)&&e.velocity.setTo(e.initialVelocity);o.particles=[],o.finish=!1,setTimeout(()=>{t.destroyed||(o.clicking=!1)},n.duration*s.millisecondsToSeconds)}}clear(){}init(){let e=this.container,t=e.actualOptions.interactivity?.modes.repulse;t&&(e.retina.repulseModeDistance=t.distance*e.retina.pixelRatio)}interact(e){let t=this.container.actualOptions,i=e.status===l.mouseMoveEvent,n=t.interactivity?.events;if(!n)return;let o=n.onHover,c=o.enable,a=o.mode,p=n.onClick,u=p.enable,f=p.mode,d=n.onDiv;i&&c&&(0,s.isInArray)(r,a)?this._hoverRepulse(e):u&&(0,s.isInArray)(r,f)?this._clickRepulse(e):(0,l.divModeExecute)(r,d,(t,i)=>{this._singleSelectorRepulse(e,t,i)})}isEnabled(e,t){let i=this.container.actualOptions,n=e.mouse,o=(t?.interactivity??i.interactivity)?.events;if(!o)return!1;let c=o.onDiv,a=o.onHover,p=o.onClick,u=(0,l.isDivModeEnabled)(r,c);if(!(u||a.enable&&n.position||p.enable&&n.clickPosition))return!1;let f=a.mode,d=p.mode;return(0,s.isInArray)(r,f)||(0,s.isInArray)(r,d)||u}loadModeOptions(e,...t){for(let i of(e.repulse??=new n.Z,t))e.repulse.load(i?.repulse)}reset(){}_clickRepulse=e=>{let t=this.container,i=t.actualOptions.interactivity?.modes.repulse;if(!i)return;let l=t.repulse??{particles:[]};if(l.finish||(l.count??=0,l.count++,l.count===t.particles.count&&(l.finish=!0)),l.clicking){let n=t.retina.repulseModeDistance;if(!n||n<0)return;let r=Math.pow(n/6,3),o=e.mouse.clickPosition;if(void 0===o)return;let c=new s.Circle(o.x,o.y,r);for(let n of t.particles.quadTree.query(c,t=>this.isEnabled(e,t))){let{dx:e,dy:t,distance:c}=(0,s.getDistances)(o,n.position),a=c**2,p=-r*i.speed/a;if(a<=r){l.particles.push(n);let i=s.Vector.create(e,t);i.length=p,n.velocity.setTo(i)}}}else if(!1===l.clicking){for(let e of l.particles)e.velocity.setTo(e.initialVelocity);l.particles=[]}};_hoverRepulse=e=>{let t=this.container,i=e.mouse.position,l=t.retina.repulseModeDistance;l&&!(l<0)&&i&&this._processRepulse(e,i,l,new s.Circle(i.x,i.y,l))};_processRepulse=(e,t,i,l,n)=>{let r=this.container,o=r.particles.quadTree.query(l,t=>this.isEnabled(e,t)),c=r.actualOptions.interactivity?.modes.repulse;if(!c)return;let{easing:a,speed:p,factor:u,maxSpeed:f}=c,d=this._engine.getEasing(a),h=(n?.speed??p)*u;for(let e of o){let{dx:l,dy:n,distance:r}=(0,s.getDistances)(e.position,t),o=(0,s.clamp)(d(1-r/i)*h,0,f),c=s.Vector.create(r?l/r*o:h,r?n/r*o:h);e.position.addTo(c)}};_singleSelectorRepulse=(e,t,i)=>{let n=this.container,r=n.actualOptions.interactivity?.modes.repulse;if(!r)return;let o=(0,s.safeDocument)().querySelectorAll(t);o.length&&o.forEach(t=>{let o=n.retina.pixelRatio,c={x:(t.offsetLeft+t.offsetWidth*s.half)*o,y:(t.offsetTop+t.offsetHeight*s.half)*o},a=t.offsetWidth*s.half*o,p=i.type===l.DivType.circle?new s.Circle(c.x,c.y,a):new s.Rectangle(t.offsetLeft*o,t.offsetTop*o,t.offsetWidth*o,t.offsetHeight*o),u=r.divs,f=(0,l.divMode)(u,t);this._processRepulse(e,c,a,p,f)})}}}}]);
|