@tsparticles/preset-matrix 4.0.0-beta.16 → 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.
@@ -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
- /* Preset v4.0.0-beta.16 */
2
+ /* Preset v4.0.0 */
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) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -959,7 +959,7 @@
959
959
  }
960
960
  }
961
961
  else {
962
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases[canvasFirstIndex];
962
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
963
963
  if (foundCanvas) {
964
964
  canvasEl = foundCanvas;
965
965
  canvasEl.dataset[generatedAttribute] = generatedFalse;
@@ -996,7 +996,7 @@
996
996
  return this._domArray;
997
997
  }
998
998
  get version() {
999
- return "4.0.0-beta.16";
999
+ return "4.0.0";
1000
1000
  }
1001
1001
  addEventListener(type, listener) {
1002
1002
  this._eventDispatcher.addEventListener(type, listener);
@@ -1027,7 +1027,11 @@
1027
1027
  }
1028
1028
  async load(params) {
1029
1029
  await this.init();
1030
- const { Container } = await Promise.resolve().then(function () { return Container$1; }), id = params.id ?? params.element?.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({
1030
+ let domSourceElement;
1031
+ if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
1032
+ domSourceElement = params.element;
1033
+ }
1034
+ 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({
1031
1035
  dispatchCallback: (eventType, args) => {
1032
1036
  this.dispatchEvent(eventType, args);
1033
1037
  },
@@ -1054,8 +1058,10 @@
1054
1058
  else {
1055
1059
  items.push(newItem);
1056
1060
  }
1057
- const domContainer = getDomContainer(id, params.element), canvasEl = getCanvasFromContainer(domContainer);
1058
- newItem.canvas.loadCanvas(canvasEl);
1061
+ const sourceCanvas = typeof OffscreenCanvas !== "undefined" && params.element instanceof OffscreenCanvas
1062
+ ? params.element
1063
+ : getCanvasFromContainer(getDomContainer(id, domSourceElement));
1064
+ newItem.canvas.loadCanvas(sourceCanvas);
1059
1065
  await newItem.start();
1060
1066
  return newItem;
1061
1067
  }
@@ -2848,7 +2854,7 @@
2848
2854
  }
2849
2855
 
2850
2856
  async function loadCircleShape(engine) {
2851
- engine.checkVersion("4.0.0-beta.16");
2857
+ engine.checkVersion("4.0.0");
2852
2858
  await engine.pluginManager.register(e => {
2853
2859
  e.pluginManager.addShape(["circle"], () => {
2854
2860
  return Promise.resolve(new CircleDrawer());
@@ -2896,7 +2902,7 @@
2896
2902
  }
2897
2903
 
2898
2904
  async function loadHexColorPlugin(engine) {
2899
- engine.checkVersion("4.0.0-beta.16");
2905
+ engine.checkVersion("4.0.0");
2900
2906
  await engine.pluginManager.register(e => {
2901
2907
  e.pluginManager.addColorManager("hex", new HexColorManager());
2902
2908
  });
@@ -2949,7 +2955,7 @@
2949
2955
  }
2950
2956
 
2951
2957
  async function loadHslColorPlugin(engine) {
2952
- engine.checkVersion("4.0.0-beta.16");
2958
+ engine.checkVersion("4.0.0");
2953
2959
  await engine.pluginManager.register(e => {
2954
2960
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2955
2961
  });
@@ -2973,7 +2979,7 @@
2973
2979
  }
2974
2980
 
2975
2981
  async function loadMovePlugin(engine) {
2976
- engine.checkVersion("4.0.0-beta.16");
2982
+ engine.checkVersion("4.0.0");
2977
2983
  await engine.pluginManager.register(e => {
2978
2984
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2979
2985
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -3034,7 +3040,7 @@
3034
3040
  }
3035
3041
 
3036
3042
  async function loadOpacityUpdater(engine) {
3037
- engine.checkVersion("4.0.0-beta.16");
3043
+ engine.checkVersion("4.0.0");
3038
3044
  await engine.pluginManager.register(e => {
3039
3045
  e.pluginManager.addParticleUpdater("opacity", container => {
3040
3046
  return Promise.resolve(new OpacityUpdater(container));
@@ -3386,7 +3392,7 @@
3386
3392
  }
3387
3393
 
3388
3394
  async function loadOutModesUpdater(engine) {
3389
- engine.checkVersion("4.0.0-beta.16");
3395
+ engine.checkVersion("4.0.0");
3390
3396
  await engine.pluginManager.register(e => {
3391
3397
  e.pluginManager.addParticleUpdater("outModes", container => {
3392
3398
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3457,7 +3463,7 @@
3457
3463
  }
3458
3464
 
3459
3465
  async function loadPaintUpdater(engine) {
3460
- engine.checkVersion("4.0.0-beta.16");
3466
+ engine.checkVersion("4.0.0");
3461
3467
  await engine.pluginManager.register(e => {
3462
3468
  e.pluginManager.addParticleUpdater("paint", container => {
3463
3469
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3512,7 +3518,7 @@
3512
3518
  }
3513
3519
 
3514
3520
  async function loadRgbColorPlugin(engine) {
3515
- engine.checkVersion("4.0.0-beta.16");
3521
+ engine.checkVersion("4.0.0");
3516
3522
  await engine.pluginManager.register(e => {
3517
3523
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3518
3524
  });
@@ -3555,7 +3561,7 @@
3555
3561
  }
3556
3562
 
3557
3563
  async function loadSizeUpdater(engine) {
3558
- engine.checkVersion("4.0.0-beta.16");
3564
+ engine.checkVersion("4.0.0");
3559
3565
  await engine.pluginManager.register(e => {
3560
3566
  e.pluginManager.addParticleUpdater("size", container => {
3561
3567
  return Promise.resolve(new SizeUpdater(container));
@@ -3564,7 +3570,7 @@
3564
3570
  }
3565
3571
 
3566
3572
  async function loadBasic(engine) {
3567
- engine.checkVersion("4.0.0-beta.16");
3573
+ engine.checkVersion("4.0.0");
3568
3574
  await engine.pluginManager.register(async (e) => {
3569
3575
  await Promise.all([
3570
3576
  loadHexColorPlugin(e),
@@ -3795,7 +3801,7 @@
3795
3801
  }
3796
3802
 
3797
3803
  async function loadMatrixShape(engine) {
3798
- engine.checkVersion("4.0.0-beta.16");
3804
+ engine.checkVersion("4.0.0");
3799
3805
  await engine.pluginManager.register(e => {
3800
3806
  e.pluginManager.addShape(["matrix"], () => Promise.resolve(new MatrixDrawer()));
3801
3807
  });
@@ -3855,7 +3861,7 @@
3855
3861
  }
3856
3862
 
3857
3863
  async function loadPoissonDiscPlugin(engine) {
3858
- engine.checkVersion("4.0.0-beta.16");
3864
+ engine.checkVersion("4.0.0");
3859
3865
  await engine.pluginManager.register(e => {
3860
3866
  e.pluginManager.addPlugin(new PoissonDiscPlugin());
3861
3867
  });
@@ -3893,7 +3899,7 @@
3893
3899
  }
3894
3900
 
3895
3901
  async function loadShadowEffect(engine) {
3896
- engine.checkVersion("4.0.0-beta.16");
3902
+ engine.checkVersion("4.0.0");
3897
3903
  await engine.pluginManager.register(e => {
3898
3904
  e.pluginManager.addEffect("shadow", container => {
3899
3905
  return Promise.resolve(new ShadowDrawer(e.pluginManager, container));
@@ -3968,7 +3974,7 @@
3968
3974
  }
3969
3975
 
3970
3976
  async function loadTrailPlugin(engine) {
3971
- engine.checkVersion("4.0.0-beta.16");
3977
+ engine.checkVersion("4.0.0");
3972
3978
  await engine.pluginManager.register(e => {
3973
3979
  e.pluginManager.addPlugin(new TrailPlugin(e.pluginManager));
3974
3980
  });
@@ -4371,6 +4377,25 @@
4371
4377
  };
4372
4378
  }
4373
4379
 
4380
+ const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
4381
+ const transferredCanvas = transferredCanvases.get(canvas);
4382
+ if (transferredCanvas) {
4383
+ return transferredCanvas;
4384
+ }
4385
+ if (typeof canvas.transferControlToOffscreen !== "function") {
4386
+ throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4387
+ }
4388
+ try {
4389
+ const offscreenCanvas = canvas.transferControlToOffscreen();
4390
+ transferredCanvases.set(canvas, offscreenCanvas);
4391
+ return offscreenCanvas;
4392
+ }
4393
+ catch {
4394
+ throw new TypeError("OffscreenCanvas transfer failed");
4395
+ }
4396
+ }, isHtmlCanvasElement = (canvas) => {
4397
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4398
+ };
4374
4399
  function setStyle(canvas, style, important = false) {
4375
4400
  if (!style) {
4376
4401
  return;
@@ -4401,8 +4426,9 @@
4401
4426
  }
4402
4427
  }
4403
4428
  class CanvasManager {
4404
- element;
4429
+ domElement;
4405
4430
  render;
4431
+ renderCanvas;
4406
4432
  size;
4407
4433
  zoom = defaultZoom;
4408
4434
  _container;
@@ -4437,9 +4463,10 @@
4437
4463
  destroy() {
4438
4464
  this.stop();
4439
4465
  if (this._generated) {
4440
- const element = this.element;
4466
+ const element = this.domElement;
4441
4467
  element?.remove();
4442
- this.element = undefined;
4468
+ this.domElement = undefined;
4469
+ this.renderCanvas = undefined;
4443
4470
  }
4444
4471
  else {
4445
4472
  this._resetOriginalStyle();
@@ -4472,16 +4499,17 @@
4472
4499
  this._initStyle();
4473
4500
  this.initBackground();
4474
4501
  this._safeMutationObserver(obs => {
4475
- if (!this.element || !(this.element instanceof Node)) {
4502
+ const element = this.domElement;
4503
+ if (!element || !(element instanceof Node)) {
4476
4504
  return;
4477
4505
  }
4478
- obs.observe(this.element, { attributes: true });
4506
+ obs.observe(element, { attributes: true });
4479
4507
  });
4480
4508
  this.initPlugins();
4481
4509
  this.render.init();
4482
4510
  }
4483
4511
  initBackground() {
4484
- const { _container } = this, options = _container.actualOptions, background = options.background, element = this.element;
4512
+ const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
4485
4513
  if (!element) {
4486
4514
  return;
4487
4515
  }
@@ -4506,21 +4534,30 @@
4506
4534
  }
4507
4535
  }
4508
4536
  loadCanvas(canvas) {
4509
- if (this._generated && this.element) {
4510
- this.element.remove();
4537
+ if (this._generated && this.domElement) {
4538
+ this.domElement.remove();
4539
+ }
4540
+ const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4541
+ this.domElement = domCanvas;
4542
+ this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4543
+ this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
4544
+ const domElement = this.domElement;
4545
+ if (domElement) {
4546
+ domElement.ariaHidden = "true";
4547
+ this._originalStyle = cloneStyle(domElement.style);
4548
+ }
4549
+ const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
4550
+ if (domElement) {
4551
+ standardSize.height = domElement.offsetHeight;
4552
+ standardSize.width = domElement.offsetWidth;
4553
+ }
4554
+ else {
4555
+ standardSize.height = renderCanvas.height;
4556
+ standardSize.width = renderCanvas.width;
4511
4557
  }
4512
- const container = this._container;
4513
- this._generated =
4514
- generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
4515
- this.element = canvas;
4516
- this.element.ariaHidden = "true";
4517
- this._originalStyle = cloneStyle(this.element.style);
4518
- const standardSize = this._standardSize;
4519
- standardSize.height = canvas.offsetHeight;
4520
- standardSize.width = canvas.offsetWidth;
4521
4558
  const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
4522
- canvas.height = retinaSize.height = standardSize.height * pxRatio;
4523
- canvas.width = retinaSize.width = standardSize.width * pxRatio;
4559
+ renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4560
+ renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4524
4561
  const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4525
4562
  this.render.setContextSettings({
4526
4563
  alpha: true,
@@ -4528,42 +4565,48 @@
4528
4565
  desynchronized: true,
4529
4566
  willReadFrequently: false,
4530
4567
  });
4531
- this.render.setContext(this.element.getContext("2d", this.render.settings));
4568
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4532
4569
  this._safeMutationObserver(obs => {
4533
4570
  obs.disconnect();
4534
4571
  });
4535
4572
  container.retina.init();
4536
4573
  this.initBackground();
4537
4574
  this._safeMutationObserver(obs => {
4538
- if (!this.element || !(this.element instanceof Node)) {
4575
+ const element = this.domElement;
4576
+ if (!element || !(element instanceof Node)) {
4539
4577
  return;
4540
4578
  }
4541
- obs.observe(this.element, { attributes: true });
4579
+ obs.observe(element, { attributes: true });
4542
4580
  });
4543
4581
  }
4544
4582
  resize() {
4545
- if (!this.element) {
4583
+ const element = this.domElement;
4584
+ if (!element) {
4585
+ return false;
4586
+ }
4587
+ const container = this._container, renderCanvas = this.renderCanvas;
4588
+ if (renderCanvas === undefined) {
4546
4589
  return false;
4547
4590
  }
4548
- const container = this._container, currentSize = container.canvas._standardSize, newSize = {
4549
- width: this.element.offsetWidth,
4550
- height: this.element.offsetHeight,
4591
+ const currentSize = container.canvas._standardSize, newSize = {
4592
+ width: element.offsetWidth,
4593
+ height: element.offsetHeight,
4551
4594
  }, pxRatio = container.retina.pixelRatio, retinaSize = {
4552
4595
  width: newSize.width * pxRatio,
4553
4596
  height: newSize.height * pxRatio,
4554
4597
  };
4555
4598
  if (newSize.height === currentSize.height &&
4556
4599
  newSize.width === currentSize.width &&
4557
- retinaSize.height === this.element.height &&
4558
- retinaSize.width === this.element.width) {
4600
+ retinaSize.height === renderCanvas.height &&
4601
+ retinaSize.width === renderCanvas.width) {
4559
4602
  return false;
4560
4603
  }
4561
4604
  const oldSize = { ...currentSize };
4562
4605
  currentSize.height = newSize.height;
4563
4606
  currentSize.width = newSize.width;
4564
4607
  const canvasSize = this.size;
4565
- this.element.width = canvasSize.width = retinaSize.width;
4566
- this.element.height = canvasSize.height = retinaSize.height;
4608
+ renderCanvas.width = canvasSize.width = retinaSize.width;
4609
+ renderCanvas.height = canvasSize.height = retinaSize.height;
4567
4610
  if (this._container.started) {
4568
4611
  container.particles.setResizeFactor({
4569
4612
  width: currentSize.width / oldSize.width,
@@ -4573,7 +4616,7 @@
4573
4616
  return true;
4574
4617
  }
4575
4618
  setPointerEvents(type) {
4576
- const element = this.element;
4619
+ const element = this.domElement;
4577
4620
  if (!element) {
4578
4621
  return;
4579
4622
  }
@@ -4592,7 +4635,7 @@
4592
4635
  this.render.stop();
4593
4636
  }
4594
4637
  async windowResize() {
4595
- if (!this.element || !this.resize()) {
4638
+ if (!this.domElement || !this.resize()) {
4596
4639
  return;
4597
4640
  }
4598
4641
  const container = this._container, needsRefresh = container.updateActualOptions();
@@ -4608,7 +4651,7 @@
4608
4651
  }
4609
4652
  };
4610
4653
  _initStyle = () => {
4611
- const element = this.element, options = this._container.actualOptions;
4654
+ const element = this.domElement, options = this._container.actualOptions;
4612
4655
  if (!element) {
4613
4656
  return;
4614
4657
  }
@@ -4630,7 +4673,7 @@
4630
4673
  }
4631
4674
  };
4632
4675
  _repairStyle = () => {
4633
- const element = this.element;
4676
+ const element = this.domElement;
4634
4677
  if (!element) {
4635
4678
  return;
4636
4679
  }
@@ -4650,7 +4693,7 @@
4650
4693
  });
4651
4694
  };
4652
4695
  _resetOriginalStyle = () => {
4653
- const element = this.element, originalStyle = this._originalStyle;
4696
+ const element = this.domElement, originalStyle = this._originalStyle;
4654
4697
  if (!element || !originalStyle) {
4655
4698
  return;
4656
4699
  }
@@ -4663,7 +4706,7 @@
4663
4706
  callback(this._mutationObserver);
4664
4707
  };
4665
4708
  _setFullScreenStyle = () => {
4666
- const element = this.element;
4709
+ const element = this.domElement;
4667
4710
  if (!element) {
4668
4711
  return;
4669
4712
  }
@@ -4737,7 +4780,7 @@
4737
4780
  manageListener(globalThis, resizeEvent, handlers.resize, add);
4738
4781
  return;
4739
4782
  }
4740
- const canvasEl = container.canvas.element;
4783
+ const canvasEl = container.canvas.domElement;
4741
4784
  if (this._resizeObserver && !add) {
4742
4785
  if (canvasEl) {
4743
4786
  this._resizeObserver.unobserve(canvasEl);
@@ -4992,8 +5035,6 @@
4992
5035
  this._initPosition(position);
4993
5036
  this.initialVelocity = this._calculateVelocity();
4994
5037
  this.velocity = this.initialVelocity.copy();
4995
- const particles = container.particles;
4996
- particles.setLastZIndex(this.position.z);
4997
5038
  this.zIndexFactor = this.position.z / container.zLayers;
4998
5039
  this.sides = 24;
4999
5040
  let effectDrawer, shapeDrawer;
@@ -5143,7 +5184,7 @@
5143
5184
  return color;
5144
5185
  };
5145
5186
  _initPosition = position => {
5146
- const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5187
+ const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5147
5188
  if (!initialPosition) {
5148
5189
  throw new Error("a valid position cannot be found for particle");
5149
5190
  }
@@ -5277,10 +5318,8 @@
5277
5318
  _container;
5278
5319
  _groupLimits;
5279
5320
  _limit;
5280
- _maxZIndex;
5281
- _minZIndex;
5282
- _needsSort;
5283
5321
  _nextId;
5322
+ _particleBuckets;
5284
5323
  _particleResetPlugins;
5285
5324
  _particleUpdatePlugins;
5286
5325
  _pluginManager;
@@ -5289,19 +5328,17 @@
5289
5328
  _postUpdatePlugins;
5290
5329
  _resizeFactor;
5291
5330
  _updatePlugins;
5292
- _zArray;
5331
+ _zBuckets;
5293
5332
  constructor(pluginManager, container) {
5294
5333
  this._pluginManager = pluginManager;
5295
5334
  this._container = container;
5296
5335
  this._nextId = 0;
5297
5336
  this._array = [];
5298
- this._zArray = [];
5299
5337
  this._pool = [];
5300
5338
  this._limit = 0;
5301
5339
  this._groupLimits = new Map();
5302
- this._needsSort = false;
5303
- this._minZIndex = 0;
5304
- this._maxZIndex = 0;
5340
+ this._particleBuckets = new Map();
5341
+ this._zBuckets = this._createBuckets(this._container.zLayers);
5305
5342
  this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5306
5343
  this.checkParticlePositionPlugins = [];
5307
5344
  this._particleResetPlugins = [];
@@ -5343,7 +5380,7 @@
5343
5380
  return;
5344
5381
  }
5345
5382
  this._array.push(particle);
5346
- this._zArray.push(particle);
5383
+ this._insertParticleIntoBucket(particle);
5347
5384
  this._nextId++;
5348
5385
  this._container.dispatchEvent(EventType.particleAdded, {
5349
5386
  particle,
@@ -5357,12 +5394,14 @@
5357
5394
  }
5358
5395
  clear() {
5359
5396
  this._array = [];
5360
- this._zArray = [];
5397
+ this._particleBuckets.clear();
5398
+ this._resetBuckets(this._container.zLayers);
5361
5399
  }
5362
5400
  destroy() {
5363
5401
  this._array = [];
5364
5402
  this._pool.length = 0;
5365
- this._zArray = [];
5403
+ this._particleBuckets.clear();
5404
+ this._zBuckets = [];
5366
5405
  this.checkParticlePositionPlugins = [];
5367
5406
  this._particleResetPlugins = [];
5368
5407
  this._particleUpdatePlugins = [];
@@ -5371,8 +5410,14 @@
5371
5410
  this._updatePlugins = [];
5372
5411
  }
5373
5412
  drawParticles(delta) {
5374
- for (const particle of this._zArray) {
5375
- particle.draw(delta);
5413
+ for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
5414
+ const bucket = this._zBuckets[i];
5415
+ if (!bucket) {
5416
+ continue;
5417
+ }
5418
+ for (const particle of bucket) {
5419
+ particle.draw(delta);
5420
+ }
5376
5421
  }
5377
5422
  }
5378
5423
  filter(condition) {
@@ -5386,15 +5431,14 @@
5386
5431
  }
5387
5432
  async init() {
5388
5433
  const container = this._container, options = container.actualOptions;
5389
- this._minZIndex = 0;
5390
- this._maxZIndex = 0;
5391
- this._needsSort = false;
5392
5434
  this.checkParticlePositionPlugins = [];
5393
5435
  this._updatePlugins = [];
5394
5436
  this._particleUpdatePlugins = [];
5395
5437
  this._postUpdatePlugins = [];
5396
5438
  this._particleResetPlugins = [];
5397
5439
  this._postParticleUpdatePlugins = [];
5440
+ this._particleBuckets.clear();
5441
+ this._resetBuckets(container.zLayers);
5398
5442
  this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5399
5443
  for (const plugin of container.plugins) {
5400
5444
  if (plugin.redrawInit) {
@@ -5495,79 +5539,25 @@
5495
5539
  }
5496
5540
  this._applyDensity(options.particles, pluginsCount);
5497
5541
  }
5498
- setLastZIndex(zIndex) {
5499
- this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
5500
- }
5501
5542
  setResizeFactor(factor) {
5502
5543
  this._resizeFactor = factor;
5503
5544
  }
5504
5545
  update(delta) {
5505
- const particlesToDelete = new Set();
5506
5546
  this.grid.clear();
5507
5547
  for (const plugin of this._updatePlugins) {
5508
5548
  plugin.update?.(delta);
5509
5549
  }
5510
- const resizeFactor = this._resizeFactor;
5511
- for (const particle of this._array) {
5512
- if (resizeFactor && !particle.ignoresResizeRatio) {
5513
- particle.position.x *= resizeFactor.width;
5514
- particle.position.y *= resizeFactor.height;
5515
- particle.initialPosition.x *= resizeFactor.width;
5516
- particle.initialPosition.y *= resizeFactor.height;
5517
- }
5518
- particle.ignoresResizeRatio = false;
5519
- for (const plugin of this._particleResetPlugins) {
5520
- plugin.particleReset?.(particle);
5521
- }
5522
- for (const plugin of this._particleUpdatePlugins) {
5523
- if (particle.destroyed) {
5524
- break;
5525
- }
5526
- plugin.particleUpdate?.(particle, delta);
5527
- }
5528
- if (particle.destroyed) {
5529
- particlesToDelete.add(particle);
5530
- continue;
5531
- }
5532
- this.grid.insert(particle);
5533
- }
5550
+ const particlesToDelete = this._updateParticlesPhase1(delta);
5534
5551
  for (const plugin of this._postUpdatePlugins) {
5535
5552
  plugin.postUpdate?.(delta);
5536
5553
  }
5537
- for (const particle of this._array) {
5538
- if (particle.destroyed) {
5539
- particlesToDelete.add(particle);
5540
- continue;
5541
- }
5542
- for (const updater of this._container.particleUpdaters) {
5543
- updater.update(particle, delta);
5544
- }
5545
- if (!particle.destroyed && !particle.spawning) {
5546
- for (const plugin of this._postParticleUpdatePlugins) {
5547
- plugin.postParticleUpdate?.(particle, delta);
5548
- }
5549
- }
5550
- else if (particle.destroyed) {
5551
- particlesToDelete.add(particle);
5552
- }
5553
- }
5554
+ this._updateParticlesPhase2(delta, particlesToDelete);
5554
5555
  if (particlesToDelete.size) {
5555
5556
  for (const particle of particlesToDelete) {
5556
5557
  this.remove(particle);
5557
5558
  }
5558
5559
  }
5559
5560
  delete this._resizeFactor;
5560
- if (this._needsSort) {
5561
- const zArray = this._zArray;
5562
- zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
5563
- const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
5564
- if (!firstItem || !lastItem) {
5565
- return;
5566
- }
5567
- this._maxZIndex = firstItem.position.z;
5568
- this._minZIndex = lastItem.position.z;
5569
- this._needsSort = false;
5570
- }
5571
5561
  }
5572
5562
  _addToPool = (...particles) => {
5573
5563
  this._pool.push(...particles);
@@ -5597,13 +5587,52 @@
5597
5587
  this.removeQuantity(particlesCount - particlesNumber, group);
5598
5588
  }
5599
5589
  };
5590
+ _createBuckets = (zLayers) => {
5591
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5592
+ return Array.from({ length: bucketCount }, () => []);
5593
+ };
5594
+ _getBucketIndex = (zIndex) => {
5595
+ const maxBucketIndex = this._zBuckets.length - one;
5596
+ if (maxBucketIndex <= minIndex) {
5597
+ return minIndex;
5598
+ }
5599
+ return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5600
+ };
5601
+ _getParticleInsertIndex = (bucket, particleId) => {
5602
+ let start = minIndex, end = bucket.length;
5603
+ while (start < end) {
5604
+ const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5605
+ if (!middleParticle) {
5606
+ end = middle;
5607
+ continue;
5608
+ }
5609
+ if (middleParticle.id < particleId) {
5610
+ start = middle + one;
5611
+ }
5612
+ else {
5613
+ end = middle;
5614
+ }
5615
+ }
5616
+ return start;
5617
+ };
5600
5618
  _initDensityFactor = densityOptions => {
5601
5619
  const container = this._container;
5602
- if (!container.canvas.element || !densityOptions.enable) {
5620
+ if (!densityOptions.enable) {
5621
+ return defaultDensityFactor;
5622
+ }
5623
+ const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
5624
+ if (!canvasSize.width || !canvasSize.height) {
5603
5625
  return defaultDensityFactor;
5604
5626
  }
5605
- const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
5606
- return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
5627
+ return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5628
+ };
5629
+ _insertParticleIntoBucket = (particle) => {
5630
+ const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5631
+ if (!bucket) {
5632
+ return;
5633
+ }
5634
+ bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
5635
+ this._particleBuckets.set(particle.id, bucketIndex);
5607
5636
  };
5608
5637
  _removeParticle = (index, group, override) => {
5609
5638
  const particle = this._array[index];
@@ -5613,9 +5642,8 @@
5613
5642
  if (particle.group !== group) {
5614
5643
  return false;
5615
5644
  }
5616
- const zIdx = this._zArray.indexOf(particle);
5617
5645
  this._array.splice(index, deleteCount);
5618
- this._zArray.splice(zIdx, deleteCount);
5646
+ this._removeParticleFromBucket(particle);
5619
5647
  particle.destroy(override);
5620
5648
  this._container.dispatchEvent(EventType.particleRemoved, {
5621
5649
  particle,
@@ -5623,6 +5651,98 @@
5623
5651
  this._addToPool(particle);
5624
5652
  return true;
5625
5653
  };
5654
+ _removeParticleFromBucket = (particle) => {
5655
+ const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5656
+ if (!bucket) {
5657
+ this._particleBuckets.delete(particle.id);
5658
+ return;
5659
+ }
5660
+ const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
5661
+ if (bucket[particleIndex]?.id !== particle.id) {
5662
+ this._particleBuckets.delete(particle.id);
5663
+ return;
5664
+ }
5665
+ bucket.splice(particleIndex, deleteCount);
5666
+ this._particleBuckets.delete(particle.id);
5667
+ };
5668
+ _resetBuckets = (zLayers) => {
5669
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5670
+ if (this._zBuckets.length !== bucketCount) {
5671
+ this._zBuckets = this._createBuckets(bucketCount);
5672
+ return;
5673
+ }
5674
+ for (const bucket of this._zBuckets) {
5675
+ bucket.length = minIndex;
5676
+ }
5677
+ };
5678
+ _updateParticleBucket = (particle) => {
5679
+ const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
5680
+ if (currentBucketIndex === undefined) {
5681
+ this._insertParticleIntoBucket(particle);
5682
+ return;
5683
+ }
5684
+ if (currentBucketIndex === newBucketIndex) {
5685
+ return;
5686
+ }
5687
+ const currentBucket = this._zBuckets[currentBucketIndex];
5688
+ if (currentBucket) {
5689
+ const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
5690
+ if (currentBucket[particleIndex]?.id === particle.id) {
5691
+ currentBucket.splice(particleIndex, deleteCount);
5692
+ }
5693
+ }
5694
+ const newBucket = this._zBuckets[newBucketIndex];
5695
+ if (!newBucket) {
5696
+ this._particleBuckets.set(particle.id, newBucketIndex);
5697
+ return;
5698
+ }
5699
+ newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
5700
+ this._particleBuckets.set(particle.id, newBucketIndex);
5701
+ };
5702
+ _updateParticlesPhase1 = (delta) => {
5703
+ const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
5704
+ for (const particle of this._array) {
5705
+ if (resizeFactor && !particle.ignoresResizeRatio) {
5706
+ particle.position.x *= resizeFactor.width;
5707
+ particle.position.y *= resizeFactor.height;
5708
+ particle.initialPosition.x *= resizeFactor.width;
5709
+ particle.initialPosition.y *= resizeFactor.height;
5710
+ }
5711
+ particle.ignoresResizeRatio = false;
5712
+ for (const plugin of this._particleResetPlugins) {
5713
+ plugin.particleReset?.(particle);
5714
+ }
5715
+ for (const plugin of this._particleUpdatePlugins) {
5716
+ if (particle.destroyed) {
5717
+ break;
5718
+ }
5719
+ plugin.particleUpdate?.(particle, delta);
5720
+ }
5721
+ if (particle.destroyed) {
5722
+ particlesToDelete.add(particle);
5723
+ continue;
5724
+ }
5725
+ this.grid.insert(particle);
5726
+ }
5727
+ return particlesToDelete;
5728
+ };
5729
+ _updateParticlesPhase2 = (delta, particlesToDelete) => {
5730
+ for (const particle of this._array) {
5731
+ if (particle.destroyed) {
5732
+ particlesToDelete.add(particle);
5733
+ continue;
5734
+ }
5735
+ for (const updater of this._container.particleUpdaters) {
5736
+ updater.update(particle, delta);
5737
+ }
5738
+ if (!particle.spawning) {
5739
+ for (const plugin of this._postParticleUpdatePlugins) {
5740
+ plugin.postParticleUpdate?.(particle, delta);
5741
+ }
5742
+ }
5743
+ this._updateParticleBucket(particle);
5744
+ }
5745
+ };
5626
5746
  }
5627
5747
 
5628
5748
  class Retina {
@@ -5638,9 +5758,8 @@
5638
5758
  const container = this.container, options = container.actualOptions;
5639
5759
  this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
5640
5760
  this.reduceFactor = defaultReduceFactor;
5641
- const ratio = this.pixelRatio, canvas = container.canvas;
5642
- if (canvas.element) {
5643
- const element = canvas.element;
5761
+ const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
5762
+ if (element) {
5644
5763
  canvas.size.width = element.offsetWidth * ratio;
5645
5764
  canvas.size.height = element.offsetHeight * ratio;
5646
5765
  }