@tsparticles/engine 4.0.0-beta.9 → 4.0.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.
- package/browser/Core/CanvasManager.js +74 -37
- package/browser/Core/Engine.js +23 -8
- package/browser/Core/Particle.js +3 -3
- package/browser/Core/ParticlesManager.js +157 -78
- package/browser/Core/Retina.js +2 -3
- package/browser/Core/Utils/EventListeners.js +1 -1
- package/browser/Options/Classes/Particles/Fill.js +0 -2
- package/browser/Options/Classes/Particles/Paint.js +25 -0
- package/browser/Options/Classes/Particles/ParticlesOptions.js +54 -48
- package/browser/Utils/CanvasUtils.js +3 -3
- package/browser/Utils/LogUtils.js +32 -15
- package/browser/Utils/Utils.js +1 -0
- package/browser/browser.js +5 -0
- package/browser/exports.js +1 -0
- package/browser/index.js +0 -1
- package/cjs/Core/CanvasManager.js +74 -37
- package/cjs/Core/Engine.js +23 -8
- package/cjs/Core/Particle.js +3 -3
- package/cjs/Core/ParticlesManager.js +157 -78
- package/cjs/Core/Retina.js +2 -3
- package/cjs/Core/Utils/EventListeners.js +1 -1
- package/cjs/Options/Classes/Particles/Fill.js +0 -2
- package/cjs/Options/Classes/Particles/Paint.js +25 -0
- package/cjs/Options/Classes/Particles/ParticlesOptions.js +54 -48
- package/cjs/Utils/CanvasUtils.js +3 -3
- package/cjs/Utils/LogUtils.js +32 -15
- package/cjs/Utils/Utils.js +1 -0
- package/cjs/browser.js +5 -0
- package/cjs/exports.js +1 -0
- package/cjs/index.js +0 -1
- package/esm/Core/CanvasManager.js +74 -37
- package/esm/Core/Engine.js +23 -8
- package/esm/Core/Particle.js +3 -3
- package/esm/Core/ParticlesManager.js +157 -78
- package/esm/Core/Retina.js +2 -3
- package/esm/Core/Utils/EventListeners.js +1 -1
- package/esm/Options/Classes/Particles/Fill.js +0 -2
- package/esm/Options/Classes/Particles/Paint.js +25 -0
- package/esm/Options/Classes/Particles/ParticlesOptions.js +54 -48
- package/esm/Utils/CanvasUtils.js +3 -3
- package/esm/Utils/LogUtils.js +32 -15
- package/esm/Utils/Utils.js +1 -0
- package/esm/browser.js +5 -0
- package/esm/exports.js +1 -0
- package/esm/index.js +0 -1
- package/package.json +8 -1
- package/report.html +4949 -94
- package/scripts/install.js +321 -220
- package/tsparticles.engine.js +5293 -939
- package/tsparticles.engine.min.js +1 -2
- package/types/Core/CanvasManager.d.ts +3 -2
- package/types/Core/Container.d.ts +1 -2
- package/types/Core/Interfaces/IContainerPlugin.d.ts +7 -8
- package/types/Core/Interfaces/IDrawParticleParams.d.ts +1 -2
- package/types/Core/Interfaces/ILoadParams.d.ts +1 -1
- package/types/Core/Interfaces/IPalette.d.ts +4 -2
- package/types/Core/Interfaces/IParticleUpdater.d.ts +1 -2
- package/types/Core/Interfaces/IShapeDrawData.d.ts +1 -2
- package/types/Core/Particle.d.ts +1 -0
- package/types/Core/ParticlesManager.d.ts +11 -5
- package/types/Core/RenderManager.d.ts +2 -3
- package/types/Core/Utils/PluginManager.d.ts +5 -6
- package/types/Options/Classes/Options.d.ts +1 -2
- package/types/Options/Classes/Particles/Fill.d.ts +1 -1
- package/types/Options/Classes/Particles/Paint.d.ts +12 -0
- package/types/Options/Classes/Particles/ParticlesOptions.d.ts +2 -4
- package/types/Options/Interfaces/Particles/IPaint.d.ts +10 -0
- package/types/Options/Interfaces/Particles/IParticlesOptions.d.ts +2 -4
- package/types/Utils/CanvasUtils.d.ts +4 -5
- package/types/Utils/LogUtils.d.ts +2 -3
- package/types/Utils/Utils.d.ts +1 -2
- package/types/browser.d.ts +1 -0
- package/types/export-types.d.ts +1 -1
- package/types/exports.d.ts +1 -0
- package/types/{bundle.d.ts → index.lazy.d.ts} +1 -0
- package/67.min.js +0 -1
- package/dist_browser_Core_Container_js.js +0 -102
- package/types/Types/CanvasContextType.d.ts +0 -1
- /package/browser/{Types/CanvasContextType.js → Options/Interfaces/Particles/IPaint.js} +0 -0
- /package/browser/{bundle.js → index.lazy.js} +0 -0
- /package/cjs/{Types/CanvasContextType.js → Options/Interfaces/Particles/IPaint.js} +0 -0
- /package/cjs/{bundle.js → index.lazy.js} +0 -0
- /package/esm/{Types/CanvasContextType.js → Options/Interfaces/Particles/IPaint.js} +0 -0
- /package/esm/{bundle.js → index.lazy.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { countOffset, defaultDensityFactor, defaultRemoveQuantity, deleteCount,
|
|
1
|
+
import { countOffset, defaultDensityFactor, defaultRemoveQuantity, deleteCount, double, empty, minCount, minIndex, minLimit, one, spatialHashGridCellSize, squareExp, } from "./Utils/Constants.js";
|
|
2
2
|
import { EventType } from "../Enums/Types/EventType.js";
|
|
3
3
|
import { LimitMode } from "../Enums/Modes/LimitMode.js";
|
|
4
4
|
import { Particle } from "./Particle.js";
|
|
@@ -12,10 +12,8 @@ export class ParticlesManager {
|
|
|
12
12
|
_container;
|
|
13
13
|
_groupLimits;
|
|
14
14
|
_limit;
|
|
15
|
-
_maxZIndex;
|
|
16
|
-
_minZIndex;
|
|
17
|
-
_needsSort;
|
|
18
15
|
_nextId;
|
|
16
|
+
_particleBuckets;
|
|
19
17
|
_particleResetPlugins;
|
|
20
18
|
_particleUpdatePlugins;
|
|
21
19
|
_pluginManager;
|
|
@@ -24,19 +22,17 @@ export class ParticlesManager {
|
|
|
24
22
|
_postUpdatePlugins;
|
|
25
23
|
_resizeFactor;
|
|
26
24
|
_updatePlugins;
|
|
27
|
-
|
|
25
|
+
_zBuckets;
|
|
28
26
|
constructor(pluginManager, container) {
|
|
29
27
|
this._pluginManager = pluginManager;
|
|
30
28
|
this._container = container;
|
|
31
29
|
this._nextId = 0;
|
|
32
30
|
this._array = [];
|
|
33
|
-
this._zArray = [];
|
|
34
31
|
this._pool = [];
|
|
35
32
|
this._limit = 0;
|
|
36
33
|
this._groupLimits = new Map();
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
39
|
-
this._maxZIndex = 0;
|
|
34
|
+
this._particleBuckets = new Map();
|
|
35
|
+
this._zBuckets = this._createBuckets(this._container.zLayers);
|
|
40
36
|
this.grid = new SpatialHashGrid(spatialHashGridCellSize);
|
|
41
37
|
this.checkParticlePositionPlugins = [];
|
|
42
38
|
this._particleResetPlugins = [];
|
|
@@ -80,7 +76,7 @@ export class ParticlesManager {
|
|
|
80
76
|
return;
|
|
81
77
|
}
|
|
82
78
|
this._array.push(particle);
|
|
83
|
-
this.
|
|
79
|
+
this._insertParticleIntoBucket(particle);
|
|
84
80
|
this._nextId++;
|
|
85
81
|
this._container.dispatchEvent(EventType.particleAdded, {
|
|
86
82
|
particle,
|
|
@@ -94,12 +90,14 @@ export class ParticlesManager {
|
|
|
94
90
|
}
|
|
95
91
|
clear() {
|
|
96
92
|
this._array = [];
|
|
97
|
-
this.
|
|
93
|
+
this._particleBuckets.clear();
|
|
94
|
+
this._resetBuckets(this._container.zLayers);
|
|
98
95
|
}
|
|
99
96
|
destroy() {
|
|
100
97
|
this._array = [];
|
|
101
98
|
this._pool.length = 0;
|
|
102
|
-
this.
|
|
99
|
+
this._particleBuckets.clear();
|
|
100
|
+
this._zBuckets = [];
|
|
103
101
|
this.checkParticlePositionPlugins = [];
|
|
104
102
|
this._particleResetPlugins = [];
|
|
105
103
|
this._particleUpdatePlugins = [];
|
|
@@ -108,8 +106,14 @@ export class ParticlesManager {
|
|
|
108
106
|
this._updatePlugins = [];
|
|
109
107
|
}
|
|
110
108
|
drawParticles(delta) {
|
|
111
|
-
for (
|
|
112
|
-
|
|
109
|
+
for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
|
|
110
|
+
const bucket = this._zBuckets[i];
|
|
111
|
+
if (!bucket) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
for (const particle of bucket) {
|
|
115
|
+
particle.draw(delta);
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
filter(condition) {
|
|
@@ -123,15 +127,14 @@ export class ParticlesManager {
|
|
|
123
127
|
}
|
|
124
128
|
async init() {
|
|
125
129
|
const container = this._container, options = container.actualOptions;
|
|
126
|
-
this._minZIndex = 0;
|
|
127
|
-
this._maxZIndex = 0;
|
|
128
|
-
this._needsSort = false;
|
|
129
130
|
this.checkParticlePositionPlugins = [];
|
|
130
131
|
this._updatePlugins = [];
|
|
131
132
|
this._particleUpdatePlugins = [];
|
|
132
133
|
this._postUpdatePlugins = [];
|
|
133
134
|
this._particleResetPlugins = [];
|
|
134
135
|
this._postParticleUpdatePlugins = [];
|
|
136
|
+
this._particleBuckets.clear();
|
|
137
|
+
this._resetBuckets(container.zLayers);
|
|
135
138
|
this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
|
|
136
139
|
for (const plugin of container.plugins) {
|
|
137
140
|
if (plugin.redrawInit) {
|
|
@@ -232,79 +235,25 @@ export class ParticlesManager {
|
|
|
232
235
|
}
|
|
233
236
|
this._applyDensity(options.particles, pluginsCount);
|
|
234
237
|
}
|
|
235
|
-
setLastZIndex(zIndex) {
|
|
236
|
-
this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
|
|
237
|
-
}
|
|
238
238
|
setResizeFactor(factor) {
|
|
239
239
|
this._resizeFactor = factor;
|
|
240
240
|
}
|
|
241
241
|
update(delta) {
|
|
242
|
-
const particlesToDelete = new Set();
|
|
243
242
|
this.grid.clear();
|
|
244
243
|
for (const plugin of this._updatePlugins) {
|
|
245
244
|
plugin.update?.(delta);
|
|
246
245
|
}
|
|
247
|
-
const
|
|
248
|
-
for (const particle of this._array) {
|
|
249
|
-
if (resizeFactor && !particle.ignoresResizeRatio) {
|
|
250
|
-
particle.position.x *= resizeFactor.width;
|
|
251
|
-
particle.position.y *= resizeFactor.height;
|
|
252
|
-
particle.initialPosition.x *= resizeFactor.width;
|
|
253
|
-
particle.initialPosition.y *= resizeFactor.height;
|
|
254
|
-
}
|
|
255
|
-
particle.ignoresResizeRatio = false;
|
|
256
|
-
for (const plugin of this._particleResetPlugins) {
|
|
257
|
-
plugin.particleReset?.(particle);
|
|
258
|
-
}
|
|
259
|
-
for (const plugin of this._particleUpdatePlugins) {
|
|
260
|
-
if (particle.destroyed) {
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
plugin.particleUpdate?.(particle, delta);
|
|
264
|
-
}
|
|
265
|
-
if (particle.destroyed) {
|
|
266
|
-
particlesToDelete.add(particle);
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
this.grid.insert(particle);
|
|
270
|
-
}
|
|
246
|
+
const particlesToDelete = this._updateParticlesPhase1(delta);
|
|
271
247
|
for (const plugin of this._postUpdatePlugins) {
|
|
272
248
|
plugin.postUpdate?.(delta);
|
|
273
249
|
}
|
|
274
|
-
|
|
275
|
-
if (particle.destroyed) {
|
|
276
|
-
particlesToDelete.add(particle);
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
for (const updater of this._container.particleUpdaters) {
|
|
280
|
-
updater.update(particle, delta);
|
|
281
|
-
}
|
|
282
|
-
if (!particle.destroyed && !particle.spawning) {
|
|
283
|
-
for (const plugin of this._postParticleUpdatePlugins) {
|
|
284
|
-
plugin.postParticleUpdate?.(particle, delta);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
else if (particle.destroyed) {
|
|
288
|
-
particlesToDelete.add(particle);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
250
|
+
this._updateParticlesPhase2(delta, particlesToDelete);
|
|
291
251
|
if (particlesToDelete.size) {
|
|
292
252
|
for (const particle of particlesToDelete) {
|
|
293
253
|
this.remove(particle);
|
|
294
254
|
}
|
|
295
255
|
}
|
|
296
256
|
delete this._resizeFactor;
|
|
297
|
-
if (this._needsSort) {
|
|
298
|
-
const zArray = this._zArray;
|
|
299
|
-
zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
|
|
300
|
-
const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
|
|
301
|
-
if (!firstItem || !lastItem) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
this._maxZIndex = firstItem.position.z;
|
|
305
|
-
this._minZIndex = lastItem.position.z;
|
|
306
|
-
this._needsSort = false;
|
|
307
|
-
}
|
|
308
257
|
}
|
|
309
258
|
_addToPool = (...particles) => {
|
|
310
259
|
this._pool.push(...particles);
|
|
@@ -334,13 +283,52 @@ export class ParticlesManager {
|
|
|
334
283
|
this.removeQuantity(particlesCount - particlesNumber, group);
|
|
335
284
|
}
|
|
336
285
|
};
|
|
286
|
+
_createBuckets = (zLayers) => {
|
|
287
|
+
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
288
|
+
return Array.from({ length: bucketCount }, () => []);
|
|
289
|
+
};
|
|
290
|
+
_getBucketIndex = (zIndex) => {
|
|
291
|
+
const maxBucketIndex = this._zBuckets.length - one;
|
|
292
|
+
if (maxBucketIndex <= minIndex) {
|
|
293
|
+
return minIndex;
|
|
294
|
+
}
|
|
295
|
+
return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
|
|
296
|
+
};
|
|
297
|
+
_getParticleInsertIndex = (bucket, particleId) => {
|
|
298
|
+
let start = minIndex, end = bucket.length;
|
|
299
|
+
while (start < end) {
|
|
300
|
+
const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
|
|
301
|
+
if (!middleParticle) {
|
|
302
|
+
end = middle;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (middleParticle.id < particleId) {
|
|
306
|
+
start = middle + one;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
end = middle;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return start;
|
|
313
|
+
};
|
|
337
314
|
_initDensityFactor = densityOptions => {
|
|
338
315
|
const container = this._container;
|
|
339
|
-
if (!
|
|
316
|
+
if (!densityOptions.enable) {
|
|
340
317
|
return defaultDensityFactor;
|
|
341
318
|
}
|
|
342
|
-
const
|
|
343
|
-
|
|
319
|
+
const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
|
|
320
|
+
if (!canvasSize.width || !canvasSize.height) {
|
|
321
|
+
return defaultDensityFactor;
|
|
322
|
+
}
|
|
323
|
+
return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
|
|
324
|
+
};
|
|
325
|
+
_insertParticleIntoBucket = (particle) => {
|
|
326
|
+
const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
|
|
327
|
+
if (!bucket) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
|
|
331
|
+
this._particleBuckets.set(particle.id, bucketIndex);
|
|
344
332
|
};
|
|
345
333
|
_removeParticle = (index, group, override) => {
|
|
346
334
|
const particle = this._array[index];
|
|
@@ -350,9 +338,8 @@ export class ParticlesManager {
|
|
|
350
338
|
if (particle.group !== group) {
|
|
351
339
|
return false;
|
|
352
340
|
}
|
|
353
|
-
const zIdx = this._zArray.indexOf(particle);
|
|
354
341
|
this._array.splice(index, deleteCount);
|
|
355
|
-
this.
|
|
342
|
+
this._removeParticleFromBucket(particle);
|
|
356
343
|
particle.destroy(override);
|
|
357
344
|
this._container.dispatchEvent(EventType.particleRemoved, {
|
|
358
345
|
particle,
|
|
@@ -360,4 +347,96 @@ export class ParticlesManager {
|
|
|
360
347
|
this._addToPool(particle);
|
|
361
348
|
return true;
|
|
362
349
|
};
|
|
350
|
+
_removeParticleFromBucket = (particle) => {
|
|
351
|
+
const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
|
|
352
|
+
if (!bucket) {
|
|
353
|
+
this._particleBuckets.delete(particle.id);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
|
|
357
|
+
if (bucket[particleIndex]?.id !== particle.id) {
|
|
358
|
+
this._particleBuckets.delete(particle.id);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
bucket.splice(particleIndex, deleteCount);
|
|
362
|
+
this._particleBuckets.delete(particle.id);
|
|
363
|
+
};
|
|
364
|
+
_resetBuckets = (zLayers) => {
|
|
365
|
+
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
366
|
+
if (this._zBuckets.length !== bucketCount) {
|
|
367
|
+
this._zBuckets = this._createBuckets(bucketCount);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
for (const bucket of this._zBuckets) {
|
|
371
|
+
bucket.length = minIndex;
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
_updateParticleBucket = (particle) => {
|
|
375
|
+
const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
|
|
376
|
+
if (currentBucketIndex === undefined) {
|
|
377
|
+
this._insertParticleIntoBucket(particle);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (currentBucketIndex === newBucketIndex) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const currentBucket = this._zBuckets[currentBucketIndex];
|
|
384
|
+
if (currentBucket) {
|
|
385
|
+
const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
|
|
386
|
+
if (currentBucket[particleIndex]?.id === particle.id) {
|
|
387
|
+
currentBucket.splice(particleIndex, deleteCount);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const newBucket = this._zBuckets[newBucketIndex];
|
|
391
|
+
if (!newBucket) {
|
|
392
|
+
this._particleBuckets.set(particle.id, newBucketIndex);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
|
|
396
|
+
this._particleBuckets.set(particle.id, newBucketIndex);
|
|
397
|
+
};
|
|
398
|
+
_updateParticlesPhase1 = (delta) => {
|
|
399
|
+
const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
|
|
400
|
+
for (const particle of this._array) {
|
|
401
|
+
if (resizeFactor && !particle.ignoresResizeRatio) {
|
|
402
|
+
particle.position.x *= resizeFactor.width;
|
|
403
|
+
particle.position.y *= resizeFactor.height;
|
|
404
|
+
particle.initialPosition.x *= resizeFactor.width;
|
|
405
|
+
particle.initialPosition.y *= resizeFactor.height;
|
|
406
|
+
}
|
|
407
|
+
particle.ignoresResizeRatio = false;
|
|
408
|
+
for (const plugin of this._particleResetPlugins) {
|
|
409
|
+
plugin.particleReset?.(particle);
|
|
410
|
+
}
|
|
411
|
+
for (const plugin of this._particleUpdatePlugins) {
|
|
412
|
+
if (particle.destroyed) {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
plugin.particleUpdate?.(particle, delta);
|
|
416
|
+
}
|
|
417
|
+
if (particle.destroyed) {
|
|
418
|
+
particlesToDelete.add(particle);
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
this.grid.insert(particle);
|
|
422
|
+
}
|
|
423
|
+
return particlesToDelete;
|
|
424
|
+
};
|
|
425
|
+
_updateParticlesPhase2 = (delta, particlesToDelete) => {
|
|
426
|
+
for (const particle of this._array) {
|
|
427
|
+
if (particle.destroyed) {
|
|
428
|
+
particlesToDelete.add(particle);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
for (const updater of this._container.particleUpdaters) {
|
|
432
|
+
updater.update(particle, delta);
|
|
433
|
+
}
|
|
434
|
+
if (!particle.spawning) {
|
|
435
|
+
for (const plugin of this._postParticleUpdatePlugins) {
|
|
436
|
+
plugin.postParticleUpdate?.(particle, delta);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
this._updateParticleBucket(particle);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
363
442
|
}
|
package/cjs/Core/Retina.js
CHANGED
|
@@ -13,9 +13,8 @@ export class Retina {
|
|
|
13
13
|
const container = this.container, options = container.actualOptions;
|
|
14
14
|
this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
|
|
15
15
|
this.reduceFactor = defaultReduceFactor;
|
|
16
|
-
const ratio = this.pixelRatio, canvas = container.canvas;
|
|
17
|
-
if (
|
|
18
|
-
const element = canvas.element;
|
|
16
|
+
const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
|
|
17
|
+
if (element) {
|
|
19
18
|
canvas.size.width = element.offsetWidth * ratio;
|
|
20
19
|
canvas.size.height = element.offsetHeight * ratio;
|
|
21
20
|
}
|
|
@@ -66,7 +66,7 @@ export class EventListeners {
|
|
|
66
66
|
manageListener(globalThis, resizeEvent, handlers.resize, add);
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
const canvasEl = container.canvas.
|
|
69
|
+
const canvasEl = container.canvas.domElement;
|
|
70
70
|
if (this._resizeObserver && !add) {
|
|
71
71
|
if (canvasEl) {
|
|
72
72
|
this._resizeObserver.unobserve(canvasEl);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AnimatableColor } from "../AnimatableColor.js";
|
|
2
|
+
import { Fill } from "./Fill.js";
|
|
3
|
+
import { Stroke } from "./Stroke.js";
|
|
4
|
+
import { isNull } from "../../../Utils/TypeUtils.js";
|
|
5
|
+
export class Paint {
|
|
6
|
+
color;
|
|
7
|
+
fill;
|
|
8
|
+
stroke;
|
|
9
|
+
load(data) {
|
|
10
|
+
if (isNull(data)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (data.color !== undefined) {
|
|
14
|
+
this.color = AnimatableColor.create(this.color, data.color);
|
|
15
|
+
}
|
|
16
|
+
if (data.fill !== undefined) {
|
|
17
|
+
this.fill ??= new Fill();
|
|
18
|
+
this.fill.load(data.fill);
|
|
19
|
+
}
|
|
20
|
+
if (data.stroke !== undefined) {
|
|
21
|
+
this.stroke ??= new Stroke();
|
|
22
|
+
this.stroke.load(data.stroke);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { deepExtend, executeOnSingleOrMultiple } from "../../../Utils/Utils.js";
|
|
2
2
|
import { isArray, isNull } from "../../../Utils/TypeUtils.js";
|
|
3
|
+
import { AnimatableColor } from "../AnimatableColor.js";
|
|
3
4
|
import { Effect } from "./Effect/Effect.js";
|
|
4
5
|
import { Fill } from "./Fill.js";
|
|
5
6
|
import { Move } from "./Move/Move.js";
|
|
6
7
|
import { Opacity } from "./Opacity/Opacity.js";
|
|
8
|
+
import { Paint } from "./Paint.js";
|
|
7
9
|
import { ParticlesBounce } from "./Bounce/ParticlesBounce.js";
|
|
8
10
|
import { ParticlesNumber } from "./Number/ParticlesNumber.js";
|
|
9
11
|
import { Shape } from "./Shape/Shape.js";
|
|
10
12
|
import { Size } from "./Size/Size.js";
|
|
11
|
-
import { Stroke } from "./Stroke.js";
|
|
12
13
|
import { ZIndex } from "./ZIndex/ZIndex.js";
|
|
13
14
|
export class ParticlesOptions {
|
|
14
15
|
bounce;
|
|
15
16
|
effect;
|
|
16
|
-
fill;
|
|
17
17
|
groups;
|
|
18
18
|
move;
|
|
19
19
|
number;
|
|
20
20
|
opacity;
|
|
21
|
+
paint;
|
|
21
22
|
palette;
|
|
22
23
|
reduceDuplicates;
|
|
23
24
|
shape;
|
|
24
25
|
size;
|
|
25
|
-
stroke;
|
|
26
26
|
zIndex;
|
|
27
27
|
_container;
|
|
28
28
|
_pluginManager;
|
|
@@ -31,15 +31,18 @@ export class ParticlesOptions {
|
|
|
31
31
|
this._container = container;
|
|
32
32
|
this.bounce = new ParticlesBounce();
|
|
33
33
|
this.effect = new Effect();
|
|
34
|
-
this.fill = new Fill();
|
|
35
34
|
this.groups = {};
|
|
36
35
|
this.move = new Move();
|
|
37
36
|
this.number = new ParticlesNumber();
|
|
38
37
|
this.opacity = new Opacity();
|
|
38
|
+
this.paint = new Paint();
|
|
39
|
+
this.paint.color = new AnimatableColor();
|
|
40
|
+
this.paint.color.value = "#fff";
|
|
41
|
+
this.paint.fill = new Fill();
|
|
42
|
+
this.paint.fill.enable = true;
|
|
39
43
|
this.reduceDuplicates = false;
|
|
40
44
|
this.shape = new Shape();
|
|
41
45
|
this.size = new Size();
|
|
42
|
-
this.stroke = new Stroke();
|
|
43
46
|
this.zIndex = new ZIndex();
|
|
44
47
|
}
|
|
45
48
|
load(data) {
|
|
@@ -69,25 +72,26 @@ export class ParticlesOptions {
|
|
|
69
72
|
this.move.load(data.move);
|
|
70
73
|
this.number.load(data.number);
|
|
71
74
|
this.opacity.load(data.opacity);
|
|
75
|
+
const paintToLoad = data.paint;
|
|
76
|
+
if (paintToLoad) {
|
|
77
|
+
if (isArray(paintToLoad)) {
|
|
78
|
+
this.paint = executeOnSingleOrMultiple(paintToLoad, t => {
|
|
79
|
+
const tmp = new Paint();
|
|
80
|
+
tmp.load(t);
|
|
81
|
+
return tmp;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (isArray(this.paint)) {
|
|
85
|
+
this.paint = new Paint();
|
|
86
|
+
this.paint.load(paintToLoad);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.paint.load(paintToLoad);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
72
92
|
this.shape.load(data.shape);
|
|
73
93
|
this.size.load(data.size);
|
|
74
94
|
this.zIndex.load(data.zIndex);
|
|
75
|
-
const fillToLoad = data.fill;
|
|
76
|
-
if (fillToLoad) {
|
|
77
|
-
this.fill = executeOnSingleOrMultiple(fillToLoad, t => {
|
|
78
|
-
const tmp = new Fill();
|
|
79
|
-
tmp.load(t);
|
|
80
|
-
return tmp;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
const strokeToLoad = data.stroke;
|
|
84
|
-
if (strokeToLoad) {
|
|
85
|
-
this.stroke = executeOnSingleOrMultiple(strokeToLoad, t => {
|
|
86
|
-
const tmp = new Stroke();
|
|
87
|
-
tmp.load(t);
|
|
88
|
-
return tmp;
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
95
|
if (this._container) {
|
|
92
96
|
for (const plugin of this._pluginManager.plugins) {
|
|
93
97
|
if (plugin.loadParticlesOptions) {
|
|
@@ -109,38 +113,40 @@ export class ParticlesOptions {
|
|
|
109
113
|
if (!paletteData) {
|
|
110
114
|
return;
|
|
111
115
|
}
|
|
112
|
-
const paletteColors = paletteData.colors,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
paletteFillObj = {
|
|
116
|
-
color: {
|
|
117
|
-
value: paletteFill.value,
|
|
118
|
-
},
|
|
119
|
-
enable: paletteFill.enable,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
let paletteStrokeObj = undefined;
|
|
123
|
-
if (paletteStroke) {
|
|
124
|
-
if (isArray(paletteStroke)) {
|
|
125
|
-
paletteStrokeObj = paletteStroke.map(s => ({
|
|
116
|
+
const paletteColors = paletteData.colors, defaultPaintStrokeWidth = 0, defaultPaintVariantsLength = 1, firstPaintVariantIndex = 0, defaultPalettePaintVariant = {}, colorVariants = isArray(paletteColors) ? paletteColors : [paletteColors], palettePaintVariants = colorVariants.flatMap(variant => {
|
|
117
|
+
const paletteFill = variant.fill, paletteStroke = variant.stroke, fillPart = paletteFill
|
|
118
|
+
? {
|
|
126
119
|
color: {
|
|
127
|
-
value:
|
|
120
|
+
value: paletteFill.value,
|
|
128
121
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
122
|
+
enable: paletteFill.enable,
|
|
123
|
+
opacity: paletteFill.opacity,
|
|
124
|
+
}
|
|
125
|
+
: undefined;
|
|
126
|
+
if (!paletteStroke) {
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
fill: fillPart,
|
|
136
130
|
},
|
|
137
|
-
|
|
138
|
-
};
|
|
131
|
+
];
|
|
139
132
|
}
|
|
140
|
-
|
|
133
|
+
return [
|
|
134
|
+
{
|
|
135
|
+
fill: fillPart,
|
|
136
|
+
stroke: {
|
|
137
|
+
color: {
|
|
138
|
+
value: paletteStroke.value,
|
|
139
|
+
},
|
|
140
|
+
opacity: paletteStroke.opacity,
|
|
141
|
+
width: paletteStroke.width || defaultPaintStrokeWidth,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
}), palettePaint = palettePaintVariants.length > defaultPaintVariantsLength
|
|
146
|
+
? palettePaintVariants
|
|
147
|
+
: (palettePaintVariants[firstPaintVariantIndex] ?? defaultPalettePaintVariant);
|
|
141
148
|
this.load({
|
|
142
|
-
|
|
143
|
-
stroke: paletteStrokeObj,
|
|
149
|
+
paint: palettePaint,
|
|
144
150
|
blend: {
|
|
145
151
|
enable: true,
|
|
146
152
|
mode: paletteData.blendMode,
|
package/cjs/Utils/CanvasUtils.js
CHANGED
|
@@ -88,12 +88,12 @@ export function drawShape(drawer, data) {
|
|
|
88
88
|
if (particle.shapeClose) {
|
|
89
89
|
context.closePath();
|
|
90
90
|
}
|
|
91
|
-
if (stroke) {
|
|
92
|
-
context.stroke();
|
|
93
|
-
}
|
|
94
91
|
if (fill) {
|
|
95
92
|
context.fill();
|
|
96
93
|
}
|
|
94
|
+
if (stroke) {
|
|
95
|
+
context.stroke();
|
|
96
|
+
}
|
|
97
97
|
}
|
|
98
98
|
export function drawShapeAfterDraw(drawer, data) {
|
|
99
99
|
if (!drawer?.afterDraw) {
|
package/cjs/Utils/LogUtils.js
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
const errorPrefix = "tsParticles - Error";
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
const wrap = (fn) => (...args) => {
|
|
3
|
+
fn(...args);
|
|
4
|
+
}, _logger = {
|
|
5
|
+
debug: wrap(console.debug),
|
|
6
|
+
error: (message, ...optionalParams) => {
|
|
7
|
+
console.error(`${errorPrefix} - ${message}`, ...optionalParams);
|
|
6
8
|
},
|
|
7
|
-
info: console.info,
|
|
8
|
-
log: console.log,
|
|
9
|
-
trace: console.trace,
|
|
10
|
-
verbose: console.log,
|
|
11
|
-
warning: console.warn,
|
|
9
|
+
info: wrap(console.info),
|
|
10
|
+
log: wrap(console.log),
|
|
11
|
+
trace: wrap(console.trace),
|
|
12
|
+
verbose: wrap(console.log),
|
|
13
|
+
warning: wrap(console.warn),
|
|
12
14
|
};
|
|
13
15
|
export function setLogger(logger) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (logger.debug) {
|
|
17
|
+
_logger.debug = wrap(logger.debug);
|
|
18
|
+
}
|
|
19
|
+
if (logger.error) {
|
|
20
|
+
_logger.error = wrap(logger.error);
|
|
21
|
+
}
|
|
22
|
+
if (logger.info) {
|
|
23
|
+
_logger.info = wrap(logger.info);
|
|
24
|
+
}
|
|
25
|
+
if (logger.log) {
|
|
26
|
+
_logger.log = wrap(logger.log);
|
|
27
|
+
}
|
|
28
|
+
if (logger.trace) {
|
|
29
|
+
_logger.trace = wrap(logger.trace);
|
|
30
|
+
}
|
|
31
|
+
if (logger.verbose) {
|
|
32
|
+
_logger.verbose = wrap(logger.verbose);
|
|
33
|
+
}
|
|
34
|
+
if (logger.warning) {
|
|
35
|
+
_logger.warning = wrap(logger.warning);
|
|
36
|
+
}
|
|
20
37
|
}
|
|
21
38
|
export function getLogger() {
|
|
22
39
|
return _logger;
|
package/cjs/Utils/Utils.js
CHANGED
package/cjs/browser.js
ADDED
package/cjs/exports.js
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./Options/Classes/Particles/Bounce/ParticlesBounce.js";
|
|
|
28
28
|
export * from "./Options/Classes/Particles/Bounce/ParticlesBounceFactor.js";
|
|
29
29
|
export * from "./Options/Classes/Particles/ParticlesOptions.js";
|
|
30
30
|
export * from "./Options/Classes/Particles/Fill.js";
|
|
31
|
+
export * from "./Options/Classes/Particles/Paint.js";
|
|
31
32
|
export * from "./Options/Classes/Particles/Stroke.js";
|
|
32
33
|
export * from "./Options/Classes/Particles/Move/Move.js";
|
|
33
34
|
export * from "./Options/Classes/Particles/Move/MoveAngle.js";
|