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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +25 -19
  2. package/browser/Bubbler.js +211 -234
  3. package/browser/Options/Classes/Bubble.js +1 -1
  4. package/browser/Options/Classes/BubbleBase.js +2 -2
  5. package/browser/Options/Classes/BubbleDiv.js +0 -10
  6. package/browser/Utils.js +11 -0
  7. package/browser/index.js +2 -2
  8. package/cjs/Bubbler.js +218 -252
  9. package/cjs/Options/Classes/Bubble.js +1 -1
  10. package/cjs/Options/Classes/BubbleBase.js +1 -1
  11. package/cjs/Options/Classes/BubbleDiv.js +0 -10
  12. package/cjs/Utils.js +15 -0
  13. package/cjs/index.js +2 -13
  14. package/esm/Bubbler.js +211 -234
  15. package/esm/Options/Classes/Bubble.js +1 -1
  16. package/esm/Options/Classes/BubbleBase.js +2 -2
  17. package/esm/Options/Classes/BubbleDiv.js +0 -10
  18. package/esm/Utils.js +11 -0
  19. package/esm/index.js +2 -2
  20. package/package.json +6 -5
  21. package/report.html +4 -4
  22. package/tsparticles.interaction.external.bubble.js +255 -262
  23. package/tsparticles.interaction.external.bubble.min.js +1 -1
  24. package/tsparticles.interaction.external.bubble.min.js.LICENSE.txt +1 -8
  25. package/types/Bubbler.d.ts +8 -9
  26. package/types/{IBubblerProcessParam.d.ts → Interfaces.d.ts} +2 -2
  27. package/types/Options/Classes/Bubble.d.ts +1 -1
  28. package/types/Options/Classes/BubbleBase.d.ts +1 -2
  29. package/types/Options/Classes/BubbleDiv.d.ts +1 -3
  30. package/types/Utils.d.ts +1 -0
  31. package/types/index.d.ts +1 -1
  32. package/umd/Bubbler.js +211 -234
  33. package/umd/Options/Classes/Bubble.js +2 -2
  34. package/umd/Options/Classes/BubbleBase.js +1 -1
  35. package/umd/Options/Classes/BubbleDiv.js +1 -11
  36. package/umd/Utils.js +25 -0
  37. package/umd/index.js +2 -2
  38. /package/browser/{IBubblerProcessParam.js → Enums.js} +0 -0
  39. /package/browser/{ProcessBubbleType.js → Interfaces.js} +0 -0
  40. /package/cjs/{IBubblerProcessParam.js → Enums.js} +0 -0
  41. /package/cjs/{ProcessBubbleType.js → Interfaces.js} +0 -0
  42. /package/esm/{IBubblerProcessParam.js → Enums.js} +0 -0
  43. /package/esm/{ProcessBubbleType.js → Interfaces.js} +0 -0
  44. /package/types/{ProcessBubbleType.d.ts → Enums.d.ts} +0 -0
  45. /package/umd/{IBubblerProcessParam.js → Enums.js} +0 -0
  46. /package/umd/{ProcessBubbleType.js → Interfaces.js} +0 -0
package/esm/Bubbler.js CHANGED
@@ -1,18 +1,211 @@
1
- import { Circle, ExternalInteractorBase, Rectangle, clamp, colorMix, divMode, divModeExecute, getDistance, getRangeMax, isDivModeEnabled, isInArray, itemFromSingleOrMultiple, mouseLeaveEvent, mouseMoveEvent, rangeColorToHsl, rgbToHsl, } from "@tsparticles/engine";
1
+ import { Circle, ExternalInteractorBase, Rectangle, colorMix, divMode, divModeExecute, getDistance, getRangeMax, isDivModeEnabled, isInArray, itemFromSingleOrMultiple, mouseLeaveEvent, mouseMoveEvent, rangeColorToHsl, rgbToHsl, } from "@tsparticles/engine";
2
2
  import { Bubble } from "./Options/Classes/Bubble";
