@tsparticles/engine 4.0.5 → 4.1.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.
- package/browser/Core/CanvasManager.js +72 -72
- package/browser/Core/Container.js +85 -85
- package/browser/Core/Engine.js +11 -11
- package/browser/Core/Particle.js +142 -63
- package/browser/Core/ParticlesManager.js +138 -138
- package/browser/Core/RenderManager.js +110 -110
- package/browser/Core/Retina.js +3 -4
- package/browser/Core/Utils/EventListeners.js +31 -31
- package/browser/Core/Utils/PluginManager.js +26 -26
- package/browser/Core/Utils/SpatialHashGrid.js +36 -36
- package/browser/Core/Utils/Vectors.js +3 -3
- package/browser/Options/Classes/Options.js +13 -13
- package/browser/Options/Classes/Particles/ParticlesOptions.js +11 -19
- package/browser/Utils/EventDispatcher.js +10 -10
- package/browser/exports.js +0 -4
- package/cjs/Core/CanvasManager.js +72 -72
- package/cjs/Core/Container.js +85 -85
- package/cjs/Core/Engine.js +11 -11
- package/cjs/Core/Particle.js +142 -63
- package/cjs/Core/ParticlesManager.js +138 -138
- package/cjs/Core/RenderManager.js +110 -110
- package/cjs/Core/Retina.js +3 -4
- package/cjs/Core/Utils/EventListeners.js +31 -31
- package/cjs/Core/Utils/PluginManager.js +26 -26
- package/cjs/Core/Utils/SpatialHashGrid.js +36 -36
- package/cjs/Core/Utils/Vectors.js +3 -3
- package/cjs/Options/Classes/Options.js +13 -13
- package/cjs/Options/Classes/Particles/ParticlesOptions.js +11 -19
- package/cjs/Utils/EventDispatcher.js +10 -10
- package/cjs/exports.js +0 -4
- package/esm/Core/CanvasManager.js +72 -72
- package/esm/Core/Container.js +85 -85
- package/esm/Core/Engine.js +11 -11
- package/esm/Core/Particle.js +142 -63
- package/esm/Core/ParticlesManager.js +138 -138
- package/esm/Core/RenderManager.js +110 -110
- package/esm/Core/Retina.js +3 -4
- package/esm/Core/Utils/EventListeners.js +31 -31
- package/esm/Core/Utils/PluginManager.js +26 -26
- package/esm/Core/Utils/SpatialHashGrid.js +36 -36
- package/esm/Core/Utils/Vectors.js +3 -3
- package/esm/Options/Classes/Options.js +13 -13
- package/esm/Options/Classes/Particles/ParticlesOptions.js +11 -19
- package/esm/Utils/EventDispatcher.js +10 -10
- package/esm/exports.js +0 -4
- package/package.json +1 -1
- package/report.html +1 -1
- package/tsparticles.engine.js +690 -697
- package/tsparticles.engine.min.js +1 -1
- package/types/Core/CanvasManager.d.ts +1 -16
- package/types/Core/Container.d.ts +1 -18
- package/types/Core/Engine.d.ts +1 -3
- package/types/Core/Interfaces/IEffectDrawer.d.ts +2 -0
- package/types/Core/Interfaces/IParticleCanvasBounds.d.ts +16 -0
- package/types/Core/Interfaces/IParticleUpdater.d.ts +1 -0
- package/types/Core/Interfaces/IShapeDrawer.d.ts +2 -0
- package/types/Core/Particle.d.ts +5 -13
- package/types/Core/ParticlesManager.d.ts +1 -28
- package/types/Core/RenderManager.d.ts +1 -23
- package/types/Core/Retina.d.ts +1 -1
- package/types/Core/Utils/EventListeners.d.ts +1 -8
- package/types/Core/Utils/PluginManager.d.ts +1 -8
- package/types/Core/Utils/SpatialHashGrid.d.ts +1 -12
- package/types/Core/Utils/Vectors.d.ts +1 -1
- package/types/Options/Classes/Options.d.ts +1 -4
- package/types/Options/Classes/Particles/ParticlesOptions.d.ts +1 -7
- package/types/Options/Interfaces/Particles/IParticlesOptions.d.ts +0 -4
- package/types/Utils/EventDispatcher.d.ts +1 -1
- package/types/export-types.d.ts +1 -4
- package/types/exports.d.ts +0 -4
- package/browser/Options/Classes/Particles/Opacity/Opacity.js +0 -21
- package/browser/Options/Classes/Particles/Opacity/OpacityAnimation.js +0 -20
- package/browser/Options/Classes/Particles/Size/Size.js +0 -21
- package/browser/Options/Classes/Particles/Size/SizeAnimation.js +0 -20
- package/browser/Options/Interfaces/Particles/Size/ISizeAnimation.js +0 -1
- package/cjs/Options/Classes/Particles/Opacity/Opacity.js +0 -21
- package/cjs/Options/Classes/Particles/Opacity/OpacityAnimation.js +0 -20
- package/cjs/Options/Classes/Particles/Size/Size.js +0 -21
- package/cjs/Options/Classes/Particles/Size/SizeAnimation.js +0 -20
- package/cjs/Options/Interfaces/Particles/Opacity/IOpacity.js +0 -1
- package/cjs/Options/Interfaces/Particles/Opacity/IOpacityAnimation.js +0 -1
- package/cjs/Options/Interfaces/Particles/Size/ISize.js +0 -1
- package/cjs/Options/Interfaces/Particles/Size/ISizeAnimation.js +0 -1
- package/esm/Options/Classes/Particles/Opacity/Opacity.js +0 -21
- package/esm/Options/Classes/Particles/Opacity/OpacityAnimation.js +0 -20
- package/esm/Options/Classes/Particles/Size/Size.js +0 -21
- package/esm/Options/Classes/Particles/Size/SizeAnimation.js +0 -20
- package/esm/Options/Interfaces/Particles/Opacity/IOpacity.js +0 -1
- package/esm/Options/Interfaces/Particles/Opacity/IOpacityAnimation.js +0 -1
- package/esm/Options/Interfaces/Particles/Size/ISize.js +0 -1
- package/esm/Options/Interfaces/Particles/Size/ISizeAnimation.js +0 -1
- package/types/Options/Classes/Particles/Opacity/Opacity.d.ts +0 -10
- package/types/Options/Classes/Particles/Opacity/OpacityAnimation.d.ts +0 -10
- package/types/Options/Classes/Particles/Size/Size.d.ts +0 -10
- package/types/Options/Classes/Particles/Size/SizeAnimation.d.ts +0 -10
- package/types/Options/Interfaces/Particles/Opacity/IOpacity.d.ts +0 -5
- package/types/Options/Interfaces/Particles/Opacity/IOpacityAnimation.d.ts +0 -5
- package/types/Options/Interfaces/Particles/Size/ISize.d.ts +0 -5
- package/types/Options/Interfaces/Particles/Size/ISizeAnimation.d.ts +0 -5
- /package/browser/{Options/Interfaces/Particles/Opacity/IOpacity.js → Core/Interfaces/IParticleCanvasBounds.js} +0 -0
- /package/{browser/Options/Interfaces/Particles/Opacity/IOpacityAnimation.js → cjs/Core/Interfaces/IParticleCanvasBounds.js} +0 -0
- /package/{browser/Options/Interfaces/Particles/Size/ISize.js → esm/Core/Interfaces/IParticleCanvasBounds.js} +0 -0
package/esm/Core/Engine.js
CHANGED
|
@@ -62,17 +62,17 @@ const getCanvasFromContainer = (domContainer) => {
|
|
|
62
62
|
};
|
|
63
63
|
export class Engine {
|
|
64
64
|
pluginManager = new PluginManager(this);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
#domArray = [];
|
|
66
|
+
#eventDispatcher = new EventDispatcher();
|
|
67
|
+
#initialized = false;
|
|
68
68
|
get items() {
|
|
69
|
-
return this
|
|
69
|
+
return this.#domArray;
|
|
70
70
|
}
|
|
71
71
|
get version() {
|
|
72
|
-
return "4.
|
|
72
|
+
return "4.1.1";
|
|
73
73
|
}
|
|
74
74
|
addEventListener(type, listener) {
|
|
75
|
-
this.
|
|
75
|
+
this.#eventDispatcher.addEventListener(type, listener);
|
|
76
76
|
}
|
|
77
77
|
checkVersion(pluginVersion) {
|
|
78
78
|
if (this.version === pluginVersion) {
|
|
@@ -81,17 +81,17 @@ export class Engine {
|
|
|
81
81
|
throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
|
|
82
82
|
}
|
|
83
83
|
dispatchEvent(type, args) {
|
|
84
|
-
this.
|
|
84
|
+
this.#eventDispatcher.dispatchEvent(type, args);
|
|
85
85
|
}
|
|
86
86
|
async init() {
|
|
87
|
-
if (this
|
|
87
|
+
if (this.#initialized) {
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
await this.pluginManager.init();
|
|
91
|
-
this
|
|
91
|
+
this.#initialized = true;
|
|
92
92
|
}
|
|
93
93
|
item(index) {
|
|
94
|
-
const
|
|
94
|
+
const items = this.items, item = items[index];
|
|
95
95
|
if (item?.destroyed) {
|
|
96
96
|
items.splice(index, removeDeleteCount);
|
|
97
97
|
return;
|
|
@@ -145,6 +145,6 @@ export class Engine {
|
|
|
145
145
|
await Promise.all(this.items.map(t => t.refresh()));
|
|
146
146
|
}
|
|
147
147
|
removeEventListener(type, listener) {
|
|
148
|
-
this.
|
|
148
|
+
this.#eventDispatcher.removeEventListener(type, listener);
|
|
149
149
|
}
|
|
150
150
|
}
|
package/esm/Core/Particle.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Vector, Vector3d } from "./Utils/Vectors.js";
|
|
2
2
|
import { alterHsl, getHslFromAnimation } from "../Utils/ColorUtils.js";
|
|
3
3
|
import { calcExactPositionOrRandomFromSize, clamp, degToRad, getParticleBaseVelocity, getParticleDirectionAngle, getRandom, getRangeValue, randomInRangeValue, setRangeValue, } from "../Utils/MathUtils.js";
|
|
4
|
-
import { deepExtend, getPosition,
|
|
4
|
+
import { deepExtend, getPosition, isInArray, itemFromSingleOrMultiple } from "../Utils/Utils.js";
|
|
5
5
|
import { defaultAngle, defaultOpacity, defaultRetryCount, defaultTransform, double, doublePI, half, identity, minZ, randomColorValue, squareExp, triple, tryCountIncrement, zIndexFactorOffset, } from "./Utils/Constants.js";
|
|
6
6
|
import { EventType } from "../Enums/Types/EventType.js";
|
|
7
7
|
import { MoveDirection } from "../Enums/Directions/MoveDirection.js";
|
|
8
8
|
import { OutMode } from "../Enums/Modes/OutMode.js";
|
|
9
|
+
import { OutModeDirection } from "../Enums/Directions/OutModeDirection.js";
|
|
9
10
|
import { ParticleOutType } from "../Enums/Types/ParticleOutType.js";
|
|
10
11
|
import { loadParticlesOptions } from "../Utils/OptionsUtils.js";
|
|
11
12
|
function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
|
|
@@ -76,24 +77,24 @@ export class Particle {
|
|
|
76
77
|
unbreakable;
|
|
77
78
|
velocity;
|
|
78
79
|
zIndexFactor;
|
|
79
|
-
|
|
80
|
+
#cachedOpacityData = {
|
|
80
81
|
fillOpacity: defaultOpacity,
|
|
81
82
|
opacity: defaultOpacity,
|
|
82
83
|
strokeOpacity: defaultOpacity,
|
|
83
84
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
#cachedPosition = Vector3d.origin;
|
|
86
|
+
#cachedRotateData = { sin: 0, cos: 0 };
|
|
87
|
+
#cachedTransform = {
|
|
87
88
|
a: 1,
|
|
88
89
|
b: 0,
|
|
89
90
|
c: 0,
|
|
90
91
|
d: 1,
|
|
91
92
|
};
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
#container;
|
|
94
|
+
#pluginManager;
|
|
94
95
|
constructor(pluginManager, container) {
|
|
95
|
-
this
|
|
96
|
-
this
|
|
96
|
+
this.#pluginManager = pluginManager;
|
|
97
|
+
this.#container = container;
|
|
97
98
|
}
|
|
98
99
|
destroy(override) {
|
|
99
100
|
if (this.unbreakable || this.destroyed) {
|
|
@@ -102,7 +103,7 @@ export class Particle {
|
|
|
102
103
|
this.destroyed = true;
|
|
103
104
|
this.bubble.inRange = false;
|
|
104
105
|
this.slow.inRange = false;
|
|
105
|
-
const container = this
|
|
106
|
+
const container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined;
|
|
106
107
|
shapeDrawer?.particleDestroy?.(this);
|
|
107
108
|
for (const plugin of container.particleDestroyedPlugins) {
|
|
108
109
|
plugin.particleDestroyed?.(this, override);
|
|
@@ -110,12 +111,12 @@ export class Particle {
|
|
|
110
111
|
for (const updater of container.particleUpdaters) {
|
|
111
112
|
updater.particleDestroyed?.(this, override);
|
|
112
113
|
}
|
|
113
|
-
this.
|
|
114
|
+
this.#container.dispatchEvent(EventType.particleDestroyed, {
|
|
114
115
|
particle: this,
|
|
115
116
|
});
|
|
116
117
|
}
|
|
117
118
|
draw(delta) {
|
|
118
|
-
const container = this
|
|
119
|
+
const container = this.#container, render = container.canvas.render;
|
|
119
120
|
render.drawParticlePlugins(this, delta);
|
|
120
121
|
render.drawParticle(this, delta);
|
|
121
122
|
}
|
|
@@ -123,50 +124,50 @@ export class Particle {
|
|
|
123
124
|
return this.rotation + (this.pathRotation ? this.velocity.angle : defaultAngle);
|
|
124
125
|
}
|
|
125
126
|
getFillColor() {
|
|
126
|
-
return this
|
|
127
|
+
return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.fillColor));
|
|
127
128
|
}
|
|
128
129
|
getMass() {
|
|
129
130
|
return this.getRadius() ** squareExp * Math.PI * half;
|
|
130
131
|
}
|
|
131
132
|
getOpacity() {
|
|
132
133
|
const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = this.bubble.opacity ?? getRangeValue(this.opacity?.value ?? defaultOpacity), fillOpacity = this.fillOpacity ?? defaultOpacity, strokeOpacity = this.strokeOpacity ?? defaultOpacity;
|
|
133
|
-
this.
|
|
134
|
-
this.
|
|
135
|
-
this.
|
|
136
|
-
return this
|
|
134
|
+
this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
|
|
135
|
+
this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
|
|
136
|
+
this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
|
|
137
|
+
return this.#cachedOpacityData;
|
|
137
138
|
}
|
|
138
139
|
getPosition() {
|
|
139
|
-
this.
|
|
140
|
-
this.
|
|
141
|
-
this.
|
|
142
|
-
return this
|
|
140
|
+
this.#cachedPosition.x = this.position.x + this.offset.x;
|
|
141
|
+
this.#cachedPosition.y = this.position.y + this.offset.y;
|
|
142
|
+
this.#cachedPosition.z = this.position.z;
|
|
143
|
+
return this.#cachedPosition;
|
|
143
144
|
}
|
|
144
145
|
getRadius() {
|
|
145
146
|
return this.bubble.radius ?? this.size.value;
|
|
146
147
|
}
|
|
147
148
|
getRotateData() {
|
|
148
149
|
const angle = this.getAngle();
|
|
149
|
-
this.
|
|
150
|
-
this.
|
|
151
|
-
return this
|
|
150
|
+
this.#cachedRotateData.sin = Math.sin(angle);
|
|
151
|
+
this.#cachedRotateData.cos = Math.cos(angle);
|
|
152
|
+
return this.#cachedRotateData;
|
|
152
153
|
}
|
|
153
154
|
getStrokeColor() {
|
|
154
|
-
return this
|
|
155
|
+
return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
|
|
155
156
|
}
|
|
156
157
|
getTransformData(externalTransform) {
|
|
157
158
|
const rotateData = this.getRotateData(), rotating = this.isRotating;
|
|
158
|
-
this.
|
|
159
|
-
this.
|
|
159
|
+
this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
|
|
160
|
+
this.#cachedTransform.b = rotating
|
|
160
161
|
? rotateData.sin * (externalTransform.b ?? identity)
|
|
161
162
|
: (externalTransform.b ?? defaultTransform.b);
|
|
162
|
-
this.
|
|
163
|
+
this.#cachedTransform.c = rotating
|
|
163
164
|
? -rotateData.sin * (externalTransform.c ?? identity)
|
|
164
165
|
: (externalTransform.c ?? defaultTransform.c);
|
|
165
|
-
this.
|
|
166
|
-
return this
|
|
166
|
+
this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
|
|
167
|
+
return this.#cachedTransform;
|
|
167
168
|
}
|
|
168
169
|
init(id, position, overrideOptions, group) {
|
|
169
|
-
const container = this
|
|
170
|
+
const container = this.#container;
|
|
170
171
|
this.id = id;
|
|
171
172
|
this.group = group;
|
|
172
173
|
this.justWarped = false;
|
|
@@ -186,21 +187,27 @@ export class Particle {
|
|
|
186
187
|
moveSpeed: 0,
|
|
187
188
|
sizeAnimationSpeed: 0,
|
|
188
189
|
};
|
|
190
|
+
this.size = {
|
|
191
|
+
value: 1,
|
|
192
|
+
max: 1,
|
|
193
|
+
min: 1,
|
|
194
|
+
enable: false,
|
|
195
|
+
};
|
|
189
196
|
this.outType = ParticleOutType.normal;
|
|
190
197
|
this.ignoresResizeRatio = true;
|
|
191
|
-
const
|
|
198
|
+
const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
|
|
192
199
|
this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
|
|
193
200
|
this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
|
|
194
201
|
const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
|
|
195
202
|
if (overrideOptions) {
|
|
196
|
-
if (overrideOptions.effect?.type) {
|
|
203
|
+
if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
|
|
197
204
|
const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
|
|
198
205
|
if (effect) {
|
|
199
206
|
this.effect = effect;
|
|
200
207
|
effectOptions.load(overrideOptions.effect);
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
|
-
if (overrideOptions.shape?.type) {
|
|
210
|
+
if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
|
|
204
211
|
const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
|
|
205
212
|
if (shape) {
|
|
206
213
|
this.shape = shape;
|
|
@@ -209,21 +216,20 @@ export class Particle {
|
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
if (this.effect === randomColorValue) {
|
|
212
|
-
const availableEffects = [...this.
|
|
219
|
+
const availableEffects = [...this.#container.effectDrawers.keys()];
|
|
213
220
|
this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
|
|
214
221
|
}
|
|
215
222
|
if (this.shape === randomColorValue) {
|
|
216
|
-
const availableShapes = [...this.
|
|
223
|
+
const availableShapes = [...this.#container.shapeDrawers.keys()];
|
|
217
224
|
this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
|
|
218
225
|
}
|
|
219
226
|
this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
|
|
220
227
|
this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
|
|
221
228
|
particlesOptions.load(overrideOptions);
|
|
222
|
-
const effectData = this.effectData;
|
|
229
|
+
const effectData = this.effectData, shapeData = this.shapeData;
|
|
223
230
|
if (effectData) {
|
|
224
231
|
particlesOptions.load(effectData.particles);
|
|
225
232
|
}
|
|
226
|
-
const shapeData = this.shapeData;
|
|
227
233
|
if (shapeData) {
|
|
228
234
|
particlesOptions.load(shapeData.particles);
|
|
229
235
|
}
|
|
@@ -231,7 +237,9 @@ export class Particle {
|
|
|
231
237
|
this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
|
|
232
238
|
this.options = particlesOptions;
|
|
233
239
|
container.retina.initParticle(this);
|
|
234
|
-
|
|
240
|
+
for (const updater of container.particleUpdaters) {
|
|
241
|
+
updater.preInit?.(this);
|
|
242
|
+
}
|
|
235
243
|
this.bubble = {
|
|
236
244
|
inRange: false,
|
|
237
245
|
};
|
|
@@ -239,8 +247,8 @@ export class Particle {
|
|
|
239
247
|
inRange: false,
|
|
240
248
|
factor: 1,
|
|
241
249
|
};
|
|
242
|
-
this
|
|
243
|
-
this.initialVelocity = this
|
|
250
|
+
this.#initPosition(position);
|
|
251
|
+
this.initialVelocity = this.#calculateVelocity();
|
|
244
252
|
this.velocity = this.initialVelocity.copy();
|
|
245
253
|
this.zIndexFactor = this.position.z / container.zLayers;
|
|
246
254
|
this.sides = 24;
|
|
@@ -271,12 +279,11 @@ export class Particle {
|
|
|
271
279
|
plugin.particleCreated?.(this);
|
|
272
280
|
}
|
|
273
281
|
}
|
|
274
|
-
isInsideCanvas() {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
position.x <= canvasSize.width + radius);
|
|
282
|
+
isInsideCanvas(direction) {
|
|
283
|
+
return this.#getInsideCanvasResult({ direction }).inside;
|
|
284
|
+
}
|
|
285
|
+
isInsideCanvasForOutMode(outMode, direction) {
|
|
286
|
+
return this.#getInsideCanvasResult({ direction, outMode }).inside;
|
|
280
287
|
}
|
|
281
288
|
isShowingBack() {
|
|
282
289
|
if (!this.roll) {
|
|
@@ -301,13 +308,13 @@ export class Particle {
|
|
|
301
308
|
return !this.destroyed && !this.spawning && this.isInsideCanvas();
|
|
302
309
|
}
|
|
303
310
|
reset() {
|
|
304
|
-
for (const updater of this.
|
|
311
|
+
for (const updater of this.#container.particleUpdaters) {
|
|
305
312
|
updater.reset?.(this);
|
|
306
313
|
}
|
|
307
314
|
}
|
|
308
|
-
|
|
315
|
+
#calcPosition = (position, zIndex) => {
|
|
309
316
|
let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
|
|
310
|
-
const container = this
|
|
317
|
+
const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
|
|
311
318
|
while (!signal.aborted) {
|
|
312
319
|
for (const plugin of plugins) {
|
|
313
320
|
const pluginPos = plugin.particlePosition?.(posVec, this);
|
|
@@ -319,10 +326,10 @@ export class Particle {
|
|
|
319
326
|
size: canvasSize,
|
|
320
327
|
position: posVec,
|
|
321
328
|
}), pos = Vector3d.create(exactPosition.x, exactPosition.y, zIndex);
|
|
322
|
-
this
|
|
323
|
-
this
|
|
324
|
-
this
|
|
325
|
-
this
|
|
329
|
+
this.#fixHorizontal(pos, radius, outModes.left ?? outModes.default);
|
|
330
|
+
this.#fixHorizontal(pos, radius, outModes.right ?? outModes.default);
|
|
331
|
+
this.#fixVertical(pos, radius, outModes.top ?? outModes.default);
|
|
332
|
+
this.#fixVertical(pos, radius, outModes.bottom ?? outModes.default);
|
|
326
333
|
let isValidPosition = true;
|
|
327
334
|
for (const plugin of container.particles.checkParticlePositionPlugins) {
|
|
328
335
|
isValidPosition = plugin.checkParticlePosition?.(this, pos, tryCount) ?? true;
|
|
@@ -338,8 +345,8 @@ export class Particle {
|
|
|
338
345
|
}
|
|
339
346
|
return posVec;
|
|
340
347
|
};
|
|
341
|
-
|
|
342
|
-
const baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy()
|
|
348
|
+
#calculateVelocity = () => {
|
|
349
|
+
const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
|
|
343
350
|
if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
|
|
344
351
|
return res;
|
|
345
352
|
}
|
|
@@ -355,27 +362,86 @@ export class Particle {
|
|
|
355
362
|
}
|
|
356
363
|
return res;
|
|
357
364
|
};
|
|
358
|
-
|
|
365
|
+
#fixHorizontal = (pos, radius, outMode) => {
|
|
359
366
|
fixOutMode({
|
|
360
367
|
outMode,
|
|
361
368
|
checkModes: [OutMode.bounce],
|
|
362
369
|
coord: pos.x,
|
|
363
|
-
maxCoord: this.
|
|
370
|
+
maxCoord: this.#container.canvas.size.width,
|
|
364
371
|
setCb: (value) => (pos.x += value),
|
|
365
372
|
radius,
|
|
366
373
|
});
|
|
367
374
|
};
|
|
368
|
-
|
|
375
|
+
#fixVertical = (pos, radius, outMode) => {
|
|
369
376
|
fixOutMode({
|
|
370
377
|
outMode,
|
|
371
378
|
checkModes: [OutMode.bounce],
|
|
372
379
|
coord: pos.y,
|
|
373
|
-
maxCoord: this.
|
|
380
|
+
maxCoord: this.#container.canvas.size.height,
|
|
374
381
|
setCb: (value) => (pos.y += value),
|
|
375
382
|
radius,
|
|
376
383
|
});
|
|
377
384
|
};
|
|
378
|
-
|
|
385
|
+
#getDefaultInsideCanvasResult = (direction, outMode) => {
|
|
386
|
+
const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
|
|
387
|
+
if (direction === OutModeDirection.bottom) {
|
|
388
|
+
return {
|
|
389
|
+
inside: isBounce ? position.y + radius < canvasSize.height : position.y - radius < canvasSize.height,
|
|
390
|
+
reason: "default",
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
if (direction === OutModeDirection.left) {
|
|
394
|
+
return {
|
|
395
|
+
inside: isBounce ? position.x - radius > defaultAngle : position.x + radius > defaultAngle,
|
|
396
|
+
reason: "default",
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (direction === OutModeDirection.right) {
|
|
400
|
+
return {
|
|
401
|
+
inside: isBounce ? position.x + radius < canvasSize.width : position.x - radius < canvasSize.width,
|
|
402
|
+
reason: "default",
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
if (direction === OutModeDirection.top) {
|
|
406
|
+
return {
|
|
407
|
+
inside: isBounce ? position.y - radius > defaultAngle : position.y + radius > defaultAngle,
|
|
408
|
+
reason: "default",
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
inside: position.x >= -radius &&
|
|
413
|
+
position.y >= -radius &&
|
|
414
|
+
position.y <= canvasSize.height + radius &&
|
|
415
|
+
position.x <= canvasSize.width + radius,
|
|
416
|
+
reason: "default",
|
|
417
|
+
};
|
|
418
|
+
};
|
|
419
|
+
#getInsideCanvasCallbackData = (direction, outMode) => {
|
|
420
|
+
return {
|
|
421
|
+
canvasSize: this.#container.canvas.size,
|
|
422
|
+
direction,
|
|
423
|
+
outMode,
|
|
424
|
+
particle: this,
|
|
425
|
+
radius: this.getRadius(),
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
#getInsideCanvasResult = (data) => {
|
|
429
|
+
const defaultResult = this.#getDefaultInsideCanvasResult(data.direction, data.outMode), container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined, effectDrawer = this.effect ? container.effectDrawers.get(this.effect) : undefined, shapeCheck = shapeDrawer?.isInsideCanvas, effectCheck = effectDrawer?.isInsideCanvas;
|
|
430
|
+
if (!shapeCheck && !effectCheck) {
|
|
431
|
+
return defaultResult;
|
|
432
|
+
}
|
|
433
|
+
const callbackData = this.#getInsideCanvasCallbackData(data.direction, data.outMode), shapeResult = shapeCheck ? this.#normalizeInsideCanvasResult(shapeCheck(callbackData), "shape") : undefined, effectResult = effectCheck ? this.#normalizeInsideCanvasResult(effectCheck(callbackData), "effect") : undefined;
|
|
434
|
+
if (shapeResult && effectResult) {
|
|
435
|
+
const margin = Math.max(shapeResult.margin ?? defaultAngle, effectResult.margin ?? defaultAngle);
|
|
436
|
+
return {
|
|
437
|
+
inside: shapeResult.inside && effectResult.inside,
|
|
438
|
+
margin: margin > defaultAngle ? margin : undefined,
|
|
439
|
+
reason: "combined",
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
return shapeResult ?? effectResult ?? defaultResult;
|
|
443
|
+
};
|
|
444
|
+
#getRollColor = color => {
|
|
379
445
|
if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
|
|
380
446
|
return color;
|
|
381
447
|
}
|
|
@@ -390,8 +456,8 @@ export class Particle {
|
|
|
390
456
|
}
|
|
391
457
|
return color;
|
|
392
458
|
};
|
|
393
|
-
|
|
394
|
-
const container = this
|
|
459
|
+
#initPosition = position => {
|
|
460
|
+
const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
|
|
395
461
|
if (!initialPosition) {
|
|
396
462
|
throw new Error("a valid position cannot be found for particle");
|
|
397
463
|
}
|
|
@@ -416,4 +482,17 @@ export class Particle {
|
|
|
416
482
|
}
|
|
417
483
|
this.offset = Vector.origin;
|
|
418
484
|
};
|
|
485
|
+
#normalizeInsideCanvasResult = (result, reason) => {
|
|
486
|
+
if (typeof result === "boolean") {
|
|
487
|
+
return {
|
|
488
|
+
inside: result,
|
|
489
|
+
reason,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
inside: result.inside,
|
|
494
|
+
margin: result.margin,
|
|
495
|
+
reason: result.reason ?? reason,
|
|
496
|
+
};
|
|
497
|
+
};
|
|
419
498
|
}
|