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

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 (53) hide show
  1. package/README.md +25 -19
  2. package/browser/Bubbler.js +212 -235
  3. package/browser/Options/Classes/Bubble.js +3 -3
  4. package/browser/Options/Classes/BubbleBase.js +2 -2
  5. package/browser/Options/Classes/BubbleDiv.js +1 -11
  6. package/browser/Utils.js +11 -0
  7. package/browser/index.js +9 -9
  8. package/browser/package.json +1 -0
  9. package/cjs/Bubbler.js +220 -254
  10. package/cjs/Options/Classes/Bubble.js +4 -4
  11. package/cjs/Options/Classes/BubbleBase.js +1 -1
  12. package/cjs/Options/Classes/BubbleDiv.js +2 -12
  13. package/cjs/Utils.js +15 -0
  14. package/cjs/index.js +9 -20
  15. package/cjs/package.json +1 -0
  16. package/esm/Bubbler.js +212 -235
  17. package/esm/Options/Classes/Bubble.js +3 -3
  18. package/esm/Options/Classes/BubbleBase.js +2 -2
  19. package/esm/Options/Classes/BubbleDiv.js +1 -11
  20. package/esm/Utils.js +11 -0
  21. package/esm/index.js +9 -9
  22. package/esm/package.json +1 -0
  23. package/package.json +19 -6
  24. package/report.html +4 -4
  25. package/tsparticles.interaction.external.bubble.js +255 -262
  26. package/tsparticles.interaction.external.bubble.min.js +1 -1
  27. package/tsparticles.interaction.external.bubble.min.js.LICENSE.txt +1 -8
  28. package/types/Bubbler.d.ts +9 -10
  29. package/types/{IBubblerProcessParam.d.ts → Interfaces.d.ts} +2 -2
  30. package/types/Options/Classes/Bubble.d.ts +4 -4
  31. package/types/Options/Classes/BubbleBase.d.ts +2 -3
  32. package/types/Options/Classes/BubbleDiv.d.ts +3 -5
  33. package/types/Options/Classes/BubbleOptions.d.ts +1 -1
  34. package/types/Options/Interfaces/IBubble.d.ts +2 -2
  35. package/types/Options/Interfaces/IBubbleDiv.d.ts +1 -1
  36. package/types/Types.d.ts +3 -3
  37. package/types/Utils.d.ts +1 -0
  38. package/types/index.d.ts +7 -7
  39. package/umd/Bubbler.js +213 -236
  40. package/umd/Options/Classes/Bubble.js +5 -5
  41. package/umd/Options/Classes/BubbleBase.js +1 -1
  42. package/umd/Options/Classes/BubbleDiv.js +3 -13
  43. package/umd/Utils.js +25 -0
  44. package/umd/index.js +10 -10
  45. /package/browser/{IBubblerProcessParam.js → Enums.js} +0 -0
  46. /package/browser/{ProcessBubbleType.js → Interfaces.js} +0 -0
  47. /package/cjs/{IBubblerProcessParam.js → Enums.js} +0 -0
  48. /package/cjs/{ProcessBubbleType.js → Interfaces.js} +0 -0
  49. /package/esm/{IBubblerProcessParam.js → Enums.js} +0 -0
  50. /package/esm/{ProcessBubbleType.js → Interfaces.js} +0 -0
  51. /package/types/{ProcessBubbleType.d.ts → Enums.d.ts} +0 -0
  52. /package/umd/{IBubblerProcessParam.js → Enums.js} +0 -0
  53. /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";
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
- }
1
+ import { Circle, ExternalInteractorBase, Rectangle, colorMix, divMode, divModeExecute, getDistance, getRangeMax, isDivModeEnabled, isInArray, itemFromSingleOrMultiple, mouseLeaveEvent, mouseMoveEvent, rangeColorToHsl, rgbToHsl, } from "@tsparticles/engine";
2
+ import { Bubble } from "./Options/Classes/Bubble.js";
3
+ import { calculateBubbleValue } from "./Utils.js";
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 { BubbleBase } from "./BubbleBase";
2
- import { BubbleDiv } from "./BubbleDiv";
3
- import { executeOnSingleOrMultiple } from "@tsparticles/engine";
1
+ import { executeOnSingleOrMultiple, } from "@tsparticles/engine";
2
+ import { BubbleBase } from "./BubbleBase.js";
3
+ import { BubbleDiv } from "./BubbleDiv.js";
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
- import { BubbleBase } from "./BubbleBase";
2
- import { executeOnSingleOrMultiple } from "@tsparticles/engine";
1
+ import { BubbleBase } from "./BubbleBase.js";
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,10 +1,10 @@
1
- import { Bubbler } from "./Bubbler";
2
- export async function loadExternalBubbleInteraction(engine) {
3
- await engine.addInteractor("externalBubble", (container) => new Bubbler(container));
1
+ import { Bubbler } from "./Bubbler.js";
2
+ export async function loadExternalBubbleInteraction(engine, refresh = true) {
3
+ await engine.addInteractor("externalBubble", (container) => new Bubbler(container), refresh);
4
4
  }
5
- export * from "./Options/Classes/BubbleBase";
6
- export * from "./Options/Classes/BubbleDiv";
7
- export * from "./Options/Classes/Bubble";
8
- export * from "./Options/Interfaces/IBubbleBase";
9
- export * from "./Options/Interfaces/IBubbleDiv";
10
- export * from "./Options/Interfaces/IBubble";
5
+ export * from "./Options/Classes/BubbleBase.js";
6
+ export * from "./Options/Classes/BubbleDiv.js";
7
+ export * from "./Options/Classes/Bubble.js";
8
+ export * from "./Options/Interfaces/IBubbleBase.js";
9
+ export * from "./Options/Interfaces/IBubbleDiv.js";
10
+ export * from "./Options/Interfaces/IBubble.js";
@@ -0,0 +1 @@
1
+ { "type": "module" }
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.1",
4
4
  "description": "tsParticles bubble external interaction",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -68,15 +68,28 @@
68
68
  "bugs": {
69
69
  "url": "https://github.com/matteobruni/tsparticles/issues"
70
70
  },
71
- "main": "cjs/index.js",
71
+ "sideEffects": false,
72
72
  "jsdelivr": "tsparticles.interaction.external.bubble.min.js",
73
73
  "unpkg": "tsparticles.interaction.external.bubble.min.js",
74
+ "browser": "browser/index.js",
75
+ "main": "cjs/index.js",
74
76
  "module": "esm/index.js",
75
77
  "types": "types/index.d.ts",
76
- "publishConfig": {
77
- "access": "public"
78
+ "exports": {
79
+ ".": {
80
+ "types": "./types/index.d.ts",
81
+ "browser": "./browser/index.js",
82
+ "import": "./esm/index.js",
83
+ "require": "./cjs/index.js",
84
+ "umd": "./umd/index.js",
85
+ "default": "./cjs/index.js"
86
+ },
87
+ "./package.json": "./package.json"
78
88
  },
79
89
  "dependencies": {
80
- "@tsparticles/engine": "^3.0.0-alpha.1"
90
+ "@tsparticles/engine": "^3.0.0-beta.1"
91
+ },
92
+ "publishConfig": {
93
+ "access": "public"
81
94
  }
82
- }
95
+ }