@tsparticles/engine 4.0.0-beta.16 → 4.0.0-beta.17
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 +73 -36
- package/browser/Core/Engine.js +11 -5
- package/browser/Core/Particle.js +1 -3
- package/browser/Core/ParticlesManager.js +157 -78
- package/browser/Core/Retina.js +2 -3
- package/browser/Core/Utils/EventListeners.js +1 -1
- package/cjs/Core/CanvasManager.js +73 -36
- package/cjs/Core/Engine.js +11 -5
- package/cjs/Core/Particle.js +1 -3
- package/cjs/Core/ParticlesManager.js +157 -78
- package/cjs/Core/Retina.js +2 -3
- package/cjs/Core/Utils/EventListeners.js +1 -1
- package/esm/Core/CanvasManager.js +73 -36
- package/esm/Core/Engine.js +11 -5
- package/esm/Core/Particle.js +1 -3
- package/esm/Core/ParticlesManager.js +157 -78
- package/esm/Core/Retina.js +2 -3
- package/esm/Core/Utils/EventListeners.js +1 -1
- package/package.json +1 -1
- package/report.html +1 -1
- package/scripts/install.js +321 -220
- package/tsparticles.engine.js +245 -126
- package/tsparticles.engine.min.js +1 -1
- 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/IParticleUpdater.d.ts +1 -2
- package/types/Core/Interfaces/IShapeDrawData.d.ts +1 -2
- 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/Utils/CanvasUtils.d.ts +4 -5
- package/types/Utils/LogUtils.d.ts +1 -2
- package/types/Utils/Utils.d.ts +1 -2
- package/types/export-types.d.ts +0 -1
- package/browser/Types/CanvasContextType.js +0 -1
- package/cjs/Types/CanvasContextType.js +0 -1
- package/esm/Types/CanvasContextType.js +0 -1
- package/types/Types/CanvasContextType.d.ts +0 -1
package/tsparticles.engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
|
|
2
|
-
/* tsParticles Engine v4.0.0-beta.
|
|
2
|
+
/* tsParticles Engine v4.0.0-beta.17 */
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
5
5
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
@@ -1081,7 +1081,7 @@
|
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
1083
1083
|
else {
|
|
1084
|
-
const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases
|
|
1084
|
+
const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
|
|
1085
1085
|
if (foundCanvas) {
|
|
1086
1086
|
canvasEl = foundCanvas;
|
|
1087
1087
|
canvasEl.dataset[generatedAttribute] = generatedFalse;
|
|
@@ -1118,7 +1118,7 @@
|
|
|
1118
1118
|
return this._domArray;
|
|
1119
1119
|
}
|
|
1120
1120
|
get version() {
|
|
1121
|
-
return "4.0.0-beta.
|
|
1121
|
+
return "4.0.0-beta.17";
|
|
1122
1122
|
}
|
|
1123
1123
|
addEventListener(type, listener) {
|
|
1124
1124
|
this._eventDispatcher.addEventListener(type, listener);
|
|
@@ -1149,7 +1149,11 @@
|
|
|
1149
1149
|
}
|
|
1150
1150
|
async load(params) {
|
|
1151
1151
|
await this.init();
|
|
1152
|
-
|
|
1152
|
+
let domSourceElement;
|
|
1153
|
+
if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
|
|
1154
|
+
domSourceElement = params.element;
|
|
1155
|
+
}
|
|
1156
|
+
const { Container } = await Promise.resolve().then(function () { return Container$1; }), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
|
|
1153
1157
|
dispatchCallback: (eventType, args) => {
|
|
1154
1158
|
this.dispatchEvent(eventType, args);
|
|
1155
1159
|
},
|
|
@@ -1176,8 +1180,10 @@
|
|
|
1176
1180
|
else {
|
|
1177
1181
|
items.push(newItem);
|
|
1178
1182
|
}
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1183
|
+
const sourceCanvas = typeof OffscreenCanvas !== "undefined" && params.element instanceof OffscreenCanvas
|
|
1184
|
+
? params.element
|
|
1185
|
+
: getCanvasFromContainer(getDomContainer(id, domSourceElement));
|
|
1186
|
+
newItem.canvas.loadCanvas(sourceCanvas);
|
|
1181
1187
|
await newItem.start();
|
|
1182
1188
|
return newItem;
|
|
1183
1189
|
}
|
|
@@ -3308,6 +3314,25 @@
|
|
|
3308
3314
|
};
|
|
3309
3315
|
}
|
|
3310
3316
|
|
|
3317
|
+
const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
|
|
3318
|
+
const transferredCanvas = transferredCanvases.get(canvas);
|
|
3319
|
+
if (transferredCanvas) {
|
|
3320
|
+
return transferredCanvas;
|
|
3321
|
+
}
|
|
3322
|
+
if (typeof canvas.transferControlToOffscreen !== "function") {
|
|
3323
|
+
throw new TypeError("OffscreenCanvas is required but not supported by this browser");
|
|
3324
|
+
}
|
|
3325
|
+
try {
|
|
3326
|
+
const offscreenCanvas = canvas.transferControlToOffscreen();
|
|
3327
|
+
transferredCanvases.set(canvas, offscreenCanvas);
|
|
3328
|
+
return offscreenCanvas;
|
|
3329
|
+
}
|
|
3330
|
+
catch {
|
|
3331
|
+
throw new TypeError("OffscreenCanvas transfer failed");
|
|
3332
|
+
}
|
|
3333
|
+
}, isHtmlCanvasElement = (canvas) => {
|
|
3334
|
+
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
3335
|
+
};
|
|
3311
3336
|
function setStyle(canvas, style, important = false) {
|
|
3312
3337
|
if (!style) {
|
|
3313
3338
|
return;
|
|
@@ -3338,8 +3363,9 @@
|
|
|
3338
3363
|
}
|
|
3339
3364
|
}
|
|
3340
3365
|
class CanvasManager {
|
|
3341
|
-
|
|
3366
|
+
domElement;
|
|
3342
3367
|
render;
|
|
3368
|
+
renderCanvas;
|
|
3343
3369
|
size;
|
|
3344
3370
|
zoom = defaultZoom;
|
|
3345
3371
|
_container;
|
|
@@ -3374,9 +3400,10 @@
|
|
|
3374
3400
|
destroy() {
|
|
3375
3401
|
this.stop();
|
|
3376
3402
|
if (this._generated) {
|
|
3377
|
-
const element = this.
|
|
3403
|
+
const element = this.domElement;
|
|
3378
3404
|
element?.remove();
|
|
3379
|
-
this.
|
|
3405
|
+
this.domElement = undefined;
|
|
3406
|
+
this.renderCanvas = undefined;
|
|
3380
3407
|
}
|
|
3381
3408
|
else {
|
|
3382
3409
|
this._resetOriginalStyle();
|
|
@@ -3409,16 +3436,17 @@
|
|
|
3409
3436
|
this._initStyle();
|
|
3410
3437
|
this.initBackground();
|
|
3411
3438
|
this._safeMutationObserver(obs => {
|
|
3412
|
-
|
|
3439
|
+
const element = this.domElement;
|
|
3440
|
+
if (!element || !(element instanceof Node)) {
|
|
3413
3441
|
return;
|
|
3414
3442
|
}
|
|
3415
|
-
obs.observe(
|
|
3443
|
+
obs.observe(element, { attributes: true });
|
|
3416
3444
|
});
|
|
3417
3445
|
this.initPlugins();
|
|
3418
3446
|
this.render.init();
|
|
3419
3447
|
}
|
|
3420
3448
|
initBackground() {
|
|
3421
|
-
const { _container } = this, options = _container.actualOptions, background = options.background, element = this.
|
|
3449
|
+
const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
|
|
3422
3450
|
if (!element) {
|
|
3423
3451
|
return;
|
|
3424
3452
|
}
|
|
@@ -3443,21 +3471,30 @@
|
|
|
3443
3471
|
}
|
|
3444
3472
|
}
|
|
3445
3473
|
loadCanvas(canvas) {
|
|
3446
|
-
if (this._generated && this.
|
|
3447
|
-
this.
|
|
3474
|
+
if (this._generated && this.domElement) {
|
|
3475
|
+
this.domElement.remove();
|
|
3476
|
+
}
|
|
3477
|
+
const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
|
|
3478
|
+
this.domElement = domCanvas;
|
|
3479
|
+
this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
|
|
3480
|
+
this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
|
|
3481
|
+
const domElement = this.domElement;
|
|
3482
|
+
if (domElement) {
|
|
3483
|
+
domElement.ariaHidden = "true";
|
|
3484
|
+
this._originalStyle = cloneStyle(domElement.style);
|
|
3485
|
+
}
|
|
3486
|
+
const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
|
|
3487
|
+
if (domElement) {
|
|
3488
|
+
standardSize.height = domElement.offsetHeight;
|
|
3489
|
+
standardSize.width = domElement.offsetWidth;
|
|
3490
|
+
}
|
|
3491
|
+
else {
|
|
3492
|
+
standardSize.height = renderCanvas.height;
|
|
3493
|
+
standardSize.width = renderCanvas.width;
|
|
3448
3494
|
}
|
|
3449
|
-
const container = this._container;
|
|
3450
|
-
this._generated =
|
|
3451
|
-
generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
|
|
3452
|
-
this.element = canvas;
|
|
3453
|
-
this.element.ariaHidden = "true";
|
|
3454
|
-
this._originalStyle = cloneStyle(this.element.style);
|
|
3455
|
-
const standardSize = this._standardSize;
|
|
3456
|
-
standardSize.height = canvas.offsetHeight;
|
|
3457
|
-
standardSize.width = canvas.offsetWidth;
|
|
3458
3495
|
const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
|
|
3459
|
-
|
|
3460
|
-
|
|
3496
|
+
renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
|
|
3497
|
+
renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
|
|
3461
3498
|
const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
|
|
3462
3499
|
this.render.setContextSettings({
|
|
3463
3500
|
alpha: true,
|
|
@@ -3465,42 +3502,48 @@
|
|
|
3465
3502
|
desynchronized: true,
|
|
3466
3503
|
willReadFrequently: false,
|
|
3467
3504
|
});
|
|
3468
|
-
this.render.setContext(
|
|
3505
|
+
this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
|
|
3469
3506
|
this._safeMutationObserver(obs => {
|
|
3470
3507
|
obs.disconnect();
|
|
3471
3508
|
});
|
|
3472
3509
|
container.retina.init();
|
|
3473
3510
|
this.initBackground();
|
|
3474
3511
|
this._safeMutationObserver(obs => {
|
|
3475
|
-
|
|
3512
|
+
const element = this.domElement;
|
|
3513
|
+
if (!element || !(element instanceof Node)) {
|
|
3476
3514
|
return;
|
|
3477
3515
|
}
|
|
3478
|
-
obs.observe(
|
|
3516
|
+
obs.observe(element, { attributes: true });
|
|
3479
3517
|
});
|
|
3480
3518
|
}
|
|
3481
3519
|
resize() {
|
|
3482
|
-
|
|
3520
|
+
const element = this.domElement;
|
|
3521
|
+
if (!element) {
|
|
3522
|
+
return false;
|
|
3523
|
+
}
|
|
3524
|
+
const container = this._container, renderCanvas = this.renderCanvas;
|
|
3525
|
+
if (renderCanvas === undefined) {
|
|
3483
3526
|
return false;
|
|
3484
3527
|
}
|
|
3485
|
-
const
|
|
3486
|
-
width:
|
|
3487
|
-
height:
|
|
3528
|
+
const currentSize = container.canvas._standardSize, newSize = {
|
|
3529
|
+
width: element.offsetWidth,
|
|
3530
|
+
height: element.offsetHeight,
|
|
3488
3531
|
}, pxRatio = container.retina.pixelRatio, retinaSize = {
|
|
3489
3532
|
width: newSize.width * pxRatio,
|
|
3490
3533
|
height: newSize.height * pxRatio,
|
|
3491
3534
|
};
|
|
3492
3535
|
if (newSize.height === currentSize.height &&
|
|
3493
3536
|
newSize.width === currentSize.width &&
|
|
3494
|
-
retinaSize.height ===
|
|
3495
|
-
retinaSize.width ===
|
|
3537
|
+
retinaSize.height === renderCanvas.height &&
|
|
3538
|
+
retinaSize.width === renderCanvas.width) {
|
|
3496
3539
|
return false;
|
|
3497
3540
|
}
|
|
3498
3541
|
const oldSize = { ...currentSize };
|
|
3499
3542
|
currentSize.height = newSize.height;
|
|
3500
3543
|
currentSize.width = newSize.width;
|
|
3501
3544
|
const canvasSize = this.size;
|
|
3502
|
-
|
|
3503
|
-
|
|
3545
|
+
renderCanvas.width = canvasSize.width = retinaSize.width;
|
|
3546
|
+
renderCanvas.height = canvasSize.height = retinaSize.height;
|
|
3504
3547
|
if (this._container.started) {
|
|
3505
3548
|
container.particles.setResizeFactor({
|
|
3506
3549
|
width: currentSize.width / oldSize.width,
|
|
@@ -3510,7 +3553,7 @@
|
|
|
3510
3553
|
return true;
|
|
3511
3554
|
}
|
|
3512
3555
|
setPointerEvents(type) {
|
|
3513
|
-
const element = this.
|
|
3556
|
+
const element = this.domElement;
|
|
3514
3557
|
if (!element) {
|
|
3515
3558
|
return;
|
|
3516
3559
|
}
|
|
@@ -3529,7 +3572,7 @@
|
|
|
3529
3572
|
this.render.stop();
|
|
3530
3573
|
}
|
|
3531
3574
|
async windowResize() {
|
|
3532
|
-
if (!this.
|
|
3575
|
+
if (!this.domElement || !this.resize()) {
|
|
3533
3576
|
return;
|
|
3534
3577
|
}
|
|
3535
3578
|
const container = this._container, needsRefresh = container.updateActualOptions();
|
|
@@ -3545,7 +3588,7 @@
|
|
|
3545
3588
|
}
|
|
3546
3589
|
};
|
|
3547
3590
|
_initStyle = () => {
|
|
3548
|
-
const element = this.
|
|
3591
|
+
const element = this.domElement, options = this._container.actualOptions;
|
|
3549
3592
|
if (!element) {
|
|
3550
3593
|
return;
|
|
3551
3594
|
}
|
|
@@ -3567,7 +3610,7 @@
|
|
|
3567
3610
|
}
|
|
3568
3611
|
};
|
|
3569
3612
|
_repairStyle = () => {
|
|
3570
|
-
const element = this.
|
|
3613
|
+
const element = this.domElement;
|
|
3571
3614
|
if (!element) {
|
|
3572
3615
|
return;
|
|
3573
3616
|
}
|
|
@@ -3587,7 +3630,7 @@
|
|
|
3587
3630
|
});
|
|
3588
3631
|
};
|
|
3589
3632
|
_resetOriginalStyle = () => {
|
|
3590
|
-
const element = this.
|
|
3633
|
+
const element = this.domElement, originalStyle = this._originalStyle;
|
|
3591
3634
|
if (!element || !originalStyle) {
|
|
3592
3635
|
return;
|
|
3593
3636
|
}
|
|
@@ -3600,7 +3643,7 @@
|
|
|
3600
3643
|
callback(this._mutationObserver);
|
|
3601
3644
|
};
|
|
3602
3645
|
_setFullScreenStyle = () => {
|
|
3603
|
-
const element = this.
|
|
3646
|
+
const element = this.domElement;
|
|
3604
3647
|
if (!element) {
|
|
3605
3648
|
return;
|
|
3606
3649
|
}
|
|
@@ -3674,7 +3717,7 @@
|
|
|
3674
3717
|
manageListener(globalThis, resizeEvent, handlers.resize, add);
|
|
3675
3718
|
return;
|
|
3676
3719
|
}
|
|
3677
|
-
const canvasEl = container.canvas.
|
|
3720
|
+
const canvasEl = container.canvas.domElement;
|
|
3678
3721
|
if (this._resizeObserver && !add) {
|
|
3679
3722
|
if (canvasEl) {
|
|
3680
3723
|
this._resizeObserver.unobserve(canvasEl);
|
|
@@ -3929,8 +3972,6 @@
|
|
|
3929
3972
|
this._initPosition(position);
|
|
3930
3973
|
this.initialVelocity = this._calculateVelocity();
|
|
3931
3974
|
this.velocity = this.initialVelocity.copy();
|
|
3932
|
-
const particles = container.particles;
|
|
3933
|
-
particles.setLastZIndex(this.position.z);
|
|
3934
3975
|
this.zIndexFactor = this.position.z / container.zLayers;
|
|
3935
3976
|
this.sides = 24;
|
|
3936
3977
|
let effectDrawer, shapeDrawer;
|
|
@@ -4080,7 +4121,7 @@
|
|
|
4080
4121
|
return color;
|
|
4081
4122
|
};
|
|
4082
4123
|
_initPosition = position => {
|
|
4083
|
-
const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
|
|
4124
|
+
const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
|
|
4084
4125
|
if (!initialPosition) {
|
|
4085
4126
|
throw new Error("a valid position cannot be found for particle");
|
|
4086
4127
|
}
|
|
@@ -4214,10 +4255,8 @@
|
|
|
4214
4255
|
_container;
|
|
4215
4256
|
_groupLimits;
|
|
4216
4257
|
_limit;
|
|
4217
|
-
_maxZIndex;
|
|
4218
|
-
_minZIndex;
|
|
4219
|
-
_needsSort;
|
|
4220
4258
|
_nextId;
|
|
4259
|
+
_particleBuckets;
|
|
4221
4260
|
_particleResetPlugins;
|
|
4222
4261
|
_particleUpdatePlugins;
|
|
4223
4262
|
_pluginManager;
|
|
@@ -4226,19 +4265,17 @@
|
|
|
4226
4265
|
_postUpdatePlugins;
|
|
4227
4266
|
_resizeFactor;
|
|
4228
4267
|
_updatePlugins;
|
|
4229
|
-
|
|
4268
|
+
_zBuckets;
|
|
4230
4269
|
constructor(pluginManager, container) {
|
|
4231
4270
|
this._pluginManager = pluginManager;
|
|
4232
4271
|
this._container = container;
|
|
4233
4272
|
this._nextId = 0;
|
|
4234
4273
|
this._array = [];
|
|
4235
|
-
this._zArray = [];
|
|
4236
4274
|
this._pool = [];
|
|
4237
4275
|
this._limit = 0;
|
|
4238
4276
|
this._groupLimits = new Map();
|
|
4239
|
-
this.
|
|
4240
|
-
this.
|
|
4241
|
-
this._maxZIndex = 0;
|
|
4277
|
+
this._particleBuckets = new Map();
|
|
4278
|
+
this._zBuckets = this._createBuckets(this._container.zLayers);
|
|
4242
4279
|
this.grid = new SpatialHashGrid(spatialHashGridCellSize);
|
|
4243
4280
|
this.checkParticlePositionPlugins = [];
|
|
4244
4281
|
this._particleResetPlugins = [];
|
|
@@ -4280,7 +4317,7 @@
|
|
|
4280
4317
|
return;
|
|
4281
4318
|
}
|
|
4282
4319
|
this._array.push(particle);
|
|
4283
|
-
this.
|
|
4320
|
+
this._insertParticleIntoBucket(particle);
|
|
4284
4321
|
this._nextId++;
|
|
4285
4322
|
this._container.dispatchEvent(exports.EventType.particleAdded, {
|
|
4286
4323
|
particle,
|
|
@@ -4294,12 +4331,14 @@
|
|
|
4294
4331
|
}
|
|
4295
4332
|
clear() {
|
|
4296
4333
|
this._array = [];
|
|
4297
|
-
this.
|
|
4334
|
+
this._particleBuckets.clear();
|
|
4335
|
+
this._resetBuckets(this._container.zLayers);
|
|
4298
4336
|
}
|
|
4299
4337
|
destroy() {
|
|
4300
4338
|
this._array = [];
|
|
4301
4339
|
this._pool.length = 0;
|
|
4302
|
-
this.
|
|
4340
|
+
this._particleBuckets.clear();
|
|
4341
|
+
this._zBuckets = [];
|
|
4303
4342
|
this.checkParticlePositionPlugins = [];
|
|
4304
4343
|
this._particleResetPlugins = [];
|
|
4305
4344
|
this._particleUpdatePlugins = [];
|
|
@@ -4308,8 +4347,14 @@
|
|
|
4308
4347
|
this._updatePlugins = [];
|
|
4309
4348
|
}
|
|
4310
4349
|
drawParticles(delta) {
|
|
4311
|
-
for (
|
|
4312
|
-
|
|
4350
|
+
for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
|
|
4351
|
+
const bucket = this._zBuckets[i];
|
|
4352
|
+
if (!bucket) {
|
|
4353
|
+
continue;
|
|
4354
|
+
}
|
|
4355
|
+
for (const particle of bucket) {
|
|
4356
|
+
particle.draw(delta);
|
|
4357
|
+
}
|
|
4313
4358
|
}
|
|
4314
4359
|
}
|
|
4315
4360
|
filter(condition) {
|
|
@@ -4323,15 +4368,14 @@
|
|
|
4323
4368
|
}
|
|
4324
4369
|
async init() {
|
|
4325
4370
|
const container = this._container, options = container.actualOptions;
|
|
4326
|
-
this._minZIndex = 0;
|
|
4327
|
-
this._maxZIndex = 0;
|
|
4328
|
-
this._needsSort = false;
|
|
4329
4371
|
this.checkParticlePositionPlugins = [];
|
|
4330
4372
|
this._updatePlugins = [];
|
|
4331
4373
|
this._particleUpdatePlugins = [];
|
|
4332
4374
|
this._postUpdatePlugins = [];
|
|
4333
4375
|
this._particleResetPlugins = [];
|
|
4334
4376
|
this._postParticleUpdatePlugins = [];
|
|
4377
|
+
this._particleBuckets.clear();
|
|
4378
|
+
this._resetBuckets(container.zLayers);
|
|
4335
4379
|
this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
|
|
4336
4380
|
for (const plugin of container.plugins) {
|
|
4337
4381
|
if (plugin.redrawInit) {
|
|
@@ -4432,79 +4476,25 @@
|
|
|
4432
4476
|
}
|
|
4433
4477
|
this._applyDensity(options.particles, pluginsCount);
|
|
4434
4478
|
}
|
|
4435
|
-
setLastZIndex(zIndex) {
|
|
4436
|
-
this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
|
|
4437
|
-
}
|
|
4438
4479
|
setResizeFactor(factor) {
|
|
4439
4480
|
this._resizeFactor = factor;
|
|
4440
4481
|
}
|
|
4441
4482
|
update(delta) {
|
|
4442
|
-
const particlesToDelete = new Set();
|
|
4443
4483
|
this.grid.clear();
|
|
4444
4484
|
for (const plugin of this._updatePlugins) {
|
|
4445
4485
|
plugin.update?.(delta);
|
|
4446
4486
|
}
|
|
4447
|
-
const
|
|
4448
|
-
for (const particle of this._array) {
|
|
4449
|
-
if (resizeFactor && !particle.ignoresResizeRatio) {
|
|
4450
|
-
particle.position.x *= resizeFactor.width;
|
|
4451
|
-
particle.position.y *= resizeFactor.height;
|
|
4452
|
-
particle.initialPosition.x *= resizeFactor.width;
|
|
4453
|
-
particle.initialPosition.y *= resizeFactor.height;
|
|
4454
|
-
}
|
|
4455
|
-
particle.ignoresResizeRatio = false;
|
|
4456
|
-
for (const plugin of this._particleResetPlugins) {
|
|
4457
|
-
plugin.particleReset?.(particle);
|
|
4458
|
-
}
|
|
4459
|
-
for (const plugin of this._particleUpdatePlugins) {
|
|
4460
|
-
if (particle.destroyed) {
|
|
4461
|
-
break;
|
|
4462
|
-
}
|
|
4463
|
-
plugin.particleUpdate?.(particle, delta);
|
|
4464
|
-
}
|
|
4465
|
-
if (particle.destroyed) {
|
|
4466
|
-
particlesToDelete.add(particle);
|
|
4467
|
-
continue;
|
|
4468
|
-
}
|
|
4469
|
-
this.grid.insert(particle);
|
|
4470
|
-
}
|
|
4487
|
+
const particlesToDelete = this._updateParticlesPhase1(delta);
|
|
4471
4488
|
for (const plugin of this._postUpdatePlugins) {
|
|
4472
4489
|
plugin.postUpdate?.(delta);
|
|
4473
4490
|
}
|
|
4474
|
-
|
|
4475
|
-
if (particle.destroyed) {
|
|
4476
|
-
particlesToDelete.add(particle);
|
|
4477
|
-
continue;
|
|
4478
|
-
}
|
|
4479
|
-
for (const updater of this._container.particleUpdaters) {
|
|
4480
|
-
updater.update(particle, delta);
|
|
4481
|
-
}
|
|
4482
|
-
if (!particle.destroyed && !particle.spawning) {
|
|
4483
|
-
for (const plugin of this._postParticleUpdatePlugins) {
|
|
4484
|
-
plugin.postParticleUpdate?.(particle, delta);
|
|
4485
|
-
}
|
|
4486
|
-
}
|
|
4487
|
-
else if (particle.destroyed) {
|
|
4488
|
-
particlesToDelete.add(particle);
|
|
4489
|
-
}
|
|
4490
|
-
}
|
|
4491
|
+
this._updateParticlesPhase2(delta, particlesToDelete);
|
|
4491
4492
|
if (particlesToDelete.size) {
|
|
4492
4493
|
for (const particle of particlesToDelete) {
|
|
4493
4494
|
this.remove(particle);
|
|
4494
4495
|
}
|
|
4495
4496
|
}
|
|
4496
4497
|
delete this._resizeFactor;
|
|
4497
|
-
if (this._needsSort) {
|
|
4498
|
-
const zArray = this._zArray;
|
|
4499
|
-
zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
|
|
4500
|
-
const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
|
|
4501
|
-
if (!firstItem || !lastItem) {
|
|
4502
|
-
return;
|
|
4503
|
-
}
|
|
4504
|
-
this._maxZIndex = firstItem.position.z;
|
|
4505
|
-
this._minZIndex = lastItem.position.z;
|
|
4506
|
-
this._needsSort = false;
|
|
4507
|
-
}
|
|
4508
4498
|
}
|
|
4509
4499
|
_addToPool = (...particles) => {
|
|
4510
4500
|
this._pool.push(...particles);
|
|
@@ -4534,13 +4524,52 @@
|
|
|
4534
4524
|
this.removeQuantity(particlesCount - particlesNumber, group);
|
|
4535
4525
|
}
|
|
4536
4526
|
};
|
|
4527
|
+
_createBuckets = (zLayers) => {
|
|
4528
|
+
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
4529
|
+
return Array.from({ length: bucketCount }, () => []);
|
|
4530
|
+
};
|
|
4531
|
+
_getBucketIndex = (zIndex) => {
|
|
4532
|
+
const maxBucketIndex = this._zBuckets.length - one;
|
|
4533
|
+
if (maxBucketIndex <= minIndex) {
|
|
4534
|
+
return minIndex;
|
|
4535
|
+
}
|
|
4536
|
+
return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
|
|
4537
|
+
};
|
|
4538
|
+
_getParticleInsertIndex = (bucket, particleId) => {
|
|
4539
|
+
let start = minIndex, end = bucket.length;
|
|
4540
|
+
while (start < end) {
|
|
4541
|
+
const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
|
|
4542
|
+
if (!middleParticle) {
|
|
4543
|
+
end = middle;
|
|
4544
|
+
continue;
|
|
4545
|
+
}
|
|
4546
|
+
if (middleParticle.id < particleId) {
|
|
4547
|
+
start = middle + one;
|
|
4548
|
+
}
|
|
4549
|
+
else {
|
|
4550
|
+
end = middle;
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
return start;
|
|
4554
|
+
};
|
|
4537
4555
|
_initDensityFactor = densityOptions => {
|
|
4538
4556
|
const container = this._container;
|
|
4539
|
-
if (!
|
|
4557
|
+
if (!densityOptions.enable) {
|
|
4558
|
+
return defaultDensityFactor;
|
|
4559
|
+
}
|
|
4560
|
+
const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
|
|
4561
|
+
if (!canvasSize.width || !canvasSize.height) {
|
|
4540
4562
|
return defaultDensityFactor;
|
|
4541
4563
|
}
|
|
4542
|
-
|
|
4543
|
-
|
|
4564
|
+
return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
|
|
4565
|
+
};
|
|
4566
|
+
_insertParticleIntoBucket = (particle) => {
|
|
4567
|
+
const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
|
|
4568
|
+
if (!bucket) {
|
|
4569
|
+
return;
|
|
4570
|
+
}
|
|
4571
|
+
bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
|
|
4572
|
+
this._particleBuckets.set(particle.id, bucketIndex);
|
|
4544
4573
|
};
|
|
4545
4574
|
_removeParticle = (index, group, override) => {
|
|
4546
4575
|
const particle = this._array[index];
|
|
@@ -4550,9 +4579,8 @@
|
|
|
4550
4579
|
if (particle.group !== group) {
|
|
4551
4580
|
return false;
|
|
4552
4581
|
}
|
|
4553
|
-
const zIdx = this._zArray.indexOf(particle);
|
|
4554
4582
|
this._array.splice(index, deleteCount);
|
|
4555
|
-
this.
|
|
4583
|
+
this._removeParticleFromBucket(particle);
|
|
4556
4584
|
particle.destroy(override);
|
|
4557
4585
|
this._container.dispatchEvent(exports.EventType.particleRemoved, {
|
|
4558
4586
|
particle,
|
|
@@ -4560,6 +4588,98 @@
|
|
|
4560
4588
|
this._addToPool(particle);
|
|
4561
4589
|
return true;
|
|
4562
4590
|
};
|
|
4591
|
+
_removeParticleFromBucket = (particle) => {
|
|
4592
|
+
const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
|
|
4593
|
+
if (!bucket) {
|
|
4594
|
+
this._particleBuckets.delete(particle.id);
|
|
4595
|
+
return;
|
|
4596
|
+
}
|
|
4597
|
+
const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
|
|
4598
|
+
if (bucket[particleIndex]?.id !== particle.id) {
|
|
4599
|
+
this._particleBuckets.delete(particle.id);
|
|
4600
|
+
return;
|
|
4601
|
+
}
|
|
4602
|
+
bucket.splice(particleIndex, deleteCount);
|
|
4603
|
+
this._particleBuckets.delete(particle.id);
|
|
4604
|
+
};
|
|
4605
|
+
_resetBuckets = (zLayers) => {
|
|
4606
|
+
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
4607
|
+
if (this._zBuckets.length !== bucketCount) {
|
|
4608
|
+
this._zBuckets = this._createBuckets(bucketCount);
|
|
4609
|
+
return;
|
|
4610
|
+
}
|
|
4611
|
+
for (const bucket of this._zBuckets) {
|
|
4612
|
+
bucket.length = minIndex;
|
|
4613
|
+
}
|
|
4614
|
+
};
|
|
4615
|
+
_updateParticleBucket = (particle) => {
|
|
4616
|
+
const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
|
|
4617
|
+
if (currentBucketIndex === undefined) {
|
|
4618
|
+
this._insertParticleIntoBucket(particle);
|
|
4619
|
+
return;
|
|
4620
|
+
}
|
|
4621
|
+
if (currentBucketIndex === newBucketIndex) {
|
|
4622
|
+
return;
|
|
4623
|
+
}
|
|
4624
|
+
const currentBucket = this._zBuckets[currentBucketIndex];
|
|
4625
|
+
if (currentBucket) {
|
|
4626
|
+
const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
|
|
4627
|
+
if (currentBucket[particleIndex]?.id === particle.id) {
|
|
4628
|
+
currentBucket.splice(particleIndex, deleteCount);
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
const newBucket = this._zBuckets[newBucketIndex];
|
|
4632
|
+
if (!newBucket) {
|
|
4633
|
+
this._particleBuckets.set(particle.id, newBucketIndex);
|
|
4634
|
+
return;
|
|
4635
|
+
}
|
|
4636
|
+
newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
|
|
4637
|
+
this._particleBuckets.set(particle.id, newBucketIndex);
|
|
4638
|
+
};
|
|
4639
|
+
_updateParticlesPhase1 = (delta) => {
|
|
4640
|
+
const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
|
|
4641
|
+
for (const particle of this._array) {
|
|
4642
|
+
if (resizeFactor && !particle.ignoresResizeRatio) {
|
|
4643
|
+
particle.position.x *= resizeFactor.width;
|
|
4644
|
+
particle.position.y *= resizeFactor.height;
|
|
4645
|
+
particle.initialPosition.x *= resizeFactor.width;
|
|
4646
|
+
particle.initialPosition.y *= resizeFactor.height;
|
|
4647
|
+
}
|
|
4648
|
+
particle.ignoresResizeRatio = false;
|
|
4649
|
+
for (const plugin of this._particleResetPlugins) {
|
|
4650
|
+
plugin.particleReset?.(particle);
|
|
4651
|
+
}
|
|
4652
|
+
for (const plugin of this._particleUpdatePlugins) {
|
|
4653
|
+
if (particle.destroyed) {
|
|
4654
|
+
break;
|
|
4655
|
+
}
|
|
4656
|
+
plugin.particleUpdate?.(particle, delta);
|
|
4657
|
+
}
|
|
4658
|
+
if (particle.destroyed) {
|
|
4659
|
+
particlesToDelete.add(particle);
|
|
4660
|
+
continue;
|
|
4661
|
+
}
|
|
4662
|
+
this.grid.insert(particle);
|
|
4663
|
+
}
|
|
4664
|
+
return particlesToDelete;
|
|
4665
|
+
};
|
|
4666
|
+
_updateParticlesPhase2 = (delta, particlesToDelete) => {
|
|
4667
|
+
for (const particle of this._array) {
|
|
4668
|
+
if (particle.destroyed) {
|
|
4669
|
+
particlesToDelete.add(particle);
|
|
4670
|
+
continue;
|
|
4671
|
+
}
|
|
4672
|
+
for (const updater of this._container.particleUpdaters) {
|
|
4673
|
+
updater.update(particle, delta);
|
|
4674
|
+
}
|
|
4675
|
+
if (!particle.spawning) {
|
|
4676
|
+
for (const plugin of this._postParticleUpdatePlugins) {
|
|
4677
|
+
plugin.postParticleUpdate?.(particle, delta);
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
this._updateParticleBucket(particle);
|
|
4681
|
+
}
|
|
4682
|
+
};
|
|
4563
4683
|
}
|
|
4564
4684
|
|
|
4565
4685
|
class Retina {
|
|
@@ -4575,9 +4695,8 @@
|
|
|
4575
4695
|
const container = this.container, options = container.actualOptions;
|
|
4576
4696
|
this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
|
|
4577
4697
|
this.reduceFactor = defaultReduceFactor;
|
|
4578
|
-
const ratio = this.pixelRatio, canvas = container.canvas;
|
|
4579
|
-
if (
|
|
4580
|
-
const element = canvas.element;
|
|
4698
|
+
const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
|
|
4699
|
+
if (element) {
|
|
4581
4700
|
canvas.size.width = element.offsetWidth * ratio;
|
|
4582
4701
|
canvas.size.height = element.offsetHeight * ratio;
|
|
4583
4702
|
}
|