@tsparticles/interaction-external-bubble 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/132.min.js +2 -0
- package/132.min.js.LICENSE.txt +1 -0
- package/browser/Bubbler.js +37 -28
- package/browser/index.js +5 -3
- package/cjs/Bubbler.js +37 -28
- package/cjs/index.js +5 -3
- package/dist_browser_Bubbler_js.js +2 -2
- package/esm/Bubbler.js +37 -28
- package/esm/index.js +5 -3
- package/package.json +3 -2
- package/report.html +1 -1
- package/tsparticles.interaction.external.bubble.js +48 -20
- package/tsparticles.interaction.external.bubble.min.js +1 -1
- package/tsparticles.interaction.external.bubble.min.js.LICENSE.txt +1 -1
- package/types/Bubbler.d.ts +6 -5
- package/types/Options/Classes/BubbleOptions.d.ts +3 -3
- package/types/Options/Interfaces/IBubbleDiv.d.ts +1 -1
- package/types/Types.d.ts +2 -2
- package/umd/Bubbler.js +44 -35
- package/umd/index.js +6 -4
- package/809.min.js +0 -2
- package/809.min.js.LICENSE.txt +0 -1
package/132.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 132.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_interaction_external_bubble=this.webpackChunk_tsparticles_interaction_external_bubble||[]).push([[132],{132(e,i,t){t.d(i,{Bubbler:()=>r});var o,b=t(303),n=t(702),l=t(443);function s(e,i,t,o){if(i>=t){const n=e+(i-t)*o;return(0,b.clamp)(n,e,i)}if(i<t){const n=e-(t-i)*o;return(0,b.clamp)(n,i,e)}}!function(e){e.color="color",e.opacity="opacity",e.size="size"}(o||(o={}));const a="bubble";class r extends n.ExternalInteractorBase{constructor(e,i){super(i),this._clickBubble=e=>{const i=this.container,t=i.actualOptions,n=e.mouse.clickPosition,l=t.interactivity?.modes.bubble;if(!l||!n)return;i.bubble??={};const s=i.retina.bubbleModeDistance;if(!s||s<0)return;const a=i.particles.quadTree.queryCircle(n,s,(i=>this.isEnabled(e,i))),{bubble:r}=i;for(const t of a){if(!r.clicking)continue;t.bubble.inRange=!r.durationEnd;const a=t.getPosition(),c=(0,b.getDistance)(a,n),u=((new Date).getTime()-(e.mouse.clickTime??0))/b.millisecondsToSeconds;u>l.duration&&(r.durationEnd=!0),u>l.duration*b.double&&(r.clicking=!1,r.durationEnd=!1);const d={bubbleObj:{optValue:i.retina.bubbleModeSize,value:t.bubble.radius},particlesObj:{optValue:(0,b.getRangeMax)(t.options.size.value)*i.retina.pixelRatio,value:t.size.value},type:o.size};this._process(t,c,u,d);const p={bubbleObj:{optValue:l.opacity,value:t.bubble.opacity},particlesObj:{optValue:(0,b.getRangeMax)(t.options.opacity.value),value:t.opacity?.value??1},type:o.opacity};this._process(t,c,u,p),!r.durationEnd&&c<=s?this._hoverBubbleColor(t,c):delete t.bubble.color}},this._hoverBubble=e=>{const i=this.container,t=e.mouse.position,o=i.retina.bubbleModeDistance;if(!o||o<0||!t)return;const l=i.particles.quadTree.queryCircle(t,o,(i=>this.isEnabled(e,i)));for(const i of l){i.bubble.inRange=!0;const l=i.getPosition(),s=(0,b.getDistance)(l,t),a=1-s/o;s<=o?a>=0&&e.status===n.mouseMoveEvent&&(this._hoverBubbleSize(i,a),this._hoverBubbleOpacity(i,a),this._hoverBubbleColor(i,a)):this.reset(e,i),e.status===n.mouseLeaveEvent&&this.reset(e,i)}},this._hoverBubbleColor=(e,i,t)=>{const o=this.container.actualOptions,n=t??o.interactivity?.modes.bubble;if(n){if(!e.bubble.finalColor){const i=n.color;if(!i)return;const t=(0,b.itemFromSingleOrMultiple)(i);e.bubble.finalColor=(0,b.rangeColorToHsl)(this._engine,t)}if(e.bubble.finalColor)if(n.mix){e.bubble.color=void 0;const t=e.getFillColor();e.bubble.color=t?(0,b.rgbToHsl)((0,b.colorMix)(t,e.bubble.finalColor,1-i,i)):e.bubble.finalColor}else e.bubble.color=e.bubble.finalColor}},this._hoverBubbleOpacity=(e,i,t)=>{const o=this.container.actualOptions,n=t?.opacity??o.interactivity?.modes.bubble?.opacity;if(!n)return;const l=e.options.opacity.value,a=s(e.opacity?.value??1,n,(0,b.getRangeMax)(l),i);void 0!==a&&(e.bubble.opacity=a)},this._hoverBubbleSize=(e,i,t)=>{const o=this.container,n=t?.size?t.size*o.retina.pixelRatio:o.retina.bubbleModeSize;if(void 0===n)return;const l=(0,b.getRangeMax)(e.options.size.value)*o.retina.pixelRatio,a=s(e.size.value,n,l,i);void 0!==a&&(e.bubble.radius=a)},this._process=(e,i,t,b)=>{const n=this.container,l=b.bubbleObj.optValue,s=n.actualOptions,a=s.interactivity?.modes.bubble;if(!a||void 0===l)return;const r=a.duration,c=n.retina.bubbleModeDistance,u=b.particlesObj.optValue,d=b.bubbleObj.value,p=b.particlesObj.value??0,h=b.type;if(c&&!(c<0)&&l!==u)if(n.bubble??={},n.bubble.durationEnd)d&&(h===o.size&&delete e.bubble.radius,h===o.opacity&&delete e.bubble.opacity);else if(i<=c){if((d??p)!==l){const i=p-t*(p-l)/r;h===o.size&&(e.bubble.radius=i),h===o.opacity&&(e.bubble.opacity=i)}}else h===o.size&&delete e.bubble.radius,h===o.opacity&&delete e.bubble.opacity},this._singleSelectorHover=(e,i,t,o)=>{const l=this.container,s=(0,b.safeDocument)().querySelectorAll(t),a=l.actualOptions.interactivity?.modes.bubble;a&&s.length&&s.forEach((t=>{const s=t,r=l.retina.pixelRatio,c={x:(s.offsetLeft+s.offsetWidth*b.half)*r,y:(s.offsetTop+s.offsetHeight*b.half)*r},u=s.offsetWidth*b.half*r,d=o.type===n.DivType.circle?new b.Circle(c.x,c.y,u):new b.Rectangle(s.offsetLeft*r,s.offsetTop*r,s.offsetWidth*r,s.offsetHeight*r),p=l.particles.quadTree.query(d,(i=>this.isEnabled(e,i)));for(const e of p){if(!d.contains(e.getPosition()))continue;e.bubble.inRange=!0;const t=a.divs,o=(0,n.divMode)(t,s);e.bubble.div&&e.bubble.div===s||(this.clear(e,i,!0),e.bubble.div=s),this._hoverBubbleSize(e,1,o),this._hoverBubbleOpacity(e,1,o),this._hoverBubbleColor(e,1,o)}}))},this._engine=e,i.bubble??={},this.handleClickMode=e=>{e===a&&(i.bubble??={},i.bubble.clicking=!0)}}clear(e,i,t){e.bubble.inRange&&!t||(delete e.bubble.div,delete e.bubble.opacity,delete e.bubble.radius,delete e.bubble.color)}init(){const e=this.container,i=e.actualOptions.interactivity?.modes.bubble;i&&(e.retina.bubbleModeDistance=i.distance*e.retina.pixelRatio,void 0!==i.size&&(e.retina.bubbleModeSize=i.size*e.retina.pixelRatio))}interact(e,i){const t=this.container.actualOptions,o=t.interactivity?.events;if(!o)return;const l=o.onHover,s=o.onClick,r=l.enable,c=l.mode,u=s.enable,d=s.mode,p=o.onDiv;r&&(0,b.isInArray)(a,c)?this._hoverBubble(e):u&&(0,b.isInArray)(a,d)?this._clickBubble(e):(0,n.divModeExecute)(a,p,((t,o)=>{this._singleSelectorHover(e,i,t,o)}))}isEnabled(e,i){const t=this.container.actualOptions,o=e.mouse,l=(i?.interactivity??t.interactivity)?.events;if(!l)return!1;const{onClick:s,onDiv:r,onHover:c}=l,u=(0,n.isDivModeEnabled)(a,r);return!!(u||c.enable&&o.position||s.enable&&o.clickPosition)&&((0,b.isInArray)(a,c.mode)||(0,b.isInArray)(a,s.mode)||u)}loadModeOptions(e,...i){e.bubble??=new l.Z;for(const t of i)e.bubble.load(t?.bubble)}reset(e,i){i.bubble.inRange=!1}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Bubble External Interaction v4.0.0-alpha.4 by Matteo Bruni */
|
package/browser/Bubbler.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, colorMix, double, getDistance, getRangeMax, half, isInArray, itemFromSingleOrMultiple, millisecondsToSeconds, rangeColorToHsl, rgbToHsl, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseLeaveEvent, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Bubble } from "./Options/Classes/Bubble.js";
|
|
3
4
|
import { ProcessBubbleType } from "./Enums.js";
|
|
4
5
|
import { calculateBubbleValue } from "./Utils.js";
|
|
5
|
-
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0,
|
|
6
|
+
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0, defaultOpacity = 1, ratioOffset = 1, defaultBubbleValue = 0, minRatio = 0, defaultRatio = 1;
|
|
6
7
|
export class Bubbler extends ExternalInteractorBase {
|
|
7
8
|
constructor(engine, container) {
|
|
8
9
|
super(container);
|
|
9
|
-
this._clickBubble =
|
|
10
|
-
const container = this.container, options = container.actualOptions, mouseClickPos =
|
|
10
|
+
this._clickBubble = interactivityData => {
|
|
11
|
+
const container = this.container, options = container.actualOptions, mouseClickPos = interactivityData.mouse.clickPosition, bubbleOptions = options.interactivity?.modes.bubble;
|
|
11
12
|
if (!bubbleOptions || !mouseClickPos) {
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
@@ -16,13 +17,13 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
16
17
|
if (!distance || distance < minDistance) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
|
-
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)), { bubble } = container;
|
|
20
|
+
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(interactivityData, p)), { bubble } = container;
|
|
20
21
|
for (const particle of query) {
|
|
21
22
|
if (!bubble.clicking) {
|
|
22
23
|
continue;
|
|
23
24
|
}
|
|
24
25
|
particle.bubble.inRange = !bubble.durationEnd;
|
|
25
|
-
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (
|
|
26
|
+
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (interactivityData.mouse.clickTime ?? defaultClickTime)) /
|
|
26
27
|
millisecondsToSeconds;
|
|
27
28
|
if (timeSpent > bubbleOptions.duration) {
|
|
28
29
|
bubble.durationEnd = true;
|
|
@@ -63,32 +64,32 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
this._hoverBubble =
|
|
67
|
-
const container = this.container, mousePos =
|
|
67
|
+
this._hoverBubble = interactivityData => {
|
|
68
|
+
const container = this.container, mousePos = interactivityData.mouse.position, distance = container.retina.bubbleModeDistance;
|
|
68
69
|
if (!distance || distance < minDistance || !mousePos) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
|
|
72
|
+
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
|
|
72
73
|
for (const particle of query) {
|
|
73
74
|
particle.bubble.inRange = true;
|
|
74
75
|
const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = ratioOffset - pointDistance / distance;
|
|
75
76
|
if (pointDistance <= distance) {
|
|
76
|
-
if (ratio >= minRatio &&
|
|
77
|
+
if (ratio >= minRatio && interactivityData.status === mouseMoveEvent) {
|
|
77
78
|
this._hoverBubbleSize(particle, ratio);
|
|
78
79
|
this._hoverBubbleOpacity(particle, ratio);
|
|
79
80
|
this._hoverBubbleColor(particle, ratio);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
|
-
this.reset(particle);
|
|
84
|
+
this.reset(interactivityData, particle);
|
|
84
85
|
}
|
|
85
|
-
if (
|
|
86
|
-
this.reset(particle);
|
|
86
|
+
if (interactivityData.status === mouseLeaveEvent) {
|
|
87
|
+
this.reset(interactivityData, particle);
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
this._hoverBubbleColor = (particle, ratio, divBubble) => {
|
|
91
|
-
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity
|
|
92
|
+
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;
|
|
92
93
|
if (!bubbleOptions) {
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
@@ -115,7 +116,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
115
116
|
}
|
|
116
117
|
};
|
|
117
118
|
this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
|
|
118
|
-
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity
|
|
119
|
+
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity?.modes.bubble?.opacity;
|
|
119
120
|
if (!modeOpacity) {
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
@@ -135,7 +136,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
135
136
|
}
|
|
136
137
|
};
|
|
137
138
|
this._process = (particle, distMouse, timeSpent, data) => {
|
|
138
|
-
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity
|
|
139
|
+
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity?.modes.bubble;
|
|
139
140
|
if (!bubbleOptions || bubbleParam === undefined) {
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
@@ -177,8 +178,8 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
};
|
|
180
|
-
this._singleSelectorHover = (delta, selector, div) => {
|
|
181
|
-
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity
|
|
181
|
+
this._singleSelectorHover = (interactivityData, delta, selector, div) => {
|
|
182
|
+
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
182
183
|
if (!bubble || !selectors.length) {
|
|
183
184
|
return;
|
|
184
185
|
}
|
|
@@ -188,7 +189,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
188
189
|
y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio,
|
|
189
190
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
190
191
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
191
|
-
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(p));
|
|
192
|
+
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p));
|
|
192
193
|
for (const particle of query) {
|
|
193
194
|
if (!area.contains(particle.getPosition())) {
|
|
194
195
|
continue;
|
|
@@ -225,7 +226,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
225
226
|
delete particle.bubble.color;
|
|
226
227
|
}
|
|
227
228
|
init() {
|
|
228
|
-
const container = this.container, bubble = container.actualOptions.interactivity
|
|
229
|
+
const container = this.container, bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
229
230
|
if (!bubble) {
|
|
230
231
|
return;
|
|
231
232
|
}
|
|
@@ -234,22 +235,30 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
234
235
|
container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
|
-
interact(delta) {
|
|
238
|
-
const options = this.container.actualOptions, events = options.interactivity
|
|
238
|
+
interact(interactivityData, delta) {
|
|
239
|
+
const options = this.container.actualOptions, events = options.interactivity?.events;
|
|
240
|
+
if (!events) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
|
|
239
244
|
if (hoverEnabled && isInArray(bubbleMode, hoverMode)) {
|
|
240
|
-
this._hoverBubble();
|
|
245
|
+
this._hoverBubble(interactivityData);
|
|
241
246
|
}
|
|
242
247
|
else if (clickEnabled && isInArray(bubbleMode, clickMode)) {
|
|
243
|
-
this._clickBubble();
|
|
248
|
+
this._clickBubble(interactivityData);
|
|
244
249
|
}
|
|
245
250
|
else {
|
|
246
251
|
divModeExecute(bubbleMode, divs, (selector, div) => {
|
|
247
|
-
this._singleSelectorHover(delta, selector, div);
|
|
252
|
+
this._singleSelectorHover(interactivityData, delta, selector, div);
|
|
248
253
|
});
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
|
-
isEnabled(particle) {
|
|
252
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
256
|
+
isEnabled(interactivityData, particle) {
|
|
257
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
258
|
+
if (!events) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
const { onClick, onDiv, onHover } = events, divBubble = isDivModeEnabled(bubbleMode, onDiv);
|
|
253
262
|
if (!(divBubble || (onHover.enable && !!mouse.position) || (onClick.enable && mouse.clickPosition))) {
|
|
254
263
|
return false;
|
|
255
264
|
}
|
|
@@ -261,7 +270,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
261
270
|
options.bubble.load(source?.bubble);
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
|
-
reset(particle) {
|
|
273
|
+
reset(_interactivityData, particle) {
|
|
265
274
|
particle.bubble.inRange = false;
|
|
266
275
|
}
|
|
267
276
|
}
|
package/browser/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalBubbleInteraction(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?.("externalBubble", async (container) => {
|
|
5
7
|
const { Bubbler } = await import("./Bubbler.js");
|
|
6
8
|
return new Bubbler(e, container);
|
|
7
9
|
});
|
package/cjs/Bubbler.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, colorMix, double, getDistance, getRangeMax, half, isInArray, itemFromSingleOrMultiple, millisecondsToSeconds, rangeColorToHsl, rgbToHsl, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseLeaveEvent, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Bubble } from "./Options/Classes/Bubble.js";
|
|
3
4
|
import { ProcessBubbleType } from "./Enums.js";
|
|
4
5
|
import { calculateBubbleValue } from "./Utils.js";
|
|
5
|
-
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0,
|
|
6
|
+
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0, defaultOpacity = 1, ratioOffset = 1, defaultBubbleValue = 0, minRatio = 0, defaultRatio = 1;
|
|
6
7
|
export class Bubbler extends ExternalInteractorBase {
|
|
7
8
|
constructor(engine, container) {
|
|
8
9
|
super(container);
|
|
9
|
-
this._clickBubble =
|
|
10
|
-
const container = this.container, options = container.actualOptions, mouseClickPos =
|
|
10
|
+
this._clickBubble = interactivityData => {
|
|
11
|
+
const container = this.container, options = container.actualOptions, mouseClickPos = interactivityData.mouse.clickPosition, bubbleOptions = options.interactivity?.modes.bubble;
|
|
11
12
|
if (!bubbleOptions || !mouseClickPos) {
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
@@ -16,13 +17,13 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
16
17
|
if (!distance || distance < minDistance) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
|
-
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)), { bubble } = container;
|
|
20
|
+
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(interactivityData, p)), { bubble } = container;
|
|
20
21
|
for (const particle of query) {
|
|
21
22
|
if (!bubble.clicking) {
|
|
22
23
|
continue;
|
|
23
24
|
}
|
|
24
25
|
particle.bubble.inRange = !bubble.durationEnd;
|
|
25
|
-
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (
|
|
26
|
+
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (interactivityData.mouse.clickTime ?? defaultClickTime)) /
|
|
26
27
|
millisecondsToSeconds;
|
|
27
28
|
if (timeSpent > bubbleOptions.duration) {
|
|
28
29
|
bubble.durationEnd = true;
|
|
@@ -63,32 +64,32 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
this._hoverBubble =
|
|
67
|
-
const container = this.container, mousePos =
|
|
67
|
+
this._hoverBubble = interactivityData => {
|
|
68
|
+
const container = this.container, mousePos = interactivityData.mouse.position, distance = container.retina.bubbleModeDistance;
|
|
68
69
|
if (!distance || distance < minDistance || !mousePos) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
|
|
72
|
+
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
|
|
72
73
|
for (const particle of query) {
|
|
73
74
|
particle.bubble.inRange = true;
|
|
74
75
|
const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = ratioOffset - pointDistance / distance;
|
|
75
76
|
if (pointDistance <= distance) {
|
|
76
|
-
if (ratio >= minRatio &&
|
|
77
|
+
if (ratio >= minRatio && interactivityData.status === mouseMoveEvent) {
|
|
77
78
|
this._hoverBubbleSize(particle, ratio);
|
|
78
79
|
this._hoverBubbleOpacity(particle, ratio);
|
|
79
80
|
this._hoverBubbleColor(particle, ratio);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
|
-
this.reset(particle);
|
|
84
|
+
this.reset(interactivityData, particle);
|
|
84
85
|
}
|
|
85
|
-
if (
|
|
86
|
-
this.reset(particle);
|
|
86
|
+
if (interactivityData.status === mouseLeaveEvent) {
|
|
87
|
+
this.reset(interactivityData, particle);
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
this._hoverBubbleColor = (particle, ratio, divBubble) => {
|
|
91
|
-
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity
|
|
92
|
+
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;
|
|
92
93
|
if (!bubbleOptions) {
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
@@ -115,7 +116,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
115
116
|
}
|
|
116
117
|
};
|
|
117
118
|
this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
|
|
118
|
-
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity
|
|
119
|
+
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity?.modes.bubble?.opacity;
|
|
119
120
|
if (!modeOpacity) {
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
@@ -135,7 +136,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
135
136
|
}
|
|
136
137
|
};
|
|
137
138
|
this._process = (particle, distMouse, timeSpent, data) => {
|
|
138
|
-
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity
|
|
139
|
+
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity?.modes.bubble;
|
|
139
140
|
if (!bubbleOptions || bubbleParam === undefined) {
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
@@ -177,8 +178,8 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
};
|
|
180
|
-
this._singleSelectorHover = (delta, selector, div) => {
|
|
181
|
-
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity
|
|
181
|
+
this._singleSelectorHover = (interactivityData, delta, selector, div) => {
|
|
182
|
+
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
182
183
|
if (!bubble || !selectors.length) {
|
|
183
184
|
return;
|
|
184
185
|
}
|
|
@@ -188,7 +189,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
188
189
|
y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio,
|
|
189
190
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
190
191
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
191
|
-
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(p));
|
|
192
|
+
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p));
|
|
192
193
|
for (const particle of query) {
|
|
193
194
|
if (!area.contains(particle.getPosition())) {
|
|
194
195
|
continue;
|
|
@@ -225,7 +226,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
225
226
|
delete particle.bubble.color;
|
|
226
227
|
}
|
|
227
228
|
init() {
|
|
228
|
-
const container = this.container, bubble = container.actualOptions.interactivity
|
|
229
|
+
const container = this.container, bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
229
230
|
if (!bubble) {
|
|
230
231
|
return;
|
|
231
232
|
}
|
|
@@ -234,22 +235,30 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
234
235
|
container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
|
-
interact(delta) {
|
|
238
|
-
const options = this.container.actualOptions, events = options.interactivity
|
|
238
|
+
interact(interactivityData, delta) {
|
|
239
|
+
const options = this.container.actualOptions, events = options.interactivity?.events;
|
|
240
|
+
if (!events) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
|
|
239
244
|
if (hoverEnabled && isInArray(bubbleMode, hoverMode)) {
|
|
240
|
-
this._hoverBubble();
|
|
245
|
+
this._hoverBubble(interactivityData);
|
|
241
246
|
}
|
|
242
247
|
else if (clickEnabled && isInArray(bubbleMode, clickMode)) {
|
|
243
|
-
this._clickBubble();
|
|
248
|
+
this._clickBubble(interactivityData);
|
|
244
249
|
}
|
|
245
250
|
else {
|
|
246
251
|
divModeExecute(bubbleMode, divs, (selector, div) => {
|
|
247
|
-
this._singleSelectorHover(delta, selector, div);
|
|
252
|
+
this._singleSelectorHover(interactivityData, delta, selector, div);
|
|
248
253
|
});
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
|
-
isEnabled(particle) {
|
|
252
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
256
|
+
isEnabled(interactivityData, particle) {
|
|
257
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
258
|
+
if (!events) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
const { onClick, onDiv, onHover } = events, divBubble = isDivModeEnabled(bubbleMode, onDiv);
|
|
253
262
|
if (!(divBubble || (onHover.enable && !!mouse.position) || (onClick.enable && mouse.clickPosition))) {
|
|
254
263
|
return false;
|
|
255
264
|
}
|
|
@@ -261,7 +270,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
261
270
|
options.bubble.load(source?.bubble);
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
|
-
reset(particle) {
|
|
273
|
+
reset(_interactivityData, particle) {
|
|
265
274
|
particle.bubble.inRange = false;
|
|
266
275
|
}
|
|
267
276
|
}
|
package/cjs/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalBubbleInteraction(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?.("externalBubble", async (container) => {
|
|
5
7
|
const { Bubbler } = await import("./Bubbler.js");
|
|
6
8
|
return new Bubbler(e, 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 */ Bubbler: () => (/* binding */ Bubbler)\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_Bubble_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Bubble.js */ \"./dist/browser/Options/Classes/Bubble.js\");\n/* harmony import */ var _Enums_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Enums.js */ \"./dist/browser/Enums.js\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\n\n\nconst bubbleMode = \"bubble\",\n minDistance = 0,\n defaultClickTime = 0,\n double = 2,\n defaultOpacity = 1,\n ratioOffset = 1,\n defaultBubbleValue = 0,\n minRatio = 0,\n half = 0.5,\n defaultRatio = 1;\nclass Bubbler extends _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.ExternalInteractorBase {\n constructor(engine, container) {\n super(container);\n this._clickBubble = () => {\n const container = this.container,\n options = container.actualOptions,\n mouseClickPos = container.interactivity.mouse.clickPosition,\n bubbleOptions = options.interactivity.modes.bubble;\n if (!bubbleOptions || !mouseClickPos) {\n return;\n }\n container.bubble ??= {};\n const distance = container.retina.bubbleModeDistance;\n if (!distance || distance < minDistance) {\n return;\n }\n const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)),\n {\n bubble\n } = container;\n for (const particle of query) {\n if (!bubble.clicking) {\n continue;\n }\n particle.bubble.inRange = !bubble.durationEnd;\n const pos = particle.getPosition(),\n distMouse = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos, mouseClickPos),\n timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime ?? defaultClickTime)) / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.millisecondsToSeconds;\n if (timeSpent > bubbleOptions.duration) {\n bubble.durationEnd = true;\n }\n if (timeSpent > bubbleOptions.duration * double) {\n bubble.clicking = false;\n bubble.durationEnd = false;\n }\n const sizeData = {\n bubbleObj: {\n optValue: container.retina.bubbleModeSize,\n value: particle.bubble.radius\n },\n particlesObj: {\n optValue: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio,\n value: particle.size.value\n },\n type: _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.size\n };\n this._process(particle, distMouse, timeSpent, sizeData);\n const opacityData = {\n bubbleObj: {\n optValue: bubbleOptions.opacity,\n value: particle.bubble.opacity\n },\n particlesObj: {\n optValue: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.opacity.value),\n value: particle.opacity?.value ?? defaultOpacity\n },\n type: _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.opacity\n };\n this._process(particle, distMouse, timeSpent, opacityData);\n if (!bubble.durationEnd && distMouse <= distance) {\n this._hoverBubbleColor(particle, distMouse);\n } else {\n delete particle.bubble.color;\n }\n }\n };\n this._hoverBubble = () => {\n const container = this.container,\n mousePos = container.interactivity.mouse.position,\n distance = container.retina.bubbleModeDistance;\n if (!distance || distance < minDistance || !mousePos) {\n return;\n }\n const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));\n for (const particle of query) {\n particle.bubble.inRange = true;\n const pos = particle.getPosition(),\n pointDistance = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos, mousePos),\n ratio = ratioOffset - pointDistance / distance;\n if (pointDistance <= distance) {\n if (ratio >= minRatio && container.interactivity.status === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.mouseMoveEvent) {\n this._hoverBubbleSize(particle, ratio);\n this._hoverBubbleOpacity(particle, ratio);\n this._hoverBubbleColor(particle, ratio);\n }\n } else {\n this.reset(particle);\n }\n if (container.interactivity.status === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.mouseLeaveEvent) {\n this.reset(particle);\n }\n }\n };\n this._hoverBubbleColor = (particle, ratio, divBubble) => {\n const options = this.container.actualOptions,\n bubbleOptions = divBubble ?? options.interactivity.modes.bubble;\n if (!bubbleOptions) {\n return;\n }\n if (!particle.bubble.finalColor) {\n const modeColor = bubbleOptions.color;\n if (!modeColor) {\n return;\n }\n const bubbleColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.itemFromSingleOrMultiple)(modeColor);\n particle.bubble.finalColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToHsl)(this._engine, bubbleColor);\n }\n if (!particle.bubble.finalColor) {\n return;\n }\n if (bubbleOptions.mix) {\n particle.bubble.color = undefined;\n const pColor = particle.getFillColor();\n particle.bubble.color = pColor ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rgbToHsl)((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.colorMix)(pColor, particle.bubble.finalColor, ratioOffset - ratio, ratio)) : particle.bubble.finalColor;\n } else {\n particle.bubble.color = particle.bubble.finalColor;\n }\n };\n this._hoverBubbleOpacity = (particle, ratio, divBubble) => {\n const container = this.container,\n options = container.actualOptions,\n modeOpacity = divBubble?.opacity ?? options.interactivity.modes.bubble?.opacity;\n if (!modeOpacity) {\n return;\n }\n const optOpacity = particle.options.opacity.value,\n pOpacity = particle.opacity?.value ?? defaultOpacity,\n opacity = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_3__.calculateBubbleValue)(pOpacity, modeOpacity, (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(optOpacity), ratio);\n if (opacity !== undefined) {\n particle.bubble.opacity = opacity;\n }\n };\n this._hoverBubbleSize = (particle, ratio, divBubble) => {\n const container = this.container,\n modeSize = divBubble?.size ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;\n if (modeSize === undefined) {\n return;\n }\n const optSize = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio,\n pSize = particle.size.value,\n size = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_3__.calculateBubbleValue)(pSize, modeSize, optSize, ratio);\n if (size !== undefined) {\n particle.bubble.radius = size;\n }\n };\n this._process = (particle, distMouse, timeSpent, data) => {\n const container = this.container,\n bubbleParam = data.bubbleObj.optValue,\n options = container.actualOptions,\n bubbleOptions = options.interactivity.modes.bubble;\n if (!bubbleOptions || bubbleParam === undefined) {\n return;\n }\n const bubbleDuration = bubbleOptions.duration,\n bubbleDistance = container.retina.bubbleModeDistance,\n particlesParam = data.particlesObj.optValue,\n pObjBubble = data.bubbleObj.value,\n pObj = data.particlesObj.value ?? defaultBubbleValue,\n type = data.type;\n if (!bubbleDistance || bubbleDistance < minDistance || bubbleParam === particlesParam) {\n return;\n }\n container.bubble ??= {};\n if (container.bubble.durationEnd) {\n if (pObjBubble) {\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.size) {\n delete particle.bubble.radius;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.opacity) {\n delete particle.bubble.opacity;\n }\n }\n } else {\n if (distMouse <= bubbleDistance) {\n const obj = pObjBubble ?? pObj;\n if (obj !== bubbleParam) {\n const value = pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration;\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.size) {\n particle.bubble.radius = value;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.opacity) {\n particle.bubble.opacity = value;\n }\n }\n } else {\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.size) {\n delete particle.bubble.radius;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_2__.ProcessBubbleType.opacity) {\n delete particle.bubble.opacity;\n }\n }\n }\n };\n this._singleSelectorHover = (delta, selector, div) => {\n const container = this.container,\n selectors = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().querySelectorAll(selector),\n bubble = container.actualOptions.interactivity.modes.bubble;\n if (!bubble || !selectors.length) {\n return;\n }\n selectors.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 query = container.particles.quadTree.query(area, p => this.isEnabled(p));\n for (const particle of query) {\n if (!area.contains(particle.getPosition())) {\n continue;\n }\n particle.bubble.inRange = true;\n const divs = bubble.divs,\n divBubble = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.divMode)(divs, elem);\n if (!particle.bubble.div || particle.bubble.div !== elem) {\n this.clear(particle, delta, true);\n particle.bubble.div = elem;\n }\n this._hoverBubbleSize(particle, defaultRatio, divBubble);\n this._hoverBubbleOpacity(particle, defaultRatio, divBubble);\n this._hoverBubbleColor(particle, defaultRatio, divBubble);\n }\n });\n };\n this._engine = engine;\n container.bubble ??= {};\n this.handleClickMode = mode => {\n if (mode !== bubbleMode) {\n return;\n }\n container.bubble ??= {};\n container.bubble.clicking = true;\n };\n }\n clear(particle, _delta, force) {\n if (particle.bubble.inRange && !force) {\n return;\n }\n delete particle.bubble.div;\n delete particle.bubble.opacity;\n delete particle.bubble.radius;\n delete particle.bubble.color;\n }\n init() {\n const container = this.container,\n bubble = container.actualOptions.interactivity.modes.bubble;\n if (!bubble) {\n return;\n }\n container.retina.bubbleModeDistance = bubble.distance * container.retina.pixelRatio;\n if (bubble.size !== undefined) {\n container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;\n }\n }\n interact(delta) {\n const options = this.container.actualOptions,\n events = options.interactivity.events,\n onHover = events.onHover,\n onClick = events.onClick,\n hoverEnabled = onHover.enable,\n hoverMode = onHover.mode,\n clickEnabled = onClick.enable,\n clickMode = onClick.mode,\n divs = events.onDiv;\n if (hoverEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, hoverMode)) {\n this._hoverBubble();\n } else if (clickEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, clickMode)) {\n this._clickBubble();\n } else {\n (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.divModeExecute)(bubbleMode, divs, (selector, div) => {\n this._singleSelectorHover(delta, 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 {\n onClick,\n onDiv,\n onHover\n } = events,\n divBubble = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isDivModeEnabled)(bubbleMode, onDiv);\n if (!(divBubble || onHover.enable && !!mouse.position || onClick.enable && mouse.clickPosition)) {\n return false;\n }\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, onHover.mode) || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, onClick.mode) || divBubble;\n }\n loadModeOptions(options, ...sources) {\n options.bubble ??= new _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_1__.Bubble();\n for (const source of sources) {\n options.bubble.load(source?.bubble);\n }\n }\n reset(particle) {\n particle.bubble.inRange = false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/interaction-external-bubble/./dist/browser/Bubbler.js?\n}");
|
|
26
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Bubbler: () => (/* binding */ Bubbler)\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_Bubble_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Bubble.js */ \"./dist/browser/Options/Classes/Bubble.js\");\n/* harmony import */ var _Enums_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Enums.js */ \"./dist/browser/Enums.js\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\n\n\n\nconst bubbleMode = \"bubble\",\n minDistance = 0,\n defaultClickTime = 0,\n defaultOpacity = 1,\n ratioOffset = 1,\n defaultBubbleValue = 0,\n minRatio = 0,\n defaultRatio = 1;\nclass Bubbler extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.ExternalInteractorBase {\n constructor(engine, container) {\n super(container);\n this._clickBubble = interactivityData => {\n const container = this.container,\n options = container.actualOptions,\n mouseClickPos = interactivityData.mouse.clickPosition,\n bubbleOptions = options.interactivity?.modes.bubble;\n if (!bubbleOptions || !mouseClickPos) {\n return;\n }\n container.bubble ??= {};\n const distance = container.retina.bubbleModeDistance;\n if (!distance || distance < minDistance) {\n return;\n }\n const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(interactivityData, p)),\n {\n bubble\n } = container;\n for (const particle of query) {\n if (!bubble.clicking) {\n continue;\n }\n particle.bubble.inRange = !bubble.durationEnd;\n const pos = particle.getPosition(),\n distMouse = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos, mouseClickPos),\n timeSpent = (new Date().getTime() - (interactivityData.mouse.clickTime ?? defaultClickTime)) / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.millisecondsToSeconds;\n if (timeSpent > bubbleOptions.duration) {\n bubble.durationEnd = true;\n }\n if (timeSpent > bubbleOptions.duration * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double) {\n bubble.clicking = false;\n bubble.durationEnd = false;\n }\n const sizeData = {\n bubbleObj: {\n optValue: container.retina.bubbleModeSize,\n value: particle.bubble.radius\n },\n particlesObj: {\n optValue: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio,\n value: particle.size.value\n },\n type: _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.size\n };\n this._process(particle, distMouse, timeSpent, sizeData);\n const opacityData = {\n bubbleObj: {\n optValue: bubbleOptions.opacity,\n value: particle.bubble.opacity\n },\n particlesObj: {\n optValue: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.opacity.value),\n value: particle.opacity?.value ?? defaultOpacity\n },\n type: _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.opacity\n };\n this._process(particle, distMouse, timeSpent, opacityData);\n if (!bubble.durationEnd && distMouse <= distance) {\n this._hoverBubbleColor(particle, distMouse);\n } else {\n delete particle.bubble.color;\n }\n }\n };\n this._hoverBubble = interactivityData => {\n const container = this.container,\n mousePos = interactivityData.mouse.position,\n distance = container.retina.bubbleModeDistance;\n if (!distance || distance < minDistance || !mousePos) {\n return;\n }\n const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));\n for (const particle of query) {\n particle.bubble.inRange = true;\n const pos = particle.getPosition(),\n pointDistance = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos, mousePos),\n ratio = ratioOffset - pointDistance / distance;\n if (pointDistance <= distance) {\n if (ratio >= minRatio && interactivityData.status === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.mouseMoveEvent) {\n this._hoverBubbleSize(particle, ratio);\n this._hoverBubbleOpacity(particle, ratio);\n this._hoverBubbleColor(particle, ratio);\n }\n } else {\n this.reset(interactivityData, particle);\n }\n if (interactivityData.status === _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.mouseLeaveEvent) {\n this.reset(interactivityData, particle);\n }\n }\n };\n this._hoverBubbleColor = (particle, ratio, divBubble) => {\n const options = this.container.actualOptions,\n bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;\n if (!bubbleOptions) {\n return;\n }\n if (!particle.bubble.finalColor) {\n const modeColor = bubbleOptions.color;\n if (!modeColor) {\n return;\n }\n const bubbleColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.itemFromSingleOrMultiple)(modeColor);\n particle.bubble.finalColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToHsl)(this._engine, bubbleColor);\n }\n if (!particle.bubble.finalColor) {\n return;\n }\n if (bubbleOptions.mix) {\n particle.bubble.color = undefined;\n const pColor = particle.getFillColor();\n particle.bubble.color = pColor ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rgbToHsl)((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.colorMix)(pColor, particle.bubble.finalColor, ratioOffset - ratio, ratio)) : particle.bubble.finalColor;\n } else {\n particle.bubble.color = particle.bubble.finalColor;\n }\n };\n this._hoverBubbleOpacity = (particle, ratio, divBubble) => {\n const container = this.container,\n options = container.actualOptions,\n modeOpacity = divBubble?.opacity ?? options.interactivity?.modes.bubble?.opacity;\n if (!modeOpacity) {\n return;\n }\n const optOpacity = particle.options.opacity.value,\n pOpacity = particle.opacity?.value ?? defaultOpacity,\n opacity = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_4__.calculateBubbleValue)(pOpacity, modeOpacity, (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(optOpacity), ratio);\n if (opacity !== undefined) {\n particle.bubble.opacity = opacity;\n }\n };\n this._hoverBubbleSize = (particle, ratio, divBubble) => {\n const container = this.container,\n modeSize = divBubble?.size ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;\n if (modeSize === undefined) {\n return;\n }\n const optSize = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio,\n pSize = particle.size.value,\n size = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_4__.calculateBubbleValue)(pSize, modeSize, optSize, ratio);\n if (size !== undefined) {\n particle.bubble.radius = size;\n }\n };\n this._process = (particle, distMouse, timeSpent, data) => {\n const container = this.container,\n bubbleParam = data.bubbleObj.optValue,\n options = container.actualOptions,\n bubbleOptions = options.interactivity?.modes.bubble;\n if (!bubbleOptions || bubbleParam === undefined) {\n return;\n }\n const bubbleDuration = bubbleOptions.duration,\n bubbleDistance = container.retina.bubbleModeDistance,\n particlesParam = data.particlesObj.optValue,\n pObjBubble = data.bubbleObj.value,\n pObj = data.particlesObj.value ?? defaultBubbleValue,\n type = data.type;\n if (!bubbleDistance || bubbleDistance < minDistance || bubbleParam === particlesParam) {\n return;\n }\n container.bubble ??= {};\n if (container.bubble.durationEnd) {\n if (pObjBubble) {\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.size) {\n delete particle.bubble.radius;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.opacity) {\n delete particle.bubble.opacity;\n }\n }\n } else {\n if (distMouse <= bubbleDistance) {\n const obj = pObjBubble ?? pObj;\n if (obj !== bubbleParam) {\n const value = pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration;\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.size) {\n particle.bubble.radius = value;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.opacity) {\n particle.bubble.opacity = value;\n }\n }\n } else {\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.size) {\n delete particle.bubble.radius;\n }\n if (type === _Enums_js__WEBPACK_IMPORTED_MODULE_3__.ProcessBubbleType.opacity) {\n delete particle.bubble.opacity;\n }\n }\n }\n };\n this._singleSelectorHover = (interactivityData, delta, selector, div) => {\n const container = this.container,\n selectors = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().querySelectorAll(selector),\n bubble = container.actualOptions.interactivity?.modes.bubble;\n if (!bubble || !selectors.length) {\n return;\n }\n selectors.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 query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p));\n for (const particle of query) {\n if (!area.contains(particle.getPosition())) {\n continue;\n }\n particle.bubble.inRange = true;\n const divs = bubble.divs,\n divBubble = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divMode)(divs, elem);\n if (!particle.bubble.div || particle.bubble.div !== elem) {\n this.clear(particle, delta, true);\n particle.bubble.div = elem;\n }\n this._hoverBubbleSize(particle, defaultRatio, divBubble);\n this._hoverBubbleOpacity(particle, defaultRatio, divBubble);\n this._hoverBubbleColor(particle, defaultRatio, divBubble);\n }\n });\n };\n this._engine = engine;\n container.bubble ??= {};\n this.handleClickMode = mode => {\n if (mode !== bubbleMode) {\n return;\n }\n container.bubble ??= {};\n container.bubble.clicking = true;\n };\n }\n clear(particle, _delta, force) {\n if (particle.bubble.inRange && !force) {\n return;\n }\n delete particle.bubble.div;\n delete particle.bubble.opacity;\n delete particle.bubble.radius;\n delete particle.bubble.color;\n }\n init() {\n const container = this.container,\n bubble = container.actualOptions.interactivity?.modes.bubble;\n if (!bubble) {\n return;\n }\n container.retina.bubbleModeDistance = bubble.distance * container.retina.pixelRatio;\n if (bubble.size !== undefined) {\n container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;\n }\n }\n interact(interactivityData, delta) {\n const options = this.container.actualOptions,\n events = options.interactivity?.events;\n if (!events) {\n return;\n }\n const onHover = events.onHover,\n onClick = events.onClick,\n hoverEnabled = onHover.enable,\n hoverMode = onHover.mode,\n clickEnabled = onClick.enable,\n clickMode = onClick.mode,\n divs = events.onDiv;\n if (hoverEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, hoverMode)) {\n this._hoverBubble(interactivityData);\n } else if (clickEnabled && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, clickMode)) {\n this._clickBubble(interactivityData);\n } else {\n (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.divModeExecute)(bubbleMode, divs, (selector, div) => {\n this._singleSelectorHover(interactivityData, delta, 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 {\n onClick,\n onDiv,\n onHover\n } = events,\n divBubble = (0,_tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_1__.isDivModeEnabled)(bubbleMode, onDiv);\n if (!(divBubble || onHover.enable && !!mouse.position || onClick.enable && mouse.clickPosition)) {\n return false;\n }\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, onHover.mode) || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(bubbleMode, onClick.mode) || divBubble;\n }\n loadModeOptions(options, ...sources) {\n options.bubble ??= new _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_2__.Bubble();\n for (const source of sources) {\n options.bubble.load(source?.bubble);\n }\n }\n reset(_interactivityData, particle) {\n particle.bubble.inRange = false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/interaction-external-bubble/./dist/browser/Bubbler.js?\n}");
|
|
27
27
|
|
|
28
28
|
/***/ },
|
|
29
29
|
|
package/esm/Bubbler.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Circle,
|
|
1
|
+
import { Circle, Rectangle, colorMix, double, getDistance, getRangeMax, half, isInArray, itemFromSingleOrMultiple, millisecondsToSeconds, rangeColorToHsl, rgbToHsl, safeDocument, } from "@tsparticles/engine";
|
|
2
|
+
import { DivType, ExternalInteractorBase, divMode, divModeExecute, isDivModeEnabled, mouseLeaveEvent, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
|
|
2
3
|
import { Bubble } from "./Options/Classes/Bubble.js";
|
|
3
4
|
import { ProcessBubbleType } from "./Enums.js";
|
|
4
5
|
import { calculateBubbleValue } from "./Utils.js";
|
|
5
|
-
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0,
|
|
6
|
+
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0, defaultOpacity = 1, ratioOffset = 1, defaultBubbleValue = 0, minRatio = 0, defaultRatio = 1;
|
|
6
7
|
export class Bubbler extends ExternalInteractorBase {
|
|
7
8
|
constructor(engine, container) {
|
|
8
9
|
super(container);
|
|
9
|
-
this._clickBubble =
|
|
10
|
-
const container = this.container, options = container.actualOptions, mouseClickPos =
|
|
10
|
+
this._clickBubble = interactivityData => {
|
|
11
|
+
const container = this.container, options = container.actualOptions, mouseClickPos = interactivityData.mouse.clickPosition, bubbleOptions = options.interactivity?.modes.bubble;
|
|
11
12
|
if (!bubbleOptions || !mouseClickPos) {
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
@@ -16,13 +17,13 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
16
17
|
if (!distance || distance < minDistance) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
|
-
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)), { bubble } = container;
|
|
20
|
+
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(interactivityData, p)), { bubble } = container;
|
|
20
21
|
for (const particle of query) {
|
|
21
22
|
if (!bubble.clicking) {
|
|
22
23
|
continue;
|
|
23
24
|
}
|
|
24
25
|
particle.bubble.inRange = !bubble.durationEnd;
|
|
25
|
-
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (
|
|
26
|
+
const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (interactivityData.mouse.clickTime ?? defaultClickTime)) /
|
|
26
27
|
millisecondsToSeconds;
|
|
27
28
|
if (timeSpent > bubbleOptions.duration) {
|
|
28
29
|
bubble.durationEnd = true;
|
|
@@ -63,32 +64,32 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
this._hoverBubble =
|
|
67
|
-
const container = this.container, mousePos =
|
|
67
|
+
this._hoverBubble = interactivityData => {
|
|
68
|
+
const container = this.container, mousePos = interactivityData.mouse.position, distance = container.retina.bubbleModeDistance;
|
|
68
69
|
if (!distance || distance < minDistance || !mousePos) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
|
|
72
|
+
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
|
|
72
73
|
for (const particle of query) {
|
|
73
74
|
particle.bubble.inRange = true;
|
|
74
75
|
const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = ratioOffset - pointDistance / distance;
|
|
75
76
|
if (pointDistance <= distance) {
|
|
76
|
-
if (ratio >= minRatio &&
|
|
77
|
+
if (ratio >= minRatio && interactivityData.status === mouseMoveEvent) {
|
|
77
78
|
this._hoverBubbleSize(particle, ratio);
|
|
78
79
|
this._hoverBubbleOpacity(particle, ratio);
|
|
79
80
|
this._hoverBubbleColor(particle, ratio);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
|
-
this.reset(particle);
|
|
84
|
+
this.reset(interactivityData, particle);
|
|
84
85
|
}
|
|
85
|
-
if (
|
|
86
|
-
this.reset(particle);
|
|
86
|
+
if (interactivityData.status === mouseLeaveEvent) {
|
|
87
|
+
this.reset(interactivityData, particle);
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
this._hoverBubbleColor = (particle, ratio, divBubble) => {
|
|
91
|
-
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity
|
|
92
|
+
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;
|
|
92
93
|
if (!bubbleOptions) {
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
@@ -115,7 +116,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
115
116
|
}
|
|
116
117
|
};
|
|
117
118
|
this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
|
|
118
|
-
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity
|
|
119
|
+
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity?.modes.bubble?.opacity;
|
|
119
120
|
if (!modeOpacity) {
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
@@ -135,7 +136,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
135
136
|
}
|
|
136
137
|
};
|
|
137
138
|
this._process = (particle, distMouse, timeSpent, data) => {
|
|
138
|
-
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity
|
|
139
|
+
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity?.modes.bubble;
|
|
139
140
|
if (!bubbleOptions || bubbleParam === undefined) {
|
|
140
141
|
return;
|
|
141
142
|
}
|
|
@@ -177,8 +178,8 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
};
|
|
180
|
-
this._singleSelectorHover = (delta, selector, div) => {
|
|
181
|
-
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity
|
|
181
|
+
this._singleSelectorHover = (interactivityData, delta, selector, div) => {
|
|
182
|
+
const container = this.container, selectors = safeDocument().querySelectorAll(selector), bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
182
183
|
if (!bubble || !selectors.length) {
|
|
183
184
|
return;
|
|
184
185
|
}
|
|
@@ -188,7 +189,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
188
189
|
y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio,
|
|
189
190
|
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type === DivType.circle
|
|
190
191
|
? new Circle(pos.x, pos.y, repulseRadius)
|
|
191
|
-
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(p));
|
|
192
|
+
: new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p));
|
|
192
193
|
for (const particle of query) {
|
|
193
194
|
if (!area.contains(particle.getPosition())) {
|
|
194
195
|
continue;
|
|
@@ -225,7 +226,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
225
226
|
delete particle.bubble.color;
|
|
226
227
|
}
|
|
227
228
|
init() {
|
|
228
|
-
const container = this.container, bubble = container.actualOptions.interactivity
|
|
229
|
+
const container = this.container, bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
229
230
|
if (!bubble) {
|
|
230
231
|
return;
|
|
231
232
|
}
|
|
@@ -234,22 +235,30 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
234
235
|
container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
|
-
interact(delta) {
|
|
238
|
-
const options = this.container.actualOptions, events = options.interactivity
|
|
238
|
+
interact(interactivityData, delta) {
|
|
239
|
+
const options = this.container.actualOptions, events = options.interactivity?.events;
|
|
240
|
+
if (!events) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
|
|
239
244
|
if (hoverEnabled && isInArray(bubbleMode, hoverMode)) {
|
|
240
|
-
this._hoverBubble();
|
|
245
|
+
this._hoverBubble(interactivityData);
|
|
241
246
|
}
|
|
242
247
|
else if (clickEnabled && isInArray(bubbleMode, clickMode)) {
|
|
243
|
-
this._clickBubble();
|
|
248
|
+
this._clickBubble(interactivityData);
|
|
244
249
|
}
|
|
245
250
|
else {
|
|
246
251
|
divModeExecute(bubbleMode, divs, (selector, div) => {
|
|
247
|
-
this._singleSelectorHover(delta, selector, div);
|
|
252
|
+
this._singleSelectorHover(interactivityData, delta, selector, div);
|
|
248
253
|
});
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
|
-
isEnabled(particle) {
|
|
252
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
256
|
+
isEnabled(interactivityData, particle) {
|
|
257
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
258
|
+
if (!events) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
const { onClick, onDiv, onHover } = events, divBubble = isDivModeEnabled(bubbleMode, onDiv);
|
|
253
262
|
if (!(divBubble || (onHover.enable && !!mouse.position) || (onClick.enable && mouse.clickPosition))) {
|
|
254
263
|
return false;
|
|
255
264
|
}
|
|
@@ -261,7 +270,7 @@ export class Bubbler extends ExternalInteractorBase {
|
|
|
261
270
|
options.bubble.load(source?.bubble);
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
|
-
reset(particle) {
|
|
273
|
+
reset(_interactivityData, particle) {
|
|
265
274
|
particle.bubble.inRange = false;
|
|
266
275
|
}
|
|
267
276
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function loadExternalBubbleInteraction(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?.("externalBubble", async (container) => {
|
|
5
7
|
const { Bubbler } = await import("./Bubbler.js");
|
|
6
8
|
return new Bubbler(e, container);
|
|
7
9
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/interaction-external-bubble",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.4",
|
|
4
4
|
"description": "tsParticles bubble 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-bubble [
|
|
6
|
+
<title>@tsparticles/interaction-external-bubble [21 Jan 2026 at 14:42]</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 */ Bubble: () => (/* reexport safe */ _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_2__.Bubble),\n/* harmony export */ BubbleBase: () => (/* reexport safe */ _Options_Classes_BubbleBase_js__WEBPACK_IMPORTED_MODULE_0__.BubbleBase),\n/* harmony export */ BubbleDiv: () => (/* reexport safe */ _Options_Classes_BubbleDiv_js__WEBPACK_IMPORTED_MODULE_1__.BubbleDiv),\n/* harmony export */ loadExternalBubbleInteraction: () => (/* binding */ loadExternalBubbleInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_BubbleBase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/BubbleBase.js */ \"./dist/browser/Options/Classes/BubbleBase.js\");\n/* harmony import */ var _Options_Classes_BubbleDiv_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/BubbleDiv.js */ \"./dist/browser/Options/Classes/BubbleDiv.js\");\n/* harmony import */ var _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Bubble.js */ \"./dist/browser/Options/Classes/Bubble.js\");\nfunction loadExternalBubbleInteraction(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 */ Bubble: () => (/* reexport safe */ _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_2__.Bubble),\n/* harmony export */ BubbleBase: () => (/* reexport safe */ _Options_Classes_BubbleBase_js__WEBPACK_IMPORTED_MODULE_0__.BubbleBase),\n/* harmony export */ BubbleDiv: () => (/* reexport safe */ _Options_Classes_BubbleDiv_js__WEBPACK_IMPORTED_MODULE_1__.BubbleDiv),\n/* harmony export */ loadExternalBubbleInteraction: () => (/* binding */ loadExternalBubbleInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_BubbleBase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/BubbleBase.js */ \"./dist/browser/Options/Classes/BubbleBase.js\");\n/* harmony import */ var _Options_Classes_BubbleDiv_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/BubbleDiv.js */ \"./dist/browser/Options/Classes/BubbleDiv.js\");\n/* harmony import */ var _Options_Classes_Bubble_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Bubble.js */ \"./dist/browser/Options/Classes/Bubble.js\");\nfunction loadExternalBubbleInteraction(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?.(\"externalBubble\", async container => {\n const {\n Bubbler\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_Bubbler_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./Bubbler.js */ \"./dist/browser/Bubbler.js\"));\n return new Bubbler(e, container);\n });\n });\n}\n\n\n\n\n//# sourceURL=webpack://@tsparticles/interaction-external-bubble/./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.bubble.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
|
|
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={52(e,t,r){r.d(t,{C:()=>n});var i=r(303),o=r(618);class n extends o.u{constructor(){super(),this.selectors=[]}load(e){super.load(e),(0,i.isNull)(e)||void 0!==e.selectors&&(this.selectors=e.selectors)}}},303(t){t.exports=e},443(e,t,r){r.d(t,{Z:()=>a});var i=r(303),o=r(618),n=r(52);class a extends o.u{load(e){super.load(e),(0,i.isNull)(e)||(this.divs=(0,i.executeOnSingleOrMultiple)(e.divs,(e=>{const t=new n.C;return t.load(e),t})))}}},618(e,t,r){r.d(t,{u:()=>o});var i=r(303);class o{constructor(){this.distance=200,this.duration=.4,this.mix=!1}load(e){if(!(0,i.isNull)(e)){if(void 0!==e.distance&&(this.distance=e.distance),void 0!==e.duration&&(this.duration=e.duration),void 0!==e.mix&&(this.mix=e.mix),void 0!==e.opacity&&(this.opacity=e.opacity),void 0!==e.color){const t=(0,i.isArray)(this.color)?void 0:this.color;this.color=(0,i.executeOnSingleOrMultiple)(e.color,(e=>i.OptionsColor.create(t,e)))}void 0!==e.size&&(this.size=e.size)}}}},702(e){e.exports=t}},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-bubble:",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"),u=0;u<c.length;u++){var p=c[u];if(p.getAttribute("src")==e||p.getAttribute("data-webpack")==n+r){a=p;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={108: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_bubble=this.webpackChunk_tsparticles_interaction_external_bubble||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var c={};l.r(c),l.d(c,{Bubble:()=>d.Z,BubbleBase:()=>u.u,BubbleDiv:()=>p.C,loadExternalBubbleInteraction:()=>f});var u=l(618),p=l(52),d=l(443);function f(e){e.checkVersion("4.0.0-alpha.4"),e.register((async e=>{const{loadInteractivityPlugin:t}=await Promise.resolve().then(l.t.bind(l,702,19));t(e),e.addInteractor?.("externalBubble",(async t=>{const{Bubbler:r}=await l.e(132).then(l.bind(l,132));return new r(e,t)}))}))}return c})()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tsParticles Bubble External Interaction v4.0.0-alpha.
|
|
1
|
+
/*! tsParticles Bubble External Interaction v4.0.0-alpha.4 by Matteo Bruni */
|
package/types/Bubbler.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { BubbleContainer, BubbleMode, IBubbleMode } from "./Types.js";
|
|
2
|
-
import { type Engine,
|
|
2
|
+
import { type Engine, type IDelta, type Particle, type RecursivePartial } from "@tsparticles/engine";
|
|
3
|
+
import { ExternalInteractorBase, type IInteractivityData, type IModes, type InteractivityParticle, type Modes } from "@tsparticles/plugin-interactivity";
|
|
3
4
|
export declare class Bubbler extends ExternalInteractorBase<BubbleContainer> {
|
|
4
|
-
handleClickMode: (mode: string) => void;
|
|
5
|
+
handleClickMode: (mode: string, interactivityData: IInteractivityData) => void;
|
|
5
6
|
private readonly _engine;
|
|
6
7
|
constructor(engine: Engine, container: BubbleContainer);
|
|
7
8
|
clear(particle: Particle, _delta: IDelta, force?: boolean): void;
|
|
8
9
|
init(): void;
|
|
9
|
-
interact(delta: IDelta): void;
|
|
10
|
-
isEnabled(particle?:
|
|
10
|
+
interact(interactivityData: IInteractivityData, delta: IDelta): void;
|
|
11
|
+
isEnabled(interactivityData: IInteractivityData, particle?: InteractivityParticle): boolean;
|
|
11
12
|
loadModeOptions(options: Modes & BubbleMode, ...sources: RecursivePartial<(IModes & IBubbleMode) | undefined>[]): void;
|
|
12
|
-
reset(particle: Particle): void;
|
|
13
|
+
reset(_interactivityData: IInteractivityData, particle: Particle): void;
|
|
13
14
|
private readonly _clickBubble;
|
|
14
15
|
private readonly _hoverBubble;
|
|
15
16
|
private readonly _hoverBubbleColor;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BubbleMode } from "../../Types.js";
|
|
2
|
-
import type {
|
|
3
|
-
export type BubbleOptions =
|
|
4
|
-
interactivity
|
|
2
|
+
import type { InteractivityOptions } from "@tsparticles/plugin-interactivity";
|
|
3
|
+
export type BubbleOptions = InteractivityOptions & {
|
|
4
|
+
interactivity?: {
|
|
5
5
|
modes: BubbleMode;
|
|
6
6
|
};
|
|
7
7
|
};
|
package/types/Types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Bubble } from "./Options/Classes/Bubble.js";
|
|
2
2
|
import type { BubbleOptions } from "./Options/Classes/BubbleOptions.js";
|
|
3
|
-
import type { Container } from "@tsparticles/engine";
|
|
4
3
|
import type { IBubble } from "./Options/Interfaces/IBubble.js";
|
|
4
|
+
import type { InteractivityContainer } from "@tsparticles/plugin-interactivity";
|
|
5
5
|
export interface IBubbleMode {
|
|
6
6
|
bubble: IBubble;
|
|
7
7
|
}
|
|
@@ -12,7 +12,7 @@ interface IContainerBubble {
|
|
|
12
12
|
clicking?: boolean;
|
|
13
13
|
durationEnd?: boolean;
|
|
14
14
|
}
|
|
15
|
-
export type BubbleContainer =
|
|
15
|
+
export type BubbleContainer = InteractivityContainer & {
|
|
16
16
|
actualOptions: BubbleOptions;
|
|
17
17
|
bubble?: IContainerBubble;
|
|
18
18
|
retina: {
|
package/umd/Bubbler.js
CHANGED
|
@@ -4,22 +4,23 @@
|
|
|
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/Bubble.js", "./Enums.js", "./Utils.js"], factory);
|
|
7
|
+
define(["require", "exports", "@tsparticles/engine", "@tsparticles/plugin-interactivity", "./Options/Classes/Bubble.js", "./Enums.js", "./Utils.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.Bubbler = void 0;
|
|
13
13
|
const engine_1 = require("@tsparticles/engine");
|
|
14
|
+
const plugin_interactivity_1 = require("@tsparticles/plugin-interactivity");
|
|
14
15
|
const Bubble_js_1 = require("./Options/Classes/Bubble.js");
|
|
15
16
|
const Enums_js_1 = require("./Enums.js");
|
|
16
17
|
const Utils_js_1 = require("./Utils.js");
|
|
17
|
-
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0,
|
|
18
|
-
class Bubbler extends
|
|
18
|
+
const bubbleMode = "bubble", minDistance = 0, defaultClickTime = 0, defaultOpacity = 1, ratioOffset = 1, defaultBubbleValue = 0, minRatio = 0, defaultRatio = 1;
|
|
19
|
+
class Bubbler extends plugin_interactivity_1.ExternalInteractorBase {
|
|
19
20
|
constructor(engine, container) {
|
|
20
21
|
super(container);
|
|
21
|
-
this._clickBubble =
|
|
22
|
-
const container = this.container, options = container.actualOptions, mouseClickPos =
|
|
22
|
+
this._clickBubble = interactivityData => {
|
|
23
|
+
const container = this.container, options = container.actualOptions, mouseClickPos = interactivityData.mouse.clickPosition, bubbleOptions = options.interactivity?.modes.bubble;
|
|
23
24
|
if (!bubbleOptions || !mouseClickPos) {
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
@@ -28,18 +29,18 @@
|
|
|
28
29
|
if (!distance || distance < minDistance) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
|
-
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)), { bubble } = container;
|
|
32
|
+
const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(interactivityData, p)), { bubble } = container;
|
|
32
33
|
for (const particle of query) {
|
|
33
34
|
if (!bubble.clicking) {
|
|
34
35
|
continue;
|
|
35
36
|
}
|
|
36
37
|
particle.bubble.inRange = !bubble.durationEnd;
|
|
37
|
-
const pos = particle.getPosition(), distMouse = (0, engine_1.getDistance)(pos, mouseClickPos), timeSpent = (new Date().getTime() - (
|
|
38
|
+
const pos = particle.getPosition(), distMouse = (0, engine_1.getDistance)(pos, mouseClickPos), timeSpent = (new Date().getTime() - (interactivityData.mouse.clickTime ?? defaultClickTime)) /
|
|
38
39
|
engine_1.millisecondsToSeconds;
|
|
39
40
|
if (timeSpent > bubbleOptions.duration) {
|
|
40
41
|
bubble.durationEnd = true;
|
|
41
42
|
}
|
|
42
|
-
if (timeSpent > bubbleOptions.duration * double) {
|
|
43
|
+
if (timeSpent > bubbleOptions.duration * engine_1.double) {
|
|
43
44
|
bubble.clicking = false;
|
|
44
45
|
bubble.durationEnd = false;
|
|
45
46
|
}
|
|
@@ -75,32 +76,32 @@
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
};
|
|
78
|
-
this._hoverBubble =
|
|
79
|
-
const container = this.container, mousePos =
|
|
79
|
+
this._hoverBubble = interactivityData => {
|
|
80
|
+
const container = this.container, mousePos = interactivityData.mouse.position, distance = container.retina.bubbleModeDistance;
|
|
80
81
|
if (!distance || distance < minDistance || !mousePos) {
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
|
-
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
|
|
84
|
+
const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
|
|
84
85
|
for (const particle of query) {
|
|
85
86
|
particle.bubble.inRange = true;
|
|
86
87
|
const pos = particle.getPosition(), pointDistance = (0, engine_1.getDistance)(pos, mousePos), ratio = ratioOffset - pointDistance / distance;
|
|
87
88
|
if (pointDistance <= distance) {
|
|
88
|
-
if (ratio >= minRatio &&
|
|
89
|
+
if (ratio >= minRatio && interactivityData.status === plugin_interactivity_1.mouseMoveEvent) {
|
|
89
90
|
this._hoverBubbleSize(particle, ratio);
|
|
90
91
|
this._hoverBubbleOpacity(particle, ratio);
|
|
91
92
|
this._hoverBubbleColor(particle, ratio);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
else {
|
|
95
|
-
this.reset(particle);
|
|
96
|
+
this.reset(interactivityData, particle);
|
|
96
97
|
}
|
|
97
|
-
if (
|
|
98
|
-
this.reset(particle);
|
|
98
|
+
if (interactivityData.status === plugin_interactivity_1.mouseLeaveEvent) {
|
|
99
|
+
this.reset(interactivityData, particle);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
103
|
this._hoverBubbleColor = (particle, ratio, divBubble) => {
|
|
103
|
-
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity
|
|
104
|
+
const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;
|
|
104
105
|
if (!bubbleOptions) {
|
|
105
106
|
return;
|
|
106
107
|
}
|
|
@@ -127,7 +128,7 @@
|
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
130
|
this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
|
|
130
|
-
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity
|
|
131
|
+
const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity?.modes.bubble?.opacity;
|
|
131
132
|
if (!modeOpacity) {
|
|
132
133
|
return;
|
|
133
134
|
}
|
|
@@ -147,7 +148,7 @@
|
|
|
147
148
|
}
|
|
148
149
|
};
|
|
149
150
|
this._process = (particle, distMouse, timeSpent, data) => {
|
|
150
|
-
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity
|
|
151
|
+
const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity?.modes.bubble;
|
|
151
152
|
if (!bubbleOptions || bubbleParam === undefined) {
|
|
152
153
|
return;
|
|
153
154
|
}
|
|
@@ -189,24 +190,24 @@
|
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
};
|
|
192
|
-
this._singleSelectorHover = (delta, selector, div) => {
|
|
193
|
-
const container = this.container, selectors = (0, engine_1.safeDocument)().querySelectorAll(selector), bubble = container.actualOptions.interactivity
|
|
193
|
+
this._singleSelectorHover = (interactivityData, delta, selector, div) => {
|
|
194
|
+
const container = this.container, selectors = (0, engine_1.safeDocument)().querySelectorAll(selector), bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
194
195
|
if (!bubble || !selectors.length) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
198
|
selectors.forEach(item => {
|
|
198
199
|
const elem = item, pxRatio = container.retina.pixelRatio, pos = {
|
|
199
|
-
x: (elem.offsetLeft + elem.offsetWidth * half) * pxRatio,
|
|
200
|
-
y: (elem.offsetTop + elem.offsetHeight * half) * pxRatio,
|
|
201
|
-
}, repulseRadius = elem.offsetWidth * half * pxRatio, area = div.type ===
|
|
200
|
+
x: (elem.offsetLeft + elem.offsetWidth * engine_1.half) * pxRatio,
|
|
201
|
+
y: (elem.offsetTop + elem.offsetHeight * engine_1.half) * pxRatio,
|
|
202
|
+
}, repulseRadius = elem.offsetWidth * engine_1.half * pxRatio, area = div.type === plugin_interactivity_1.DivType.circle
|
|
202
203
|
? new engine_1.Circle(pos.x, pos.y, repulseRadius)
|
|
203
|
-
: new engine_1.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(p));
|
|
204
|
+
: new engine_1.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, p => this.isEnabled(interactivityData, p));
|
|
204
205
|
for (const particle of query) {
|
|
205
206
|
if (!area.contains(particle.getPosition())) {
|
|
206
207
|
continue;
|
|
207
208
|
}
|
|
208
209
|
particle.bubble.inRange = true;
|
|
209
|
-
const divs = bubble.divs, divBubble = (0,
|
|
210
|
+
const divs = bubble.divs, divBubble = (0, plugin_interactivity_1.divMode)(divs, elem);
|
|
210
211
|
if (!particle.bubble.div || particle.bubble.div !== elem) {
|
|
211
212
|
this.clear(particle, delta, true);
|
|
212
213
|
particle.bubble.div = elem;
|
|
@@ -237,7 +238,7 @@
|
|
|
237
238
|
delete particle.bubble.color;
|
|
238
239
|
}
|
|
239
240
|
init() {
|
|
240
|
-
const container = this.container, bubble = container.actualOptions.interactivity
|
|
241
|
+
const container = this.container, bubble = container.actualOptions.interactivity?.modes.bubble;
|
|
241
242
|
if (!bubble) {
|
|
242
243
|
return;
|
|
243
244
|
}
|
|
@@ -246,22 +247,30 @@
|
|
|
246
247
|
container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
|
-
interact(delta) {
|
|
250
|
-
const options = this.container.actualOptions, events = options.interactivity
|
|
250
|
+
interact(interactivityData, delta) {
|
|
251
|
+
const options = this.container.actualOptions, events = options.interactivity?.events;
|
|
252
|
+
if (!events) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
|
|
251
256
|
if (hoverEnabled && (0, engine_1.isInArray)(bubbleMode, hoverMode)) {
|
|
252
|
-
this._hoverBubble();
|
|
257
|
+
this._hoverBubble(interactivityData);
|
|
253
258
|
}
|
|
254
259
|
else if (clickEnabled && (0, engine_1.isInArray)(bubbleMode, clickMode)) {
|
|
255
|
-
this._clickBubble();
|
|
260
|
+
this._clickBubble(interactivityData);
|
|
256
261
|
}
|
|
257
262
|
else {
|
|
258
|
-
(0,
|
|
259
|
-
this._singleSelectorHover(delta, selector, div);
|
|
263
|
+
(0, plugin_interactivity_1.divModeExecute)(bubbleMode, divs, (selector, div) => {
|
|
264
|
+
this._singleSelectorHover(interactivityData, delta, selector, div);
|
|
260
265
|
});
|
|
261
266
|
}
|
|
262
267
|
}
|
|
263
|
-
isEnabled(particle) {
|
|
264
|
-
const container = this.container, options = container.actualOptions, mouse =
|
|
268
|
+
isEnabled(interactivityData, particle) {
|
|
269
|
+
const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events;
|
|
270
|
+
if (!events) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
const { onClick, onDiv, onHover } = events, divBubble = (0, plugin_interactivity_1.isDivModeEnabled)(bubbleMode, onDiv);
|
|
265
274
|
if (!(divBubble || (onHover.enable && !!mouse.position) || (onClick.enable && mouse.clickPosition))) {
|
|
266
275
|
return false;
|
|
267
276
|
}
|
|
@@ -273,7 +282,7 @@
|
|
|
273
282
|
options.bubble.load(source?.bubble);
|
|
274
283
|
}
|
|
275
284
|
}
|
|
276
|
-
reset(particle) {
|
|
285
|
+
reset(_interactivityData, particle) {
|
|
277
286
|
particle.bubble.inRange = false;
|
|
278
287
|
}
|
|
279
288
|
}
|
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.loadExternalBubbleInteraction = loadExternalBubbleInteraction;
|
|
50
50
|
function loadExternalBubbleInteraction(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?.("externalBubble", async (container) => {
|
|
56
|
+
const { Bubbler } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./Bubbler.js"))) : new Promise((resolve_2, reject_2) => { require(["./Bubbler.js"], resolve_2, reject_2); }).then(__importStar));
|
|
55
57
|
return new Bubbler(e, container);
|
|
56
58
|
});
|
|
57
59
|
});
|
package/809.min.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! For license information please see 809.min.js.LICENSE.txt */
|
|
2
|
-
(this.webpackChunk_tsparticles_interaction_external_bubble=this.webpackChunk_tsparticles_interaction_external_bubble||[]).push([[809],{809(e,i,t){t.d(i,{Bubbler:()=>a});var o,b=t(303),n=t(888);function l(e,i,t,o){if(i>=t){const n=e+(i-t)*o;return(0,b.clamp)(n,e,i)}if(i<t){const n=e-(t-i)*o;return(0,b.clamp)(n,i,e)}}!function(e){e.color="color",e.opacity="opacity",e.size="size"}(o||(o={}));const s="bubble";class a extends b.ExternalInteractorBase{constructor(e,i){super(i),this._clickBubble=()=>{const e=this.container,i=e.actualOptions,t=e.interactivity.mouse.clickPosition,n=i.interactivity.modes.bubble;if(!n||!t)return;e.bubble??={};const l=e.retina.bubbleModeDistance;if(!l||l<0)return;const s=e.particles.quadTree.queryCircle(t,l,(e=>this.isEnabled(e))),{bubble:a}=e;for(const i of s){if(!a.clicking)continue;i.bubble.inRange=!a.durationEnd;const s=i.getPosition(),r=(0,b.getDistance)(s,t),c=((new Date).getTime()-(e.interactivity.mouse.clickTime??0))/b.millisecondsToSeconds;c>n.duration&&(a.durationEnd=!0),c>2*n.duration&&(a.clicking=!1,a.durationEnd=!1);const u={bubbleObj:{optValue:e.retina.bubbleModeSize,value:i.bubble.radius},particlesObj:{optValue:(0,b.getRangeMax)(i.options.size.value)*e.retina.pixelRatio,value:i.size.value},type:o.size};this._process(i,r,c,u);const d={bubbleObj:{optValue:n.opacity,value:i.bubble.opacity},particlesObj:{optValue:(0,b.getRangeMax)(i.options.opacity.value),value:i.opacity?.value??1},type:o.opacity};this._process(i,r,c,d),!a.durationEnd&&r<=l?this._hoverBubbleColor(i,r):delete i.bubble.color}},this._hoverBubble=()=>{const e=this.container,i=e.interactivity.mouse.position,t=e.retina.bubbleModeDistance;if(!t||t<0||!i)return;const o=e.particles.quadTree.queryCircle(i,t,(e=>this.isEnabled(e)));for(const n of o){n.bubble.inRange=!0;const o=n.getPosition(),l=(0,b.getDistance)(o,i),s=1-l/t;l<=t?s>=0&&e.interactivity.status===b.mouseMoveEvent&&(this._hoverBubbleSize(n,s),this._hoverBubbleOpacity(n,s),this._hoverBubbleColor(n,s)):this.reset(n),e.interactivity.status===b.mouseLeaveEvent&&this.reset(n)}},this._hoverBubbleColor=(e,i,t)=>{const o=this.container.actualOptions,n=t??o.interactivity.modes.bubble;if(n){if(!e.bubble.finalColor){const i=n.color;if(!i)return;const t=(0,b.itemFromSingleOrMultiple)(i);e.bubble.finalColor=(0,b.rangeColorToHsl)(this._engine,t)}if(e.bubble.finalColor)if(n.mix){e.bubble.color=void 0;const t=e.getFillColor();e.bubble.color=t?(0,b.rgbToHsl)((0,b.colorMix)(t,e.bubble.finalColor,1-i,i)):e.bubble.finalColor}else e.bubble.color=e.bubble.finalColor}},this._hoverBubbleOpacity=(e,i,t)=>{const o=this.container.actualOptions,n=t?.opacity??o.interactivity.modes.bubble?.opacity;if(!n)return;const s=e.options.opacity.value,a=l(e.opacity?.value??1,n,(0,b.getRangeMax)(s),i);void 0!==a&&(e.bubble.opacity=a)},this._hoverBubbleSize=(e,i,t)=>{const o=this.container,n=t?.size?t.size*o.retina.pixelRatio:o.retina.bubbleModeSize;if(void 0===n)return;const s=(0,b.getRangeMax)(e.options.size.value)*o.retina.pixelRatio,a=l(e.size.value,n,s,i);void 0!==a&&(e.bubble.radius=a)},this._process=(e,i,t,b)=>{const n=this.container,l=b.bubbleObj.optValue,s=n.actualOptions.interactivity.modes.bubble;if(!s||void 0===l)return;const a=s.duration,r=n.retina.bubbleModeDistance,c=b.particlesObj.optValue,u=b.bubbleObj.value,d=b.particlesObj.value??0,p=b.type;if(r&&!(r<0)&&l!==c)if(n.bubble??={},n.bubble.durationEnd)u&&(p===o.size&&delete e.bubble.radius,p===o.opacity&&delete e.bubble.opacity);else if(i<=r){if((u??d)!==l){const i=d-t*(d-l)/a;p===o.size&&(e.bubble.radius=i),p===o.opacity&&(e.bubble.opacity=i)}}else p===o.size&&delete e.bubble.radius,p===o.opacity&&delete e.bubble.opacity},this._singleSelectorHover=(e,i,t)=>{const o=this.container,n=(0,b.safeDocument)().querySelectorAll(i),l=o.actualOptions.interactivity.modes.bubble;l&&n.length&&n.forEach((i=>{const n=i,s=o.retina.pixelRatio,a={x:(n.offsetLeft+.5*n.offsetWidth)*s,y:(n.offsetTop+.5*n.offsetHeight)*s},r=.5*n.offsetWidth*s,c=t.type===b.DivType.circle?new b.Circle(a.x,a.y,r):new b.Rectangle(n.offsetLeft*s,n.offsetTop*s,n.offsetWidth*s,n.offsetHeight*s),u=o.particles.quadTree.query(c,(e=>this.isEnabled(e)));for(const i of u){if(!c.contains(i.getPosition()))continue;i.bubble.inRange=!0;const t=l.divs,o=(0,b.divMode)(t,n);i.bubble.div&&i.bubble.div===n||(this.clear(i,e,!0),i.bubble.div=n),this._hoverBubbleSize(i,1,o),this._hoverBubbleOpacity(i,1,o),this._hoverBubbleColor(i,1,o)}}))},this._engine=e,i.bubble??={},this.handleClickMode=e=>{e===s&&(i.bubble??={},i.bubble.clicking=!0)}}clear(e,i,t){e.bubble.inRange&&!t||(delete e.bubble.div,delete e.bubble.opacity,delete e.bubble.radius,delete e.bubble.color)}init(){const e=this.container,i=e.actualOptions.interactivity.modes.bubble;i&&(e.retina.bubbleModeDistance=i.distance*e.retina.pixelRatio,void 0!==i.size&&(e.retina.bubbleModeSize=i.size*e.retina.pixelRatio))}interact(e){const i=this.container.actualOptions.interactivity.events,t=i.onHover,o=i.onClick,n=t.enable,l=t.mode,a=o.enable,r=o.mode,c=i.onDiv;n&&(0,b.isInArray)(s,l)?this._hoverBubble():a&&(0,b.isInArray)(s,r)?this._clickBubble():(0,b.divModeExecute)(s,c,((i,t)=>{this._singleSelectorHover(e,i,t)}))}isEnabled(e){const i=this.container,t=i.actualOptions,o=i.interactivity.mouse,n=(e?.interactivity??t.interactivity).events,{onClick:l,onDiv:a,onHover:r}=n,c=(0,b.isDivModeEnabled)(s,a);return!!(c||r.enable&&o.position||l.enable&&o.clickPosition)&&((0,b.isInArray)(s,r.mode)||(0,b.isInArray)(s,l.mode)||c)}loadModeOptions(e,...i){e.bubble??=new n.Z;for(const t of i)e.bubble.load(t?.bubble)}reset(e){e.bubble.inRange=!1}}}}]);
|
package/809.min.js.LICENSE.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! tsParticles Bubble External Interaction v4.0.0-alpha.2 by Matteo Bruni */
|