@tsparticles/interaction-external-repulse 4.0.0-alpha.2 → 4.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/783.min.js +2 -0
- package/783.min.js.LICENSE.txt +1 -0
- package/browser/Repulser.js +34 -25
- package/browser/index.js +5 -3
- package/cjs/Repulser.js +34 -25
- package/cjs/index.js +5 -3
- package/dist_browser_Repulser_js.js +2 -2
- package/esm/Repulser.js +34 -25
- package/esm/index.js +5 -3
- package/package.json +3 -2
- package/report.html +1 -1
- package/tsparticles.interaction.external.repulse.js +48 -20
- package/tsparticles.interaction.external.repulse.min.js +1 -1
- package/tsparticles.interaction.external.repulse.min.js.LICENSE.txt +1 -1
- package/types/Options/Classes/RepulseOptions.d.ts +3 -3
- package/types/Options/Interfaces/IRepulseDiv.d.ts +1 -1
- package/types/Repulser.d.ts +5 -4
- package/types/Types.d.ts +3 -2
- package/umd/Repulser.js +40 -31
- package/umd/index.js +6 -4
- package/176.min.js +0 -2
- package/176.min.js.LICENSE.txt +0 -1
package/783.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 783.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).push([[783],{783(e,t,i){i.d(t,{Repulser:()=>r});var s=i(303),n=i(702),o=i(591);const c="repulse";class r extends n.ExternalInteractorBase{constructor(e,t){super(t),this._clickRepulse=e=>{const t=this.container,i=t.actualOptions.interactivity?.modes.repulse;if(!i)return;const n=t.repulse??{particles:[]};if(n.finish||(n.count??=0,n.count++,n.count===t.particles.count&&(n.finish=!0)),n.clicking){const o=t.retina.repulseModeDistance;if(!o||o<0)return;const c=Math.pow(o/6,3),r=e.mouse.clickPosition;if(void 0===r)return;const a=new s.Circle(r.x,r.y,c),l=t.particles.quadTree.query(a,(t=>this.isEnabled(e,t)));for(const e of l){const{dx:t,dy:o,distance:a}=(0,s.getDistances)(r,e.position),l=a**2,p=-c*i.speed/l;if(l<=c){n.particles.push(e);const i=s.Vector.create(t,o);i.length=p,e.velocity.setTo(i)}}}else if(!1===n.clicking){for(const e of n.particles)e.velocity.setTo(e.initialVelocity);n.particles=[]}},this._hoverRepulse=e=>{const 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))},this._processRepulse=(e,t,i,n,o)=>{const c=this.container,r=c.particles.quadTree.query(n,(t=>this.isEnabled(e,t))),a=c.actualOptions.interactivity?.modes.repulse;if(!a)return;const{easing:l,speed:p,factor:u,maxSpeed:d}=a,f=this._engine.getEasing(l),h=(o?.speed??p)*u;for(const e of r){const{dx:n,dy:o,distance:c}=(0,s.getDistances)(e.position,t),r=(0,s.clamp)(f(1-c/i)*h,0,d),a=s.Vector.create(c?n/c*r:h,c?o/c*r:h);e.position.addTo(a)}},this._singleSelectorRepulse=(e,t,i)=>{const o=this.container,c=o.actualOptions.interactivity?.modes.repulse;if(!c)return;const r=(0,s.safeDocument)().querySelectorAll(t);r.length&&r.forEach((t=>{const r=t,a=o.retina.pixelRatio,l={x:(r.offsetLeft+r.offsetWidth*s.half)*a,y:(r.offsetTop+r.offsetHeight*s.half)*a},p=r.offsetWidth*s.half*a,u=i.type===n.DivType.circle?new s.Circle(l.x,l.y,p):new s.Rectangle(r.offsetLeft*a,r.offsetTop*a,r.offsetWidth*a,r.offsetHeight*a),d=c.divs,f=(0,n.divMode)(d,r);this._processRepulse(e,l,p,u,f)}))},this._engine=e,t.repulse??={particles:[]},this.handleClickMode=(e,i)=>{const n=this.container.actualOptions,o=n.interactivity?.modes.repulse;if(!o||e!==c)return;t.repulse??={particles:[]};const r=t.repulse;r.clicking=!0,r.count=0;for(const e of t.repulse.particles)this.isEnabled(i,e)&&e.velocity.setTo(e.initialVelocity);r.particles=[],r.finish=!1,setTimeout((()=>{t.destroyed||(r.clicking=!1)}),o.duration*s.millisecondsToSeconds)}}clear(){}init(){const e=this.container,t=e.actualOptions.interactivity?.modes.repulse;t&&(e.retina.repulseModeDistance=t.distance*e.retina.pixelRatio)}interact(e){const t=this.container.actualOptions,i=e.status===n.mouseMoveEvent,o=t.interactivity?.events;if(!o)return;const r=o.onHover,a=r.enable,l=r.mode,p=o.onClick,u=p.enable,d=p.mode,f=o.onDiv;i&&a&&(0,s.isInArray)(c,l)?this._hoverRepulse(e):u&&(0,s.isInArray)(c,d)?this._clickRepulse(e):(0,n.divModeExecute)(c,f,((t,i)=>{this._singleSelectorRepulse(e,t,i)}))}isEnabled(e,t){const i=this.container.actualOptions,o=e.mouse,r=(t?.interactivity??i.interactivity)?.events;if(!r)return!1;const a=r.onDiv,l=r.onHover,p=r.onClick,u=(0,n.isDivModeEnabled)(c,a);if(!(u||l.enable&&o.position||p.enable&&o.clickPosition))return!1;const d=l.mode,f=p.mode;return(0,s.isInArray)(c,d)||(0,s.isInArray)(c,f)||u}loadModeOptions(e,...t){e.repulse??=new o.Z;for(const i of t)e.repulse.load(i?.repulse)}reset(){}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Repulse External Interaction v4.0.0-alpha.4 by Matteo Bruni */
|
package/browser/Repulser.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, Vector, clamp, getDistances, half, isInArray, millisecondsToSeconds, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Repulse } from "./Options/Classes/Repulse.js";
|
|
3
|
-
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1
|
|
4
|
+
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
4
5
|
export class Repulser extends ExternalInteractorBase {
|
|
5
6
|
constructor(engine, container) {
|
|
6
7
|
super(container);
|
|
7
|
-
this._clickRepulse =
|
|
8
|
-
const container = this.container, repulseOptions = container.actualOptions.interactivity
|
|
8
|
+
this._clickRepulse = interactivityData => {
|
|
9
|
+
const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
9
10
|
if (!repulseOptions) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
@@ -22,11 +23,11 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
22
23
|
if (!repulseDistance || repulseDistance < minDistance) {
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
|
-
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos =
|
|
26
|
+
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;
|
|
26
27
|
if (mouseClickPos === undefined) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(p));
|
|
30
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(interactivityData, p));
|
|
30
31
|
for (const particle of query) {
|
|
31
32
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
32
33
|
if (d <= repulseRadius) {
|
|
@@ -44,15 +45,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
44
45
|
repulse.particles = [];
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
|
-
this._hoverRepulse =
|
|
48
|
-
const container = this.container, mousePos =
|
|
48
|
+
this._hoverRepulse = interactivityData => {
|
|
49
|
+
const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;
|
|
49
50
|
if (!repulseRadius || repulseRadius < minRadius || !mousePos) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
this._processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
|
+
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
54
|
};
|
|
54
|
-
this._processRepulse = (position, repulseRadius, area, divRepulse) => {
|
|
55
|
-
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(p)), repulseOptions = container.actualOptions.interactivity
|
|
55
|
+
this._processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
56
|
+
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
56
57
|
if (!repulseOptions) {
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
@@ -62,8 +63,8 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
62
63
|
particle.position.addTo(normVec);
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
|
-
this._singleSelectorRepulse = (selector, div) => {
|
|
66
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
66
|
+
this._singleSelectorRepulse = (interactivityData, selector, div) => {
|
|
67
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
67
68
|
if (!repulse) {
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
@@ -78,13 +79,13 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
78
79
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
79
80
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
80
81
|
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = divMode(divs, elem);
|
|
81
|
-
this._processRepulse(pos, repulseRadius, area, divRepulse);
|
|
82
|
+
this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);
|
|
82
83
|
});
|
|
83
84
|
};
|
|
84
85
|
this._engine = engine;
|
|
85
86
|
container.repulse ??= { particles: [] };
|
|
86
|
-
this.handleClickMode = (mode) => {
|
|
87
|
-
const options = this.container.actualOptions, repulseOpts = options.interactivity
|
|
87
|
+
this.handleClickMode = (mode, interactivityData) => {
|
|
88
|
+
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
88
89
|
if (!repulseOpts || mode !== repulseMode) {
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
@@ -93,7 +94,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
93
94
|
repulse.clicking = true;
|
|
94
95
|
repulse.count = 0;
|
|
95
96
|
for (const particle of container.repulse.particles) {
|
|
96
|
-
if (!this.isEnabled(particle)) {
|
|
97
|
+
if (!this.isEnabled(interactivityData, particle)) {
|
|
97
98
|
continue;
|
|
98
99
|
}
|
|
99
100
|
particle.velocity.setTo(particle.initialVelocity);
|
|
@@ -111,28 +112,36 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
111
112
|
clear() {
|
|
112
113
|
}
|
|
113
114
|
init() {
|
|
114
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
115
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
115
116
|
if (!repulse) {
|
|
116
117
|
return;
|
|
117
118
|
}
|
|
118
119
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
119
120
|
}
|
|
120
|
-
interact() {
|
|
121
|
-
const container = this.container, options = container.actualOptions, mouseMoveStatus =
|
|
121
|
+
interact(interactivityData) {
|
|
122
|
+
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
123
|
+
if (!events) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;
|
|
122
127
|
if (mouseMoveStatus && hoverEnabled && isInArray(repulseMode, hoverMode)) {
|
|
123
|
-
this._hoverRepulse();
|
|
128
|
+
this._hoverRepulse(interactivityData);
|
|
124
129
|
}
|
|
125
130
|
else if (clickEnabled && isInArray(repulseMode, clickMode)) {
|
|
126
|
-
this._clickRepulse();
|
|
131
|
+
this._clickRepulse(interactivityData);
|
|
127
132
|
}
|
|
128
133
|
else {
|
|
129
134
|
divModeExecute(repulseMode, divs, (selector, div) => {
|
|
130
|
-
this._singleSelectorRepulse(selector, div);
|
|
135
|
+
this._singleSelectorRepulse(interactivityData, selector, div);
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
|
-
isEnabled(particle) {
|
|
135
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
139
|
+
isEnabled(interactivityData, particle) {
|
|
140
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
141
|
+
if (!events) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = isDivModeEnabled(repulseMode, divs);
|
|
136
145
|
if (!(divRepulse || (hover.enable && !!mouse.position) || (click.enable && mouse.clickPosition))) {
|
|
137
146
|
return false;
|
|
138
147
|
}
|
package/browser/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
3
|
-
engine.register(e => {
|
|
4
|
-
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.4");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { loadInteractivityPlugin } = await import("@tsparticles/plugin-interactivity");
|
|
5
|
+
loadInteractivityPlugin(e);
|
|
6
|
+
e.addInteractor?.("externalRepulse", async (container) => {
|
|
5
7
|
const { Repulser } = await import("./Repulser.js");
|
|
6
8
|
return new Repulser(engine, container);
|
|
7
9
|
});
|
package/cjs/Repulser.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, Vector, clamp, getDistances, half, isInArray, millisecondsToSeconds, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Repulse } from "./Options/Classes/Repulse.js";
|
|
3
|
-
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1
|
|
4
|
+
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
4
5
|
export class Repulser extends ExternalInteractorBase {
|
|
5
6
|
constructor(engine, container) {
|
|
6
7
|
super(container);
|
|
7
|
-
this._clickRepulse =
|
|
8
|
-
const container = this.container, repulseOptions = container.actualOptions.interactivity
|
|
8
|
+
this._clickRepulse = interactivityData => {
|
|
9
|
+
const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
9
10
|
if (!repulseOptions) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
@@ -22,11 +23,11 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
22
23
|
if (!repulseDistance || repulseDistance < minDistance) {
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
|
-
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos =
|
|
26
|
+
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;
|
|
26
27
|
if (mouseClickPos === undefined) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(p));
|
|
30
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(interactivityData, p));
|
|
30
31
|
for (const particle of query) {
|
|
31
32
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
32
33
|
if (d <= repulseRadius) {
|
|
@@ -44,15 +45,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
44
45
|
repulse.particles = [];
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
|
-
this._hoverRepulse =
|
|
48
|
-
const container = this.container, mousePos =
|
|
48
|
+
this._hoverRepulse = interactivityData => {
|
|
49
|
+
const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;
|
|
49
50
|
if (!repulseRadius || repulseRadius < minRadius || !mousePos) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
this._processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
|
+
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
54
|
};
|
|
54
|
-
this._processRepulse = (position, repulseRadius, area, divRepulse) => {
|
|
55
|
-
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(p)), repulseOptions = container.actualOptions.interactivity
|
|
55
|
+
this._processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
56
|
+
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
56
57
|
if (!repulseOptions) {
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
@@ -62,8 +63,8 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
62
63
|
particle.position.addTo(normVec);
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
|
-
this._singleSelectorRepulse = (selector, div) => {
|
|
66
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
66
|
+
this._singleSelectorRepulse = (interactivityData, selector, div) => {
|
|
67
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
67
68
|
if (!repulse) {
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
@@ -78,13 +79,13 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
78
79
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
79
80
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
80
81
|
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = divMode(divs, elem);
|
|
81
|
-
this._processRepulse(pos, repulseRadius, area, divRepulse);
|
|
82
|
+
this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);
|
|
82
83
|
});
|
|
83
84
|
};
|
|
84
85
|
this._engine = engine;
|
|
85
86
|
container.repulse ??= { particles: [] };
|
|
86
|
-
this.handleClickMode = (mode) => {
|
|
87
|
-
const options = this.container.actualOptions, repulseOpts = options.interactivity
|
|
87
|
+
this.handleClickMode = (mode, interactivityData) => {
|
|
88
|
+
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
88
89
|
if (!repulseOpts || mode !== repulseMode) {
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
@@ -93,7 +94,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
93
94
|
repulse.clicking = true;
|
|
94
95
|
repulse.count = 0;
|
|
95
96
|
for (const particle of container.repulse.particles) {
|
|
96
|
-
if (!this.isEnabled(particle)) {
|
|
97
|
+
if (!this.isEnabled(interactivityData, particle)) {
|
|
97
98
|
continue;
|
|
98
99
|
}
|
|
99
100
|
particle.velocity.setTo(particle.initialVelocity);
|
|
@@ -111,28 +112,36 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
111
112
|
clear() {
|
|
112
113
|
}
|
|
113
114
|
init() {
|
|
114
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
115
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
115
116
|
if (!repulse) {
|
|
116
117
|
return;
|
|
117
118
|
}
|
|
118
119
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
119
120
|
}
|
|
120
|
-
interact() {
|
|
121
|
-
const container = this.container, options = container.actualOptions, mouseMoveStatus =
|
|
121
|
+
interact(interactivityData) {
|
|
122
|
+
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
123
|
+
if (!events) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;
|
|
122
127
|
if (mouseMoveStatus && hoverEnabled && isInArray(repulseMode, hoverMode)) {
|
|
123
|
-
this._hoverRepulse();
|
|
128
|
+
this._hoverRepulse(interactivityData);
|
|
124
129
|
}
|
|
125
130
|
else if (clickEnabled && isInArray(repulseMode, clickMode)) {
|
|
126
|
-
this._clickRepulse();
|
|
131
|
+
this._clickRepulse(interactivityData);
|
|
127
132
|
}
|
|
128
133
|
else {
|
|
129
134
|
divModeExecute(repulseMode, divs, (selector, div) => {
|
|
130
|
-
this._singleSelectorRepulse(selector, div);
|
|
135
|
+
this._singleSelectorRepulse(interactivityData, selector, div);
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
|
-
isEnabled(particle) {
|
|
135
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
139
|
+
isEnabled(interactivityData, particle) {
|
|
140
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
141
|
+
if (!events) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = isDivModeEnabled(repulseMode, divs);
|
|
136
145
|
if (!(divRepulse || (hover.enable && !!mouse.position) || (click.enable && mouse.clickPosition))) {
|
|
137
146
|
return false;
|
|
138
147
|
}
|
package/cjs/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
3
|
-
engine.register(e => {
|
|
4
|
-
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.4");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { loadInteractivityPlugin } = await import("@tsparticles/plugin-interactivity");
|
|
5
|
+
loadInteractivityPlugin(e);
|
|
6
|
+
e.addInteractor?.("externalRepulse", async (container) => {
|
|
5
7
|
const { Repulser } = await import("./Repulser.js");
|
|
6
8
|
return new Repulser(engine, container);
|
|
7
9
|
});
|
|
@@ -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.4
|
|
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 _Options_Classes_Repulse_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Repulse.js */ \"./dist/browser/Options/Classes/Repulse.js\");\n\n\nconst repulseMode = \"repulse\",\n minDistance = 0,\n repulseRadiusFactor = 6,\n repulseRadiusPower = 3,\n squarePower = 2,\n minRadius = 0,\n minSpeed = 0,\n easingOffset = 1,\n half = 0.5;\nclass Repulser extends _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.ExternalInteractorBase {\n constructor(engine, container) {\n super(container);\n this._clickRepulse = () => {\n const container = this.container,\n 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),\n mouseClickPos = container.interactivity.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),\n query = container.particles.quadTree.query(range, p => this.isEnabled(p));\n for (const particle of query) {\n const {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(mouseClickPos, particle.position),\n d = distance ** squarePower,\n velocity = repulseOptions.speed,\n 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 this._hoverRepulse = () => {\n const container = this.container,\n mousePos = container.interactivity.mouse.position,\n repulseRadius = container.retina.repulseModeDistance;\n if (!repulseRadius || repulseRadius < minRadius || !mousePos) {\n return;\n }\n this._processRepulse(mousePos, repulseRadius, new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(mousePos.x, mousePos.y, repulseRadius));\n };\n this._processRepulse = (position, repulseRadius, area, divRepulse) => {\n const container = this.container,\n query = container.particles.quadTree.query(area, p => this.isEnabled(p)),\n repulseOptions = container.actualOptions.interactivity.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const {\n easing,\n speed,\n factor,\n maxSpeed\n } = repulseOptions,\n easingFunc = this._engine.getEasing(easing),\n velocity = (divRepulse?.speed ?? speed) * factor;\n for (const particle of query) {\n const {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(particle.position, position),\n repulseFactor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed),\n 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 this._singleSelectorRepulse = (selector, div) => {\n const container = this.container,\n 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,\n pxRatio = container.retina.pixelRatio,\n pos = {\n x: (elem.offsetLeft + elem.offsetWidth * half) * pxRatio,\n y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio\n },\n repulseRadius = elem.offsetWidth * half * pxRatio,\n area = div.type === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.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),\n divs = repulse.divs,\n divRepulse = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.divMode)(divs, elem);\n this._processRepulse(pos, repulseRadius, area, divRepulse);\n });\n };\n this._engine = engine;\n container.repulse ??= {\n particles: []\n };\n this.handleClickMode = mode => {\n const options = this.container.actualOptions,\n 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(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,\n repulse = container.actualOptions.interactivity.modes.repulse;\n if (!repulse) {\n return;\n }\n container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;\n }\n interact() {\n const container = this.container,\n options = container.actualOptions,\n mouseMoveStatus = container.interactivity.status === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.mouseMoveEvent,\n events = options.interactivity.events,\n hover = events.onHover,\n hoverEnabled = hover.enable,\n hoverMode = hover.mode,\n click = events.onClick,\n clickEnabled = click.enable,\n clickMode = click.mode,\n divs = events.onDiv;\n if (mouseMoveStatus && hoverEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, hoverMode)) {\n this._hoverRepulse();\n } else if (clickEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(repulseMode, clickMode)) {\n this._clickRepulse();\n } else {\n (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.divModeExecute)(repulseMode, divs, (selector, div) => {\n this._singleSelectorRepulse(selector, div);\n });\n }\n }\n isEnabled(particle) {\n const container = this.container,\n options = container.actualOptions,\n mouse = container.interactivity.mouse,\n events = (particle?.interactivity ?? options.interactivity).events,\n divs = events.onDiv,\n hover = events.onHover,\n click = events.onClick,\n divRepulse = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isDivModeEnabled)(repulseMode, divs);\n if (!(divRepulse || hover.enable && !!mouse.position || click.enable && mouse.clickPosition)) {\n return false;\n }\n const hoverMode = hover.mode,\n 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_1__.Repulse();\n for (const source of sources) {\n options.repulse.load(source?.repulse);\n }\n }\n reset() {}\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\",\n minDistance = 0,\n repulseRadiusFactor = 6,\n repulseRadiusPower = 3,\n squarePower = 2,\n minRadius = 0,\n minSpeed = 0,\n easingOffset = 1;\nclass Repulser extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.ExternalInteractorBase {\n constructor(engine, container) {\n super(container);\n this._clickRepulse = interactivityData => {\n const container = this.container,\n 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),\n 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),\n query = container.particles.quadTree.query(range, p => this.isEnabled(interactivityData, p));\n for (const particle of query) {\n const {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(mouseClickPos, particle.position),\n d = distance ** squarePower,\n velocity = repulseOptions.speed,\n 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 this._hoverRepulse = interactivityData => {\n const container = this.container,\n mousePos = interactivityData.mouse.position,\n 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 this._processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {\n const container = this.container,\n query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p)),\n repulseOptions = container.actualOptions.interactivity?.modes.repulse;\n if (!repulseOptions) {\n return;\n }\n const {\n easing,\n speed,\n factor,\n maxSpeed\n } = repulseOptions,\n easingFunc = this._engine.getEasing(easing),\n velocity = (divRepulse?.speed ?? speed) * factor;\n for (const particle of query) {\n const {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(particle.position, position),\n repulseFactor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.clamp)(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed),\n 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 this._singleSelectorRepulse = (interactivityData, selector, div) => {\n const container = this.container,\n 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,\n pxRatio = container.retina.pixelRatio,\n 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 },\n repulseRadius = elem.offsetWidth * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half * pxRatio,\n 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),\n divs = repulse.divs,\n divRepulse = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divMode)(divs, elem);\n this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);\n });\n };\n this._engine = engine;\n container.repulse ??= {\n particles: []\n };\n this.handleClickMode = (mode, interactivityData) => {\n const options = this.container.actualOptions,\n 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,\n 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,\n options = container.actualOptions,\n mouseMoveStatus = interactivityData.status === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.mouseMoveEvent,\n events = options.interactivity?.events;\n if (!events) {\n return;\n }\n const hover = events.onHover,\n hoverEnabled = hover.enable,\n hoverMode = hover.mode,\n click = events.onClick,\n clickEnabled = click.enable,\n clickMode = click.mode,\n 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,\n options = container.actualOptions,\n mouse = interactivityData.mouse,\n events = (particle?.interactivity ?? options.interactivity)?.events;\n if (!events) {\n return false;\n }\n const divs = events.onDiv,\n hover = events.onHover,\n click = events.onClick,\n 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,\n 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}\n\n//# sourceURL=webpack://@tsparticles/interaction-external-repulse/./dist/browser/Repulser.js?\n}");
|
|
27
27
|
|
|
28
28
|
/***/ }
|
|
29
29
|
|
package/esm/Repulser.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, Vector, clamp, getDistances, half, isInArray, millisecondsToSeconds, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Repulse } from "./Options/Classes/Repulse.js";
|
|
3
|
-
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1
|
|
4
|
+
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
4
5
|
export class Repulser extends ExternalInteractorBase {
|
|
5
6
|
constructor(engine, container) {
|
|
6
7
|
super(container);
|
|
7
|
-
this._clickRepulse =
|
|
8
|
-
const container = this.container, repulseOptions = container.actualOptions.interactivity
|
|
8
|
+
this._clickRepulse = interactivityData => {
|
|
9
|
+
const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
9
10
|
if (!repulseOptions) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
@@ -22,11 +23,11 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
22
23
|
if (!repulseDistance || repulseDistance < minDistance) {
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
|
-
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos =
|
|
26
|
+
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;
|
|
26
27
|
if (mouseClickPos === undefined) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(p));
|
|
30
|
+
const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(interactivityData, p));
|
|
30
31
|
for (const particle of query) {
|
|
31
32
|
const { dx, dy, distance } = getDistances(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
32
33
|
if (d <= repulseRadius) {
|
|
@@ -44,15 +45,15 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
44
45
|
repulse.particles = [];
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
|
-
this._hoverRepulse =
|
|
48
|
-
const container = this.container, mousePos =
|
|
48
|
+
this._hoverRepulse = interactivityData => {
|
|
49
|
+
const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;
|
|
49
50
|
if (!repulseRadius || repulseRadius < minRadius || !mousePos) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
this._processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
|
+
this._processRepulse(interactivityData, mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
53
54
|
};
|
|
54
|
-
this._processRepulse = (position, repulseRadius, area, divRepulse) => {
|
|
55
|
-
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(p)), repulseOptions = container.actualOptions.interactivity
|
|
55
|
+
this._processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
56
|
+
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
56
57
|
if (!repulseOptions) {
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
@@ -62,8 +63,8 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
62
63
|
particle.position.addTo(normVec);
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
|
-
this._singleSelectorRepulse = (selector, div) => {
|
|
66
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
66
|
+
this._singleSelectorRepulse = (interactivityData, selector, div) => {
|
|
67
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
67
68
|
if (!repulse) {
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
@@ -78,13 +79,13 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
78
79
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
79
80
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
80
81
|
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = divMode(divs, elem);
|
|
81
|
-
this._processRepulse(pos, repulseRadius, area, divRepulse);
|
|
82
|
+
this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);
|
|
82
83
|
});
|
|
83
84
|
};
|
|
84
85
|
this._engine = engine;
|
|
85
86
|
container.repulse ??= { particles: [] };
|
|
86
|
-
this.handleClickMode = (mode) => {
|
|
87
|
-
const options = this.container.actualOptions, repulseOpts = options.interactivity
|
|
87
|
+
this.handleClickMode = (mode, interactivityData) => {
|
|
88
|
+
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
88
89
|
if (!repulseOpts || mode !== repulseMode) {
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
@@ -93,7 +94,7 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
93
94
|
repulse.clicking = true;
|
|
94
95
|
repulse.count = 0;
|
|
95
96
|
for (const particle of container.repulse.particles) {
|
|
96
|
-
if (!this.isEnabled(particle)) {
|
|
97
|
+
if (!this.isEnabled(interactivityData, particle)) {
|
|
97
98
|
continue;
|
|
98
99
|
}
|
|
99
100
|
particle.velocity.setTo(particle.initialVelocity);
|
|
@@ -111,28 +112,36 @@ export class Repulser extends ExternalInteractorBase {
|
|
|
111
112
|
clear() {
|
|
112
113
|
}
|
|
113
114
|
init() {
|
|
114
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
115
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
115
116
|
if (!repulse) {
|
|
116
117
|
return;
|
|
117
118
|
}
|
|
118
119
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
119
120
|
}
|
|
120
|
-
interact() {
|
|
121
|
-
const container = this.container, options = container.actualOptions, mouseMoveStatus =
|
|
121
|
+
interact(interactivityData) {
|
|
122
|
+
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === mouseMoveEvent, events = options.interactivity?.events;
|
|
123
|
+
if (!events) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;
|
|
122
127
|
if (mouseMoveStatus && hoverEnabled && isInArray(repulseMode, hoverMode)) {
|
|
123
|
-
this._hoverRepulse();
|
|
128
|
+
this._hoverRepulse(interactivityData);
|
|
124
129
|
}
|
|
125
130
|
else if (clickEnabled && isInArray(repulseMode, clickMode)) {
|
|
126
|
-
this._clickRepulse();
|
|
131
|
+
this._clickRepulse(interactivityData);
|
|
127
132
|
}
|
|
128
133
|
else {
|
|
129
134
|
divModeExecute(repulseMode, divs, (selector, div) => {
|
|
130
|
-
this._singleSelectorRepulse(selector, div);
|
|
135
|
+
this._singleSelectorRepulse(interactivityData, selector, div);
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
|
-
isEnabled(particle) {
|
|
135
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
139
|
+
isEnabled(interactivityData, particle) {
|
|
140
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
141
|
+
if (!events) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = isDivModeEnabled(repulseMode, divs);
|
|
136
145
|
if (!(divRepulse || (hover.enable && !!mouse.position) || (click.enable && mouse.clickPosition))) {
|
|
137
146
|
return false;
|
|
138
147
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalRepulseInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
3
|
-
engine.register(e => {
|
|
4
|
-
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.4");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { loadInteractivityPlugin } = await import("@tsparticles/plugin-interactivity");
|
|
5
|
+
loadInteractivityPlugin(e);
|
|
6
|
+
e.addInteractor?.("externalRepulse", async (container) => {
|
|
5
7
|
const { Repulser } = await import("./Repulser.js");
|
|
6
8
|
return new Repulser(engine, container);
|
|
7
9
|
});
|
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.4",
|
|
4
4
|
"description": "tsParticles repulse external interaction",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -87,7 +87,8 @@
|
|
|
87
87
|
"./package.json": "./package.json"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@tsparticles/engine": "4.0.0-alpha.
|
|
90
|
+
"@tsparticles/engine": "4.0.0-alpha.4",
|
|
91
|
+
"@tsparticles/plugin-interactivity": "4.0.0-alpha.4"
|
|
91
92
|
},
|
|
92
93
|
"publishConfig": {
|
|
93
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 [21 Jan 2026 at 14:44]</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.4
|
|
8
8
|
*/
|
|
9
9
|
/*
|
|
10
10
|
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
*/
|
|
17
17
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
18
18
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
19
|
-
module.exports = factory(require("@tsparticles/engine"));
|
|
19
|
+
module.exports = factory(require("@tsparticles/engine"), require("@tsparticles/plugin-interactivity"));
|
|
20
20
|
else if(typeof define === 'function' && define.amd)
|
|
21
|
-
define(["@tsparticles/engine"], factory);
|
|
21
|
+
define(["@tsparticles/engine", "@tsparticles/plugin-interactivity"], factory);
|
|
22
22
|
else {
|
|
23
|
-
var a = typeof exports === 'object' ? factory(require("@tsparticles/engine")) : factory(root["window"]);
|
|
23
|
+
var a = typeof exports === 'object' ? factory(require("@tsparticles/engine"), require("@tsparticles/plugin-interactivity")) : factory(root["window"], root["window"]);
|
|
24
24
|
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
|
|
25
25
|
}
|
|
26
|
-
})(this, (__WEBPACK_EXTERNAL_MODULE__tsparticles_engine__) => {
|
|
26
|
+
})(this, (__WEBPACK_EXTERNAL_MODULE__tsparticles_engine__, __WEBPACK_EXTERNAL_MODULE__tsparticles_plugin_interactivity__) => {
|
|
27
27
|
return /******/ (() => { // webpackBootstrap
|
|
28
28
|
/******/ "use strict";
|
|
29
29
|
/******/ var __webpack_modules__ = ({
|
|
@@ -64,7 +64,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
64
64
|
\*******************************/
|
|
65
65
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
66
66
|
|
|
67
|
-
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\");\nfunction loadExternalRepulseInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.
|
|
67
|
+
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\");\nfunction loadExternalRepulseInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.4\");\n engine.register(async e => {\n const {\n loadInteractivityPlugin\n } = await Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\", 19));\n loadInteractivityPlugin(e);\n e.addInteractor?.(\"externalRepulse\", async container => {\n const {\n Repulser\n } = 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//# sourceURL=webpack://@tsparticles/interaction-external-repulse/./dist/browser/index.js?\n}");
|
|
68
68
|
|
|
69
69
|
/***/ },
|
|
70
70
|
|
|
@@ -76,6 +76,16 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
76
76
|
|
|
77
77
|
module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
78
78
|
|
|
79
|
+
/***/ },
|
|
80
|
+
|
|
81
|
+
/***/ "@tsparticles/plugin-interactivity"
|
|
82
|
+
/*!***************************************************************************************************************************************************************************!*\
|
|
83
|
+
!*** external {"commonjs":"@tsparticles/plugin-interactivity","commonjs2":"@tsparticles/plugin-interactivity","amd":"@tsparticles/plugin-interactivity","root":"window"} ***!
|
|
84
|
+
\***************************************************************************************************************************************************************************/
|
|
85
|
+
(module) {
|
|
86
|
+
|
|
87
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_plugin_interactivity__;
|
|
88
|
+
|
|
79
89
|
/***/ }
|
|
80
90
|
|
|
81
91
|
/******/ });
|
|
@@ -114,6 +124,36 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
114
124
|
/******/ __webpack_require__.m = __webpack_modules__;
|
|
115
125
|
/******/
|
|
116
126
|
/************************************************************************/
|
|
127
|
+
/******/ /* webpack/runtime/create fake namespace object */
|
|
128
|
+
/******/ (() => {
|
|
129
|
+
/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);
|
|
130
|
+
/******/ var leafPrototypes;
|
|
131
|
+
/******/ // create a fake namespace object
|
|
132
|
+
/******/ // mode & 1: value is a module id, require it
|
|
133
|
+
/******/ // mode & 2: merge all properties of value into the ns
|
|
134
|
+
/******/ // mode & 4: return value when already ns object
|
|
135
|
+
/******/ // mode & 16: return value when it's Promise-like
|
|
136
|
+
/******/ // mode & 8|1: behave like require
|
|
137
|
+
/******/ __webpack_require__.t = function(value, mode) {
|
|
138
|
+
/******/ if(mode & 1) value = this(value);
|
|
139
|
+
/******/ if(mode & 8) return value;
|
|
140
|
+
/******/ if(typeof value === 'object' && value) {
|
|
141
|
+
/******/ if((mode & 4) && value.__esModule) return value;
|
|
142
|
+
/******/ if((mode & 16) && typeof value.then === 'function') return value;
|
|
143
|
+
/******/ }
|
|
144
|
+
/******/ var ns = Object.create(null);
|
|
145
|
+
/******/ __webpack_require__.r(ns);
|
|
146
|
+
/******/ var def = {};
|
|
147
|
+
/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
|
|
148
|
+
/******/ for(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) {
|
|
149
|
+
/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));
|
|
150
|
+
/******/ }
|
|
151
|
+
/******/ def['default'] = () => (value);
|
|
152
|
+
/******/ __webpack_require__.d(ns, def);
|
|
153
|
+
/******/ return ns;
|
|
154
|
+
/******/ };
|
|
155
|
+
/******/ })();
|
|
156
|
+
/******/
|
|
117
157
|
/******/ /* webpack/runtime/define property getters */
|
|
118
158
|
/******/ (() => {
|
|
119
159
|
/******/ // define getter functions for harmony exports
|
|
@@ -148,18 +188,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
148
188
|
/******/ };
|
|
149
189
|
/******/ })();
|
|
150
190
|
/******/
|
|
151
|
-
/******/ /* webpack/runtime/global */
|
|
152
|
-
/******/ (() => {
|
|
153
|
-
/******/ __webpack_require__.g = (function() {
|
|
154
|
-
/******/ if (typeof globalThis === 'object') return globalThis;
|
|
155
|
-
/******/ try {
|
|
156
|
-
/******/ return this || new Function('return this')();
|
|
157
|
-
/******/ } catch (e) {
|
|
158
|
-
/******/ if (typeof window === 'object') return window;
|
|
159
|
-
/******/ }
|
|
160
|
-
/******/ })();
|
|
161
|
-
/******/ })();
|
|
162
|
-
/******/
|
|
163
191
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
164
192
|
/******/ (() => {
|
|
165
193
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
@@ -224,8 +252,8 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
224
252
|
/******/ /* webpack/runtime/publicPath */
|
|
225
253
|
/******/ (() => {
|
|
226
254
|
/******/ var scriptUrl;
|
|
227
|
-
/******/ if (
|
|
228
|
-
/******/ var document =
|
|
255
|
+
/******/ if (globalThis.importScripts) scriptUrl = globalThis.location + "";
|
|
256
|
+
/******/ var document = globalThis.document;
|
|
229
257
|
/******/ if (!scriptUrl && document) {
|
|
230
258
|
/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')
|
|
231
259
|
/******/ scriptUrl = document.currentScript.src;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see tsparticles.interaction.external.repulse.min.js.LICENSE.txt */
|
|
2
|
-
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine")):t(e.window);for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,(e=>(()=>{var
|
|
2
|
+
!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)=>(()=>{var r,i,o,n,a={303(t){t.exports=e},591(e,t,r){r.d(t,{Z:()=>a});var i=r(303),o=r(790),n=r(680);class a extends o._{load(e){super.load(e),(0,i.isNull)(e)||(this.divs=(0,i.executeOnSingleOrMultiple)(e.divs,(e=>{const t=new n.W;return t.load(e),t})))}}},680(e,t,r){r.d(t,{W:()=>n});var i=r(303),o=r(790);class n extends o._{constructor(){super(),this.selectors=[]}load(e){super.load(e),(0,i.isNull)(e)||void 0!==e.selectors&&(this.selectors=e.selectors)}}},702(e){e.exports=t},790(e,t,r){r.d(t,{_:()=>o});var i=r(303);class o{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))}}}},s={};function l(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}};return a[e](r,r.exports,l),r.exports}l.m=a,i=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,l.t=function(e,t){if(1&t&&(e=this(e)),8&t)return e;if("object"==typeof e&&e){if(4&t&&e.__esModule)return e;if(16&t&&"function"==typeof e.then)return e}var o=Object.create(null);l.r(o);var n={};r=r||[null,i({}),i([]),i(i)];for(var a=2&t&&e;("object"==typeof a||"function"==typeof a)&&!~r.indexOf(a);a=i(a))Object.getOwnPropertyNames(a).forEach((t=>n[t]=()=>e[t]));return n.default=()=>e,l.d(o,n),o},l.d=(e,t)=>{for(var r in t)l.o(t,r)&&!l.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},l.f={},l.e=e=>Promise.all(Object.keys(l.f).reduce(((t,r)=>(l.f[r](e,t),t)),[])),l.u=e=>e+".min.js",l.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o={},n="@tsparticles/interaction-external-repulse:",l.l=(e,t,r,i)=>{if(o[e])o[e].push(t);else{var a,s;if(void 0!==r)for(var c=document.getElementsByTagName("script"),p=0;p<c.length;p++){var u=c[p];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==n+r){a=u;break}}a||(s=!0,(a=document.createElement("script")).charset="utf-8",l.nc&&a.setAttribute("nonce",l.nc),a.setAttribute("data-webpack",n+r),a.src=e),o[e]=[t];var d=(t,r)=>{a.onerror=a.onload=null,clearTimeout(f);var i=o[e];if(delete o[e],a.parentNode&&a.parentNode.removeChild(a),i&&i.forEach((e=>e(r))),t)return t(r)},f=setTimeout(d.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=d.bind(null,a.onerror),a.onload=d.bind(null,a.onload),s&&document.head.appendChild(a)}},l.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;globalThis.importScripts&&(e=globalThis.location+"");var t=globalThis.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var i=r.length-1;i>-1&&(!e||!/^http(s?):/.test(e));)e=r[i--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),l.p=e})(),(()=>{var e={64:0};l.f.j=(t,r)=>{var i=l.o(e,t)?e[t]:void 0;if(0!==i)if(i)r.push(i[2]);else{var o=new Promise(((r,o)=>i=e[t]=[r,o]));r.push(i[2]=o);var n=l.p+l.u(t),a=new Error;l.l(n,(r=>{if(l.o(e,t)&&(0!==(i=e[t])&&(e[t]=void 0),i)){var o=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;a.message="Loading chunk "+t+" failed.\n("+o+": "+n+")",a.name="ChunkLoadError",a.type=o,a.request=n,i[1](a)}}),"chunk-"+t,t)}};var t=(t,r)=>{var i,o,[n,a,s]=r,c=0;if(n.some((t=>0!==e[t]))){for(i in a)l.o(a,i)&&(l.m[i]=a[i]);if(s)s(l)}for(t&&t(r);c<n.length;c++)o=n[c],l.o(e,o)&&e[o]&&e[o][0](),e[o]=0},r=this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var c={};l.r(c),l.d(c,{Repulse:()=>d.Z,RepulseBase:()=>p._,RepulseDiv:()=>u.W,loadExternalRepulseInteraction:()=>f});var p=l(790),u=l(680),d=l(591);function f(e){e.checkVersion("4.0.0-alpha.4"),e.register((async t=>{const{loadInteractivityPlugin:r}=await Promise.resolve().then(l.t.bind(l,702,19));r(t),t.addInteractor?.("externalRepulse",(async t=>{const{Repulser:r}=await l.e(783).then(l.bind(l,783));return new r(e,t)}))}))}return c})()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tsParticles Repulse External Interaction v4.0.0-alpha.
|
|
1
|
+
/*! tsParticles Repulse External Interaction v4.0.0-alpha.4 by Matteo Bruni */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { InteractivityOptions } from "@tsparticles/plugin-interactivity";
|
|
2
2
|
import type { RepulseMode } from "../../Types.js";
|
|
3
|
-
export type RepulseOptions =
|
|
4
|
-
interactivity
|
|
3
|
+
export type RepulseOptions = InteractivityOptions & {
|
|
4
|
+
interactivity?: {
|
|
5
5
|
modes: RepulseMode;
|
|
6
6
|
};
|
|
7
7
|
};
|
package/types/Repulser.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { type Engine,
|
|
1
|
+
import { type Engine, type RecursivePartial } from "@tsparticles/engine";
|
|
2
|
+
import { ExternalInteractorBase, type IInteractivityData, type IModes, type InteractivityParticle, type Modes } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import type { IRepulseMode, RepulseContainer, RepulseMode } from "./Types.js";
|
|
3
4
|
export declare class Repulser extends ExternalInteractorBase<RepulseContainer> {
|
|
4
|
-
handleClickMode: (mode: string) => void;
|
|
5
|
+
handleClickMode: (mode: string, interactivityData: IInteractivityData) => void;
|
|
5
6
|
private readonly _engine;
|
|
6
7
|
constructor(engine: Engine, container: RepulseContainer);
|
|
7
8
|
clear(): void;
|
|
8
9
|
init(): void;
|
|
9
|
-
interact(): void;
|
|
10
|
-
isEnabled(particle?:
|
|
10
|
+
interact(interactivityData: IInteractivityData): void;
|
|
11
|
+
isEnabled(interactivityData: IInteractivityData, particle?: InteractivityParticle): boolean;
|
|
11
12
|
loadModeOptions(options: Modes & RepulseMode, ...sources: RecursivePartial<(IModes & IRepulseMode) | undefined>[]): void;
|
|
12
13
|
reset(): void;
|
|
13
14
|
private readonly _clickRepulse;
|
package/types/Types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Container, Particle } from "@tsparticles/engine";
|
|
2
1
|
import type { IRepulse } from "./Options/Interfaces/IRepulse.js";
|
|
2
|
+
import type { InteractivityContainer } from "@tsparticles/plugin-interactivity";
|
|
3
|
+
import type { Particle } from "@tsparticles/engine";
|
|
3
4
|
import type { Repulse } from "./Options/Classes/Repulse.js";
|
|
4
5
|
import type { RepulseOptions } from "./Options/Classes/RepulseOptions.js";
|
|
5
6
|
export interface IRepulseMode {
|
|
@@ -14,7 +15,7 @@ interface IContainerRepulse {
|
|
|
14
15
|
finish?: boolean;
|
|
15
16
|
particles: Particle[];
|
|
16
17
|
}
|
|
17
|
-
export type RepulseContainer =
|
|
18
|
+
export type RepulseContainer = InteractivityContainer & {
|
|
18
19
|
actualOptions: RepulseOptions;
|
|
19
20
|
repulse?: IContainerRepulse;
|
|
20
21
|
retina: {
|
package/umd/Repulser.js
CHANGED
|
@@ -4,20 +4,21 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "@tsparticles/engine", "./Options/Classes/Repulse.js"], factory);
|
|
7
|
+
define(["require", "exports", "@tsparticles/engine", "@tsparticles/plugin-interactivity", "./Options/Classes/Repulse.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.Repulser = void 0;
|
|
13
13
|
const engine_1 = require("@tsparticles/engine");
|
|
14
|
+
const plugin_interactivity_1 = require("@tsparticles/plugin-interactivity");
|
|
14
15
|
const Repulse_js_1 = require("./Options/Classes/Repulse.js");
|
|
15
|
-
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1
|
|
16
|
-
class Repulser extends
|
|
16
|
+
const repulseMode = "repulse", minDistance = 0, repulseRadiusFactor = 6, repulseRadiusPower = 3, squarePower = 2, minRadius = 0, minSpeed = 0, easingOffset = 1;
|
|
17
|
+
class Repulser extends plugin_interactivity_1.ExternalInteractorBase {
|
|
17
18
|
constructor(engine, container) {
|
|
18
19
|
super(container);
|
|
19
|
-
this._clickRepulse =
|
|
20
|
-
const container = this.container, repulseOptions = container.actualOptions.interactivity
|
|
20
|
+
this._clickRepulse = interactivityData => {
|
|
21
|
+
const container = this.container, repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
21
22
|
if (!repulseOptions) {
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
@@ -34,11 +35,11 @@
|
|
|
34
35
|
if (!repulseDistance || repulseDistance < minDistance) {
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
|
-
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos =
|
|
38
|
+
const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower), mouseClickPos = interactivityData.mouse.clickPosition;
|
|
38
39
|
if (mouseClickPos === undefined) {
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
const range = new engine_1.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(p));
|
|
42
|
+
const range = new engine_1.Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range, p => this.isEnabled(interactivityData, p));
|
|
42
43
|
for (const particle of query) {
|
|
43
44
|
const { dx, dy, distance } = (0, engine_1.getDistances)(mouseClickPos, particle.position), d = distance ** squarePower, velocity = repulseOptions.speed, force = (-repulseRadius * velocity) / d;
|
|
44
45
|
if (d <= repulseRadius) {
|
|
@@ -56,15 +57,15 @@
|
|
|
56
57
|
repulse.particles = [];
|
|
57
58
|
}
|
|
58
59
|
};
|
|
59
|
-
this._hoverRepulse =
|
|
60
|
-
const container = this.container, mousePos =
|
|
60
|
+
this._hoverRepulse = interactivityData => {
|
|
61
|
+
const container = this.container, mousePos = interactivityData.mouse.position, repulseRadius = container.retina.repulseModeDistance;
|
|
61
62
|
if (!repulseRadius || repulseRadius < minRadius || !mousePos) {
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
|
-
this._processRepulse(mousePos, repulseRadius, new engine_1.Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
65
|
+
this._processRepulse(interactivityData, mousePos, repulseRadius, new engine_1.Circle(mousePos.x, mousePos.y, repulseRadius));
|
|
65
66
|
};
|
|
66
|
-
this._processRepulse = (position, repulseRadius, area, divRepulse) => {
|
|
67
|
-
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(p)), repulseOptions = container.actualOptions.interactivity
|
|
67
|
+
this._processRepulse = (interactivityData, position, repulseRadius, area, divRepulse) => {
|
|
68
|
+
const container = this.container, query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p)), repulseOptions = container.actualOptions.interactivity?.modes.repulse;
|
|
68
69
|
if (!repulseOptions) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
@@ -74,8 +75,8 @@
|
|
|
74
75
|
particle.position.addTo(normVec);
|
|
75
76
|
}
|
|
76
77
|
};
|
|
77
|
-
this._singleSelectorRepulse = (selector, div) => {
|
|
78
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
78
|
+
this._singleSelectorRepulse = (interactivityData, selector, div) => {
|
|
79
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
79
80
|
if (!repulse) {
|
|
80
81
|
return;
|
|
81
82
|
}
|
|
@@ -85,18 +86,18 @@
|
|
|
85
86
|
}
|
|
86
87
|
query.forEach(item => {
|
|
87
88
|
const elem = item, pxRatio = container.retina.pixelRatio, pos = {
|
|
88
|
-
x: (elem.offsetLeft + elem.offsetWidth * half) * pxRatio,
|
|
89
|
-
y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio,
|
|
90
|
-
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type ===
|
|
89
|
+
x: (elem.offsetLeft + elem.offsetWidth * engine_1.half) * pxRatio,
|
|
90
|
+
y: (elem.offsetTop + elem.offsetHeight * engine_1.half) * pxRatio,
|
|
91
|
+
}, repulseRadius = elem.offsetWidth * engine_1.half * pxRatio, area = div.type === plugin_interactivity_1.DivType.circle
|
|
91
92
|
? new engine_1.Circle(pos.x, pos.y, repulseRadius)
|
|
92
|
-
: new engine_1.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = (0,
|
|
93
|
-
this._processRepulse(pos, repulseRadius, area, divRepulse);
|
|
93
|
+
: new engine_1.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = repulse.divs, divRepulse = (0, plugin_interactivity_1.divMode)(divs, elem);
|
|
94
|
+
this._processRepulse(interactivityData, pos, repulseRadius, area, divRepulse);
|
|
94
95
|
});
|
|
95
96
|
};
|
|
96
97
|
this._engine = engine;
|
|
97
98
|
container.repulse ??= { particles: [] };
|
|
98
|
-
this.handleClickMode = (mode) => {
|
|
99
|
-
const options = this.container.actualOptions, repulseOpts = options.interactivity
|
|
99
|
+
this.handleClickMode = (mode, interactivityData) => {
|
|
100
|
+
const options = this.container.actualOptions, repulseOpts = options.interactivity?.modes.repulse;
|
|
100
101
|
if (!repulseOpts || mode !== repulseMode) {
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
@@ -105,7 +106,7 @@
|
|
|
105
106
|
repulse.clicking = true;
|
|
106
107
|
repulse.count = 0;
|
|
107
108
|
for (const particle of container.repulse.particles) {
|
|
108
|
-
if (!this.isEnabled(particle)) {
|
|
109
|
+
if (!this.isEnabled(interactivityData, particle)) {
|
|
109
110
|
continue;
|
|
110
111
|
}
|
|
111
112
|
particle.velocity.setTo(particle.initialVelocity);
|
|
@@ -123,28 +124,36 @@
|
|
|
123
124
|
clear() {
|
|
124
125
|
}
|
|
125
126
|
init() {
|
|
126
|
-
const container = this.container, repulse = container.actualOptions.interactivity
|
|
127
|
+
const container = this.container, repulse = container.actualOptions.interactivity?.modes.repulse;
|
|
127
128
|
if (!repulse) {
|
|
128
129
|
return;
|
|
129
130
|
}
|
|
130
131
|
container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
|
|
131
132
|
}
|
|
132
|
-
interact() {
|
|
133
|
-
const container = this.container, options = container.actualOptions, mouseMoveStatus =
|
|
133
|
+
interact(interactivityData) {
|
|
134
|
+
const container = this.container, options = container.actualOptions, mouseMoveStatus = interactivityData.status === plugin_interactivity_1.mouseMoveEvent, events = options.interactivity?.events;
|
|
135
|
+
if (!events) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const hover = events.onHover, hoverEnabled = hover.enable, hoverMode = hover.mode, click = events.onClick, clickEnabled = click.enable, clickMode = click.mode, divs = events.onDiv;
|
|
134
139
|
if (mouseMoveStatus && hoverEnabled && (0, engine_1.isInArray)(repulseMode, hoverMode)) {
|
|
135
|
-
this._hoverRepulse();
|
|
140
|
+
this._hoverRepulse(interactivityData);
|
|
136
141
|
}
|
|
137
142
|
else if (clickEnabled && (0, engine_1.isInArray)(repulseMode, clickMode)) {
|
|
138
|
-
this._clickRepulse();
|
|
143
|
+
this._clickRepulse(interactivityData);
|
|
139
144
|
}
|
|
140
145
|
else {
|
|
141
|
-
(0,
|
|
142
|
-
this._singleSelectorRepulse(selector, div);
|
|
146
|
+
(0, plugin_interactivity_1.divModeExecute)(repulseMode, divs, (selector, div) => {
|
|
147
|
+
this._singleSelectorRepulse(interactivityData, selector, div);
|
|
143
148
|
});
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
|
-
isEnabled(particle) {
|
|
147
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
151
|
+
isEnabled(interactivityData, particle) {
|
|
152
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
153
|
+
if (!events) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const divs = events.onDiv, hover = events.onHover, click = events.onClick, divRepulse = (0, plugin_interactivity_1.isDivModeEnabled)(repulseMode, divs);
|
|
148
157
|
if (!(divRepulse || (hover.enable && !!mouse.position) || (click.enable && mouse.clickPosition))) {
|
|
149
158
|
return false;
|
|
150
159
|
}
|
package/umd/index.js
CHANGED
|
@@ -48,10 +48,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.loadExternalRepulseInteraction = loadExternalRepulseInteraction;
|
|
50
50
|
function loadExternalRepulseInteraction(engine) {
|
|
51
|
-
engine.checkVersion("4.0.0-alpha.
|
|
52
|
-
engine.register(e => {
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
engine.checkVersion("4.0.0-alpha.4");
|
|
52
|
+
engine.register(async (e) => {
|
|
53
|
+
const { loadInteractivityPlugin } = 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
|
+
loadInteractivityPlugin(e);
|
|
55
|
+
e.addInteractor?.("externalRepulse", async (container) => {
|
|
56
|
+
const { Repulser } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./Repulser.js"))) : new Promise((resolve_2, reject_2) => { require(["./Repulser.js"], resolve_2, reject_2); }).then(__importStar));
|
|
55
57
|
return new Repulser(engine, container);
|
|
56
58
|
});
|
|
57
59
|
});
|
package/176.min.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! For license information please see 176.min.js.LICENSE.txt */
|
|
2
|
-
(this.webpackChunk_tsparticles_interaction_external_repulse=this.webpackChunk_tsparticles_interaction_external_repulse||[]).push([[176],{176(e,t,i){i.d(t,{Repulser:()=>c});var s=i(303),n=i(246);const o="repulse";class c extends s.ExternalInteractorBase{constructor(e,t){super(t),this._clickRepulse=()=>{const e=this.container,t=e.actualOptions.interactivity.modes.repulse;if(!t)return;const i=e.repulse??{particles:[]};if(i.finish||(i.count??=0,i.count++,i.count===e.particles.count&&(i.finish=!0)),i.clicking){const n=e.retina.repulseModeDistance;if(!n||n<0)return;const o=Math.pow(n/6,3),c=e.interactivity.mouse.clickPosition;if(void 0===c)return;const r=new s.Circle(c.x,c.y,o),a=e.particles.quadTree.query(r,(e=>this.isEnabled(e)));for(const e of a){const{dx:n,dy:r,distance:a}=(0,s.getDistances)(c,e.position),l=a**2,p=-o*t.speed/l;if(l<=o){i.particles.push(e);const t=s.Vector.create(n,r);t.length=p,e.velocity.setTo(t)}}}else if(!1===i.clicking){for(const e of i.particles)e.velocity.setTo(e.initialVelocity);i.particles=[]}},this._hoverRepulse=()=>{const e=this.container,t=e.interactivity.mouse.position,i=e.retina.repulseModeDistance;!i||i<0||!t||this._processRepulse(t,i,new s.Circle(t.x,t.y,i))},this._processRepulse=(e,t,i,n)=>{const o=this.container,c=o.particles.quadTree.query(i,(e=>this.isEnabled(e))),r=o.actualOptions.interactivity.modes.repulse;if(!r)return;const{easing:a,speed:l,factor:p,maxSpeed:u}=r,d=this._engine.getEasing(a),f=(n?.speed??l)*p;for(const i of c){const{dx:n,dy:o,distance:c}=(0,s.getDistances)(i.position,e),r=(0,s.clamp)(d(1-c/t)*f,0,u),a=s.Vector.create(c?n/c*r:f,c?o/c*r:f);i.position.addTo(a)}},this._singleSelectorRepulse=(e,t)=>{const i=this.container,n=i.actualOptions.interactivity.modes.repulse;if(!n)return;const o=(0,s.safeDocument)().querySelectorAll(e);o.length&&o.forEach((e=>{const o=e,c=i.retina.pixelRatio,r={x:(o.offsetLeft+.5*o.offsetWidth)*c,y:(o.offsetTop+.5*o.offsetHeight)*c},a=.5*o.offsetWidth*c,l=t.type===s.DivType.circle?new s.Circle(r.x,r.y,a):new s.Rectangle(o.offsetLeft*c,o.offsetTop*c,o.offsetWidth*c,o.offsetHeight*c),p=n.divs,u=(0,s.divMode)(p,o);this._processRepulse(r,a,l,u)}))},this._engine=e,t.repulse??={particles:[]},this.handleClickMode=e=>{const i=this.container.actualOptions.interactivity.modes.repulse;if(!i||e!==o)return;t.repulse??={particles:[]};const n=t.repulse;n.clicking=!0,n.count=0;for(const e of t.repulse.particles)this.isEnabled(e)&&e.velocity.setTo(e.initialVelocity);n.particles=[],n.finish=!1,setTimeout((()=>{t.destroyed||(n.clicking=!1)}),i.duration*s.millisecondsToSeconds)}}clear(){}init(){const e=this.container,t=e.actualOptions.interactivity.modes.repulse;t&&(e.retina.repulseModeDistance=t.distance*e.retina.pixelRatio)}interact(){const e=this.container,t=e.actualOptions,i=e.interactivity.status===s.mouseMoveEvent,n=t.interactivity.events,c=n.onHover,r=c.enable,a=c.mode,l=n.onClick,p=l.enable,u=l.mode,d=n.onDiv;i&&r&&(0,s.isInArray)(o,a)?this._hoverRepulse():p&&(0,s.isInArray)(o,u)?this._clickRepulse():(0,s.divModeExecute)(o,d,((e,t)=>{this._singleSelectorRepulse(e,t)}))}isEnabled(e){const t=this.container,i=t.actualOptions,n=t.interactivity.mouse,c=(e?.interactivity??i.interactivity).events,r=c.onDiv,a=c.onHover,l=c.onClick,p=(0,s.isDivModeEnabled)(o,r);if(!(p||a.enable&&n.position||l.enable&&n.clickPosition))return!1;const u=a.mode,d=l.mode;return(0,s.isInArray)(o,u)||(0,s.isInArray)(o,d)||p}loadModeOptions(e,...t){e.repulse??=new n.Z;for(const i of t)e.repulse.load(i?.repulse)}reset(){}}}}]);
|
package/176.min.js.LICENSE.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! tsParticles Repulse External Interaction v4.0.0-alpha.2 by Matteo Bruni */
|