3
- function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
4
- if (modeValue >= optionsValue) {
5
- const value = particleValue + (modeValue - optionsValue) * ratio;
6
- return clamp(value, particleValue, modeValue);
7
- }
8
- else if (modeValue < optionsValue) {
9
- const value = particleValue - (optionsValue - modeValue) * ratio;
10
- return clamp(value, modeValue, particleValue);
11
- }
12
- }
3
+ import { calculateBubbleValue } from "./Utils";
13
4
  export class Bubbler extends ExternalInteractorBase {
14
5
  constructor(container) {
15
6
  super(container);
7
+ this._clickBubble = () => {
8
+ const container = this.container, options = container.actualOptions, mouseClickPos = container.interactivity.mouse.clickPosition, bubbleOptions = options.interactivity.modes.bubble;
9
+ if (!bubbleOptions || !mouseClickPos) {
10
+ return;
11
+ }
12
+ if (!container.bubble) {
13
+ container.bubble = {};
14
+ }
15
+ const distance = container.retina.bubbleModeDistance;
16
+ if (!distance || distance < 0) {
17
+ return;
18
+ }
19
+ const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, (p) => this.isEnabled(p)), { bubble } = container;
20
+ for (const particle of query) {
21
+ if (!bubble.clicking) {
22
+ continue;
23
+ }
24
+ particle.bubble.inRange = !bubble.durationEnd;
25
+ const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000;
26
+ if (timeSpent > bubbleOptions.duration) {
27
+ bubble.durationEnd = true;
28
+ }
29
+ if (timeSpent > bubbleOptions.duration * 2) {
30
+ bubble.clicking = false;
31
+ bubble.durationEnd = false;
32
+ }
33
+ const sizeData = {
34
+ bubbleObj: {
35
+ optValue: container.retina.bubbleModeSize,
36
+ value: particle.bubble.radius,
37
+ },
38
+ particlesObj: {
39
+ optValue: getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
40
+ value: particle.size.value,
41
+ },
42
+ type: "size",
43
+ };
44
+ this._process(particle, distMouse, timeSpent, sizeData);
45
+ const opacityData = {
46
+ bubbleObj: {
47
+ optValue: bubbleOptions.opacity,
48
+ value: particle.bubble.opacity,
49
+ },
50
+ particlesObj: {
51
+ optValue: getRangeMax(particle.options.opacity.value),
52
+ value: particle.opacity?.value ?? 1,
53
+ },
54
+ type: "opacity",
55
+ };
56
+ this._process(particle, distMouse, timeSpent, opacityData);
57
+ if (!bubble.durationEnd && distMouse <= distance) {
58
+ this._hoverBubbleColor(particle, distMouse);
59
+ }
60
+ else {
61
+ delete particle.bubble.color;
62
+ }
63
+ }
64
+ };
65
+ this._hoverBubble = () => {
66
+ const container = this.container, mousePos = container.interactivity.mouse.position, distance = container.retina.bubbleModeDistance;
67
+ if (!distance || distance < 0 || mousePos === undefined) {
68
+ return;
69
+ }
70
+ const query = container.particles.quadTree.queryCircle(mousePos, distance, (p) => this.isEnabled(p));
71
+ for (const particle of query) {
72
+ particle.bubble.inRange = true;
73
+ const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = 1 - pointDistance / distance;
74
+ if (pointDistance <= distance) {
75
+ if (ratio >= 0 && container.interactivity.status === mouseMoveEvent) {
76
+ this._hoverBubbleSize(particle, ratio);
77
+ this._hoverBubbleOpacity(particle, ratio);
78
+ this._hoverBubbleColor(particle, ratio);
79
+ }
80
+ }
81
+ else {
82
+ this.reset(particle);
83
+ }
84
+ if (container.interactivity.status === mouseLeaveEvent) {
85
+ this.reset(particle);
86
+ }
87
+ }
88
+ };
89
+ this._hoverBubbleColor = (particle, ratio, divBubble) => {
90
+ const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity.modes.bubble;
91
+ if (!bubbleOptions) {
92
+ return;
93
+ }
94
+ if (!particle.bubble.finalColor) {
95
+ const modeColor = bubbleOptions.color;
96
+ if (!modeColor) {
97
+ return;
98
+ }
99
+ const bubbleColor = itemFromSingleOrMultiple(modeColor);
100
+ particle.bubble.finalColor = rangeColorToHsl(bubbleColor);
101
+ }
102
+ if (!particle.bubble.finalColor) {
103
+ return;
104
+ }
105
+ if (bubbleOptions.mix) {
106
+ particle.bubble.color = undefined;
107
+ const pColor = particle.getFillColor();
108
+ particle.bubble.color = pColor
109
+ ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio))
110
+ : particle.bubble.finalColor;
111
+ }
112
+ else {
113
+ particle.bubble.color = particle.bubble.finalColor;
114
+ }
115
+ };
116
+ this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
117
+ const container = this.container, options = container.actualOptions, modeOpacity = divBubble?.opacity ?? options.interactivity.modes.bubble?.opacity;
118
+ if (!modeOpacity) {
119
+ return;
120
+ }
121
+ const optOpacity = particle.options.opacity.value, pOpacity = particle.opacity?.value ?? 1, opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
122
+ if (opacity !== undefined) {
123
+ particle.bubble.opacity = opacity;
124
+ }
125
+ };
126
+ this._hoverBubbleSize = (particle, ratio, divBubble) => {
127
+ const container = this.container, modeSize = divBubble?.size ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;
128
+ if (modeSize === undefined) {
129
+ return;
130
+ }
131
+ const optSize = getRangeMax(particle.options.size.value) * container.retina.pixelRatio, pSize = particle.size.value, size = calculateBubbleValue(pSize, modeSize, optSize, ratio);
132
+ if (size !== undefined) {
133
+ particle.bubble.radius = size;
134
+ }
135
+ };
136
+ this._process = (particle, distMouse, timeSpent, data) => {
137
+ const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubbleOptions = options.interactivity.modes.bubble;
138
+ if (!bubbleOptions || bubbleParam === undefined) {
139
+ return;
140
+ }
141
+ const bubbleDuration = bubbleOptions.duration, bubbleDistance = container.retina.bubbleModeDistance, particlesParam = data.particlesObj.optValue, pObjBubble = data.bubbleObj.value, pObj = data.particlesObj.value || 0, type = data.type;
142
+ if (!bubbleDistance || bubbleDistance < 0 || bubbleParam === particlesParam) {
143
+ return;
144
+ }
145
+ if (!container.bubble) {
146
+ container.bubble = {};
147
+ }
148
+ if (container.bubble.durationEnd) {
149
+ if (pObjBubble) {
150
+ if (type === "size") {
151
+ delete particle.bubble.radius;
152
+ }
153
+ if (type === "opacity") {
154
+ delete particle.bubble.opacity;
155
+ }
156
+ }
157
+ }
158
+ else {
159
+ if (distMouse <= bubbleDistance) {
160
+ const obj = pObjBubble ?? pObj;
161
+ if (obj !== bubbleParam) {
162
+ const value = pObj - (timeSpent * (pObj - bubbleParam)) / bubbleDuration;
163
+ if (type === "size") {
164
+ particle.bubble.radius = value;
165
+ }
166
+ if (type === "opacity") {
167
+ particle.bubble.opacity = value;
168
+ }
169
+ }
170
+ }
171
+ else {
172
+ if (type === "size") {
173
+ delete particle.bubble.radius;
174
+ }
175
+ if (type === "opacity") {
176
+ delete particle.bubble.opacity;
177
+ }
178
+ }
179
+ }
180
+ };
181
+ this._singleSelectorHover = (delta, selector, div) => {
182
+ const container = this.container, selectors = document.querySelectorAll(selector), bubble = container.actualOptions.interactivity.modes.bubble;
183
+ if (!bubble || !selectors.length) {
184
+ return;
185
+ }
186
+ selectors.forEach((item) => {
187
+ const elem = item, pxRatio = container.retina.pixelRatio, pos = {
188
+ x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
189
+ y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio,
190
+ }, repulseRadius = (elem.offsetWidth / 2) * pxRatio, area = div.type === "circle"
191
+ ? new Circle(pos.x, pos.y, repulseRadius)
192
+ : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, (p) => this.isEnabled(p));
193
+ for (const particle of query) {
194
+ if (!area.contains(particle.getPosition())) {
195
+ continue;
196
+ }
197
+ particle.bubble.inRange = true;
198
+ const divs = bubble.divs, divBubble = divMode(divs, elem);
199
+ if (!particle.bubble.div || particle.bubble.div !== elem) {
200
+ this.clear(particle, delta, true);
201
+ particle.bubble.div = elem;
202
+ }
203
+ this._hoverBubbleSize(particle, 1, divBubble);
204
+ this._hoverBubbleOpacity(particle, 1, divBubble);
205
+ this._hoverBubbleColor(particle, 1, divBubble);
206
+ }
207
+ });
208
+ };
16
209
  if (!container.bubble) {
17
210
  container.bubble = {};
18
211
  }
@@ -48,247 +241,31 @@ export class Bubbler extends ExternalInteractorBase {
48
241
  async interact(delta) {
49
242
  const options = this.container.actualOptions, events = options.interactivity.events, onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
50
243
  if (hoverEnabled && isInArray("bubble", hoverMode)) {
51
- this.hoverBubble(delta);
244
+ this._hoverBubble();
52
245
  }
53
246
  else if (clickEnabled && isInArray("bubble", clickMode)) {
54
- this.clickBubble(delta);
247
+ this._clickBubble();
55
248
  }
56
249
  else {
57
- divModeExecute("bubble", divs, (selector, div) => this.singleSelectorHover(delta, selector, div));
250
+ divModeExecute("bubble", divs, (selector, div) => this._singleSelectorHover(delta, selector, div));
58
251
  }
59
252
  }
60
253
  isEnabled(particle) {
61
- var _a;
62
- const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events, divs = events.onDiv, divBubble = isDivModeEnabled("bubble", divs);
63
- if (!(divBubble || (events.onHover.enable && mouse.position) || (events.onClick.enable && mouse.clickPosition))) {
254
+ const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = (particle?.interactivity ?? options.interactivity).events, { onClick, onDiv, onHover } = events, divBubble = isDivModeEnabled("bubble", onDiv);
255
+ if (!(divBubble || (onHover.enable && mouse.position) || (onClick.enable && mouse.clickPosition))) {
64
256
  return false;
65
257
  }
66
- const hoverMode = events.onHover.mode;
67
- const clickMode = events.onClick.mode;
68
- return isInArray("bubble", hoverMode) || isInArray("bubble", clickMode) || divBubble;
258
+ return isInArray("bubble", onHover.mode) || isInArray("bubble", onClick.mode) || divBubble;
69
259
  }
70
260
  loadModeOptions(options, ...sources) {
71
261
  if (!options.bubble) {
72
262
  options.bubble = new Bubble();
73
263
  }
74
264
  for (const source of sources) {
75
- options.bubble.load(source === null || source === void 0 ? void 0 : source.bubble);
265
+ options.bubble.load(source?.bubble);
76
266
  }
77
267
  }
78
268
  reset(particle) {
79
269
  particle.bubble.inRange = false;
80
270
  }
81
- clickBubble(delta) {
82
- var _a, _b;
83
- const container = this.container, options = container.actualOptions, mouseClickPos = container.interactivity.mouse.clickPosition, bubble = options.interactivity.modes.bubble;
84
- if (!bubble || !mouseClickPos) {
85
- return;
86
- }
87
- if (!container.bubble) {
88
- container.bubble = {};
89
- }
90
- const distance = container.retina.bubbleModeDistance;
91
- if (!distance || distance < 0) {
92
- return;
93
- }
94
- const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, (p) => this.isEnabled(p));
95
- for (const particle of query) {
96
- if (!container.bubble.clicking) {
97
- continue;
98
- }
99
- particle.bubble.inRange = !container.bubble.durationEnd;
100
- const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000;
101
- if (timeSpent > bubble.duration) {
102
- container.bubble.durationEnd = true;
103
- }
104
- if (timeSpent > bubble.duration * 2) {
105
- container.bubble.clicking = false;
106
- container.bubble.durationEnd = false;
107
- }
108
- const sizeData = {
109
- bubbleObj: {
110
- optValue: container.retina.bubbleModeSize,
111
- value: particle.bubble.radius,
112
- },
113
- particlesObj: {
114
- optValue: getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
115
- value: particle.size.value,
116
- },
117
- type: "size",
118
- };
119
- this.process(particle, distMouse, timeSpent, sizeData);
120
- const opacityData = {
121
- bubbleObj: {
122
- optValue: bubble.opacity,
123
- value: particle.bubble.opacity,
124
- },
125
- particlesObj: {
126
- optValue: getRangeMax(particle.options.opacity.value),
127
- value: (_b = (_a = particle.opacity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 1,
128
- },
129
- type: "opacity",
130
- };
131
- this.process(particle, distMouse, timeSpent, opacityData);
132
- if (!container.bubble.durationEnd) {
133
- if (distMouse <= distance) {
134
- this.hoverBubbleColor(particle, distMouse);
135
- }
136
- else {
137
- delete particle.bubble.color;
138
- }
139
- }
140
- else {
141
- delete particle.bubble.color;
142
- }
143
- }
144
- }
145
- hoverBubble(delta) {
146
- const container = this.container, mousePos = container.interactivity.mouse.position, distance = container.retina.bubbleModeDistance;
147
- if (!distance || distance < 0 || mousePos === undefined) {
148
- return;
149
- }
150
- const query = container.particles.quadTree.queryCircle(mousePos, distance, (p) => this.isEnabled(p));
151
- for (const particle of query) {
152
- particle.bubble.inRange = true;
153
- const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = 1 - pointDistance / distance;
154
- if (pointDistance <= distance) {
155
- if (ratio >= 0 && container.interactivity.status === mouseMoveEvent) {
156
- this.hoverBubbleSize(particle, ratio);
157
- this.hoverBubbleOpacity(particle, ratio);
158
- this.hoverBubbleColor(particle, ratio);
159
- }
160
- }
161
- else {
162
- this.reset(particle);
163
- }
164
- if (container.interactivity.status === mouseLeaveEvent) {
165
- this.reset(particle);
166
- }
167
- }
168
- }
169
- hoverBubbleColor(particle, ratio, divBubble) {
170
- const options = this.container.actualOptions;
171
- const bubbleOptions = divBubble !== null && divBubble !== void 0 ? divBubble : options.interactivity.modes.bubble;
172
- if (!bubbleOptions) {
173
- return;
174
- }
175
- if (!particle.bubble.finalColor) {
176
- const modeColor = bubbleOptions.color;
177
- if (!modeColor) {
178
- return;
179
- }
180
- const bubbleColor = itemFromSingleOrMultiple(modeColor);
181
- particle.bubble.finalColor = rangeColorToHsl(bubbleColor);
182
- }
183
- if (!particle.bubble.finalColor) {
184
- return;
185
- }
186
- if (bubbleOptions.mix) {
187
- particle.bubble.color = undefined;
188
- const pColor = particle.getFillColor();
189
- particle.bubble.color = pColor
190
- ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio))
191
- : particle.bubble.finalColor;
192
- }
193
- else {
194
- particle.bubble.color = particle.bubble.finalColor;
195
- }
196
- }
197
- hoverBubbleOpacity(particle, ratio, divBubble) {
198
- var _a, _b, _c, _d;
199
- const container = this.container, options = container.actualOptions, modeOpacity = (_a = divBubble === null || divBubble === void 0 ? void 0 : divBubble.opacity) !== null && _a !== void 0 ? _a : (_b = options.interactivity.modes.bubble) === null || _b === void 0 ? void 0 : _b.opacity;
200
- if (!modeOpacity) {
201
- return;
202
- }
203
- const optOpacity = particle.options.opacity.value;
204
- const pOpacity = (_d = (_c = particle.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 1;
205
- const opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
206
- if (opacity !== undefined) {
207
- particle.bubble.opacity = opacity;
208
- }
209
- }
210
- hoverBubbleSize(particle, ratio, divBubble) {
211
- const container = this.container, modeSize = (divBubble === null || divBubble === void 0 ? void 0 : divBubble.size) ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;
212
- if (modeSize === undefined) {
213
- return;
214
- }
215
- const optSize = getRangeMax(particle.options.size.value) * container.retina.pixelRatio;
216
- const pSize = particle.size.value;
217
- const size = calculateBubbleValue(pSize, modeSize, optSize, ratio);
218
- if (size !== undefined) {
219
- particle.bubble.radius = size;
220
- }
221
- }
222
- process(particle, distMouse, timeSpent, data) {
223
- const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubble = options.interactivity.modes.bubble;
224
- if (!bubble || bubbleParam === undefined) {
225
- return;
226
- }
227
- const bubbleDuration = bubble.duration, bubbleDistance = container.retina.bubbleModeDistance, particlesParam = data.particlesObj.optValue, pObjBubble = data.bubbleObj.value, pObj = data.particlesObj.value || 0, type = data.type;
228
- if (!bubbleDistance || bubbleDistance < 0 || bubbleParam === particlesParam) {
229
- return;
230
- }
231
- if (!container.bubble) {
232
- container.bubble = {};
233
- }
234
- if (!container.bubble.durationEnd) {
235
- if (distMouse <= bubbleDistance) {
236
- const obj = pObjBubble !== null && pObjBubble !== void 0 ? pObjBubble : pObj;
237
- if (obj !== bubbleParam) {
238
- const value = pObj - (timeSpent * (pObj - bubbleParam)) / bubbleDuration;
239
- if (type === "size") {
240
- particle.bubble.radius = value;
241
- }
242
- if (type === "opacity") {
243
- particle.bubble.opacity = value;
244
- }
245
- }
246
- }
247
- else {
248
- if (type === "size") {
249
- delete particle.bubble.radius;
250
- }
251
- if (type === "opacity") {
252
- delete particle.bubble.opacity;
253
- }
254
- }
255
- }
256
- else if (pObjBubble) {
257
- if (type === "size") {
258
- delete particle.bubble.radius;
259
- }
260
- if (type === "opacity") {
261
- delete particle.bubble.opacity;
262
- }
263
- }
264
- }
265
- singleSelectorHover(delta, selector, div) {
266
- const container = this.container, selectors = document.querySelectorAll(selector), bubble = container.actualOptions.interactivity.modes.bubble;
267
- if (!bubble || !selectors.length) {
268
- return;
269
- }
270
- selectors.forEach((item) => {
271
- const elem = item, pxRatio = container.retina.pixelRatio, pos = {
272
- x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
273
- y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio,
274
- }, repulseRadius = (elem.offsetWidth / 2) * pxRatio, area = div.type === "circle"
275
- ? new Circle(pos.x, pos.y, repulseRadius)
276
- : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, (p) => this.isEnabled(p));
277
- for (const particle of query) {
278
- if (!area.contains(particle.getPosition())) {
279
- continue;
280
- }
281
- particle.bubble.inRange = true;
282
- const divs = bubble.divs;
283
- const divBubble = divMode(divs, elem);
284
- if (!particle.bubble.div || particle.bubble.div !== elem) {
285
- this.clear(particle, delta, true);
286
- particle.bubble.div = elem;
287
- }
288
- this.hoverBubbleSize(particle, 1, divBubble);
289
- this.hoverBubbleOpacity(particle, 1, divBubble);
290
- this.hoverBubbleColor(particle, 1, divBubble);
291
- }
292
- });
293
- }
294
271
  }
@@ -1,6 +1,6 @@
1
+ import { executeOnSingleOrMultiple, } from "@tsparticles/engine";
1
2
  import { BubbleBase } from "./BubbleBase";
2
3
  import { BubbleDiv } from "./BubbleDiv";
3
- import { executeOnSingleOrMultiple } from "@tsparticles/engine";
4
4
  export class Bubble extends BubbleBase {
5
5
  load(data) {
6
6
  super.load(data);
@@ -1,4 +1,4 @@
1
- import { OptionsColor, executeOnSingleOrMultiple } from "@tsparticles/engine";
1
+ import { OptionsColor, executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
2
  export class BubbleBase {
3
3
  constructor() {
4
4
  this.distance = 200;
@@ -22,7 +22,7 @@ export class BubbleBase {
22
22
  this.opacity = data.opacity;
23
23
  }
24
24
  if (data.color !== undefined) {
25
- const sourceColor = this.color instanceof Array ? undefined : this.color;
25
+ const sourceColor = isArray(this.color) ? undefined : this.color;
26
26
  this.color = executeOnSingleOrMultiple(data.color, (color) => {
27
27
  return OptionsColor.create(sourceColor, color);
28
28
  });
@@ -1,24 +1,14 @@
1
1
  import { BubbleBase } from "./BubbleBase";
2
- import { executeOnSingleOrMultiple } from "@tsparticles/engine";
3
2
  export class BubbleDiv extends BubbleBase {
4
3
  constructor() {
5
4
  super();
6
5
  this.selectors = [];
7
6
  }
8
- get ids() {
9
- return executeOnSingleOrMultiple(this.selectors, (t) => t.replace("#", ""));
10
- }
11
- set ids(value) {
12
- this.selectors = executeOnSingleOrMultiple(value, (t) => `#${t}`);
13
- }
14
7
  load(data) {
15
8
  super.load(data);
16
9
  if (!data) {
17
10
  return;
18
11
  }
19
- if (data.ids !== undefined) {
20
- this.ids = data.ids;
21
- }
22
12
  if (data.selectors !== undefined) {
23
13
  this.selectors = data.selectors;
24
14
  }
package/esm/Utils.js ADDED
@@ -0,0 +1,11 @@
1
+ import { clamp } from "@tsparticles/engine";
2
+ export function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
3
+ if (modeValue >= optionsValue) {
4
+ const value = particleValue + (modeValue - optionsValue) * ratio;
5
+ return clamp(value, particleValue, modeValue);
6
+ }
7
+ else if (modeValue < optionsValue) {
8
+ const value = particleValue - (optionsValue - modeValue) * ratio;
9
+ return clamp(value, modeValue, particleValue);
10
+ }
11
+ }
package/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Bubbler } from "./Bubbler";
2
- export async function loadExternalBubbleInteraction(engine) {
3
- await engine.addInteractor("externalBubble", (container) => new Bubbler(container));
2
+ export async function loadExternalBubbleInteraction(engine, refresh = true) {
3
+ await engine.addInteractor("externalBubble", (container) => new Bubbler(container), refresh);
4
4
  }
5
5
  export * from "./Options/Classes/BubbleBase";
6
6
  export * from "./Options/Classes/BubbleDiv";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/interaction-external-bubble",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "tsParticles bubble external interaction",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -73,10 +73,11 @@
73
73
  "unpkg": "tsparticles.interaction.external.bubble.min.js",
74
74
  "module": "esm/index.js",
75
75
  "types": "types/index.d.ts",
76
+ "sideEffects": false,
77
+ "dependencies": {
78
+ "@tsparticles/engine": "^3.0.0-beta.0"
79
+ },
76
80
  "publishConfig": {
77
81
  "access": "public"
78
- },
79
- "dependencies": {
80
- "@tsparticles/engine": "^3.0.0-alpha.1"
81
82
  }
82
- }
83
+ }