@tsparticles/preset-hyperspace 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$2 = 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$2 = 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) {
@@ -975,7 +975,7 @@
975
975
  }
976
976
  }
977
977
  else {
978
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases[canvasFirstIndex];
978
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
979
979
  if (foundCanvas) {
980
980
  canvasEl = foundCanvas;
981
981
  canvasEl.dataset[generatedAttribute] = generatedFalse;
@@ -1012,7 +1012,7 @@
1012
1012
  return this._domArray;
1013
1013
  }
1014
1014
  get version() {
1015
- return "4.0.0-beta.16";
1015
+ return "4.0.0";
1016
1016
  }
1017
1017
  addEventListener(type, listener) {
1018
1018
  this._eventDispatcher.addEventListener(type, listener);
@@ -1043,7 +1043,11 @@
1043
1043
  }
1044
1044
  async load(params) {
1045
1045
  await this.init();
1046
- 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({
1046
+ let domSourceElement;
1047
+ if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
1048
+ domSourceElement = params.element;
1049
+ }
1050
+ 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({
1047
1051
  dispatchCallback: (eventType, args) => {
1048
1052
  this.dispatchEvent(eventType, args);
1049
1053
  },
@@ -1070,8 +1074,10 @@
1070
1074
  else {
1071
1075
  items.push(newItem);
1072
1076
  }
1073
- const domContainer = getDomContainer(id, params.element), canvasEl = getCanvasFromContainer(domContainer);
1074
- newItem.canvas.loadCanvas(canvasEl);
1077
+ const sourceCanvas = typeof OffscreenCanvas !== "undefined" && params.element instanceof OffscreenCanvas
1078
+ ? params.element
1079
+ : getCanvasFromContainer(getDomContainer(id, domSourceElement));
1080
+ newItem.canvas.loadCanvas(sourceCanvas);
1075
1081
  await newItem.start();
1076
1082
  return newItem;
1077
1083
  }
@@ -2864,7 +2870,7 @@
2864
2870
  }
2865
2871
 
2866
2872
  async function loadCircleShape(engine) {
2867
- engine.checkVersion("4.0.0-beta.16");
2873
+ engine.checkVersion("4.0.0");
2868
2874
  await engine.pluginManager.register(e => {
2869
2875
  e.pluginManager.addShape(["circle"], () => {
2870
2876
  return Promise.resolve(new CircleDrawer());
@@ -2912,7 +2918,7 @@
2912
2918
  }
2913
2919
 
2914
2920
  async function loadHexColorPlugin(engine) {
2915
- engine.checkVersion("4.0.0-beta.16");
2921
+ engine.checkVersion("4.0.0");
2916
2922
  await engine.pluginManager.register(e => {
2917
2923
  e.pluginManager.addColorManager("hex", new HexColorManager());
2918
2924
  });
@@ -2965,7 +2971,7 @@
2965
2971
  }
2966
2972
 
2967
2973
  async function loadHslColorPlugin(engine) {
2968
- engine.checkVersion("4.0.0-beta.16");
2974
+ engine.checkVersion("4.0.0");
2969
2975
  await engine.pluginManager.register(e => {
2970
2976
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2971
2977
  });
@@ -2989,7 +2995,7 @@
2989
2995
  }
2990
2996
 
2991
2997
  async function loadMovePlugin(engine) {
2992
- engine.checkVersion("4.0.0-beta.16");
2998
+ engine.checkVersion("4.0.0");
2993
2999
  await engine.pluginManager.register(e => {
2994
3000
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2995
3001
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -3050,7 +3056,7 @@
3050
3056
  }
3051
3057
 
3052
3058
  async function loadOpacityUpdater(engine) {
3053
- engine.checkVersion("4.0.0-beta.16");
3059
+ engine.checkVersion("4.0.0");
3054
3060
  await engine.pluginManager.register(e => {
3055
3061
  e.pluginManager.addParticleUpdater("opacity", container => {
3056
3062
  return Promise.resolve(new OpacityUpdater(container));
@@ -3402,7 +3408,7 @@
3402
3408
  }
3403
3409
 
3404
3410
  async function loadOutModesUpdater(engine) {
3405
- engine.checkVersion("4.0.0-beta.16");
3411
+ engine.checkVersion("4.0.0");
3406
3412
  await engine.pluginManager.register(e => {
3407
3413
  e.pluginManager.addParticleUpdater("outModes", container => {
3408
3414
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3473,7 +3479,7 @@
3473
3479
  }
3474
3480
 
3475
3481
  async function loadPaintUpdater(engine) {
3476
- engine.checkVersion("4.0.0-beta.16");
3482
+ engine.checkVersion("4.0.0");
3477
3483
  await engine.pluginManager.register(e => {
3478
3484
  e.pluginManager.addParticleUpdater("paint", container => {
3479
3485
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3528,7 +3534,7 @@
3528
3534
  }
3529
3535
 
3530
3536
  async function loadRgbColorPlugin(engine) {
3531
- engine.checkVersion("4.0.0-beta.16");
3537
+ engine.checkVersion("4.0.0");
3532
3538
  await engine.pluginManager.register(e => {
3533
3539
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3534
3540
  });
@@ -3571,7 +3577,7 @@
3571
3577
  }
3572
3578
 
3573
3579
  async function loadSizeUpdater(engine) {
3574
- engine.checkVersion("4.0.0-beta.16");
3580
+ engine.checkVersion("4.0.0");
3575
3581
  await engine.pluginManager.register(e => {
3576
3582
  e.pluginManager.addParticleUpdater("size", container => {
3577
3583
  return Promise.resolve(new SizeUpdater(container));
@@ -3580,7 +3586,7 @@
3580
3586
  }
3581
3587
 
3582
3588
  async function loadBasic(engine) {
3583
- engine.checkVersion("4.0.0-beta.16");
3589
+ engine.checkVersion("4.0.0");
3584
3590
  await engine.pluginManager.register(async (e) => {
3585
3591
  await Promise.all([
3586
3592
  loadHexColorPlugin(e),
@@ -3881,7 +3887,7 @@
3881
3887
  })(EmitterClickMode || (EmitterClickMode = {}));
3882
3888
 
3883
3889
  async function loadEmittersPluginSimple(engine) {
3884
- engine.checkVersion("4.0.0-beta.16");
3890
+ engine.checkVersion("4.0.0");
3885
3891
  await engine.pluginManager.register(async (e) => {
3886
3892
  const instancesManager = await getEmittersInstancesManager(e);
3887
3893
  await addEmittersShapesManager(e);
@@ -3969,7 +3975,7 @@
3969
3975
  }
3970
3976
 
3971
3977
  async function loadEmittersShapeSquare(engine) {
3972
- engine.checkVersion("4.0.0-beta.16");
3978
+ engine.checkVersion("4.0.0");
3973
3979
  await engine.pluginManager.register((e) => {
3974
3980
  ensureEmittersPluginLoaded(e);
3975
3981
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -4135,7 +4141,7 @@
4135
4141
  }
4136
4142
 
4137
4143
  async function loadLifeUpdater(engine) {
4138
- engine.checkVersion("4.0.0-beta.16");
4144
+ engine.checkVersion("4.0.0");
4139
4145
  await engine.pluginManager.register(e => {
4140
4146
  e.pluginManager.addParticleUpdater("life", container => {
4141
4147
  return Promise.resolve(new LifeUpdater(container));
@@ -4210,7 +4216,7 @@
4210
4216
  }
4211
4217
 
4212
4218
  async function loadTrailPlugin(engine) {
4213
- engine.checkVersion("4.0.0-beta.16");
4219
+ engine.checkVersion("4.0.0");
4214
4220
  await engine.pluginManager.register(e => {
4215
4221
  e.pluginManager.addPlugin(new TrailPlugin(e.pluginManager));
4216
4222
  });
@@ -4600,6 +4606,25 @@
4600
4606
  };
4601
4607
  }
4602
4608
 
4609
+ const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
4610
+ const transferredCanvas = transferredCanvases.get(canvas);
4611
+ if (transferredCanvas) {
4612
+ return transferredCanvas;
4613
+ }
4614
+ if (typeof canvas.transferControlToOffscreen !== "function") {
4615
+ throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4616
+ }
4617
+ try {
4618
+ const offscreenCanvas = canvas.transferControlToOffscreen();
4619
+ transferredCanvases.set(canvas, offscreenCanvas);
4620
+ return offscreenCanvas;
4621
+ }
4622
+ catch {
4623
+ throw new TypeError("OffscreenCanvas transfer failed");
4624
+ }
4625
+ }, isHtmlCanvasElement = (canvas) => {
4626
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4627
+ };
4603
4628
  function setStyle(canvas, style, important = false) {
4604
4629
  if (!style) {
4605
4630
  return;
@@ -4630,8 +4655,9 @@
4630
4655
  }
4631
4656
  }
4632
4657
  class CanvasManager {
4633
- element;
4658
+ domElement;
4634
4659
  render;
4660
+ renderCanvas;
4635
4661
  size;
4636
4662
  zoom = defaultZoom;
4637
4663
  _container;
@@ -4666,9 +4692,10 @@
4666
4692
  destroy() {
4667
4693
  this.stop();
4668
4694
  if (this._generated) {
4669
- const element = this.element;
4695
+ const element = this.domElement;
4670
4696
  element?.remove();
4671
- this.element = undefined;
4697
+ this.domElement = undefined;
4698
+ this.renderCanvas = undefined;
4672
4699
  }
4673
4700
  else {
4674
4701
  this._resetOriginalStyle();
@@ -4701,16 +4728,17 @@
4701
4728
  this._initStyle();
4702
4729
  this.initBackground();
4703
4730
  this._safeMutationObserver(obs => {
4704
- if (!this.element || !(this.element instanceof Node)) {
4731
+ const element = this.domElement;
4732
+ if (!element || !(element instanceof Node)) {
4705
4733
  return;
4706
4734
  }
4707
- obs.observe(this.element, { attributes: true });
4735
+ obs.observe(element, { attributes: true });
4708
4736
  });
4709
4737
  this.initPlugins();
4710
4738
  this.render.init();
4711
4739
  }
4712
4740
  initBackground() {
4713
- const { _container } = this, options = _container.actualOptions, background = options.background, element = this.element;
4741
+ const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
4714
4742
  if (!element) {
4715
4743
  return;
4716
4744
  }
@@ -4735,21 +4763,30 @@
4735
4763
  }
4736
4764
  }
4737
4765
  loadCanvas(canvas) {
4738
- if (this._generated && this.element) {
4739
- this.element.remove();
4766
+ if (this._generated && this.domElement) {
4767
+ this.domElement.remove();
4768
+ }
4769
+ const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4770
+ this.domElement = domCanvas;
4771
+ this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4772
+ this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
4773
+ const domElement = this.domElement;
4774
+ if (domElement) {
4775
+ domElement.ariaHidden = "true";
4776
+ this._originalStyle = cloneStyle(domElement.style);
4777
+ }
4778
+ const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
4779
+ if (domElement) {
4780
+ standardSize.height = domElement.offsetHeight;
4781
+ standardSize.width = domElement.offsetWidth;
4782
+ }
4783
+ else {
4784
+ standardSize.height = renderCanvas.height;
4785
+ standardSize.width = renderCanvas.width;
4740
4786
  }
4741
- const container = this._container;
4742
- this._generated =
4743
- generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
4744
- this.element = canvas;
4745
- this.element.ariaHidden = "true";
4746
- this._originalStyle = cloneStyle(this.element.style);
4747
- const standardSize = this._standardSize;
4748
- standardSize.height = canvas.offsetHeight;
4749
- standardSize.width = canvas.offsetWidth;
4750
4787
  const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
4751
- canvas.height = retinaSize.height = standardSize.height * pxRatio;
4752
- canvas.width = retinaSize.width = standardSize.width * pxRatio;
4788
+ renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4789
+ renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4753
4790
  const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4754
4791
  this.render.setContextSettings({
4755
4792
  alpha: true,
@@ -4757,42 +4794,48 @@
4757
4794
  desynchronized: true,
4758
4795
  willReadFrequently: false,
4759
4796
  });
4760
- this.render.setContext(this.element.getContext("2d", this.render.settings));
4797
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4761
4798
  this._safeMutationObserver(obs => {
4762
4799
  obs.disconnect();
4763
4800
  });
4764
4801
  container.retina.init();
4765
4802
  this.initBackground();
4766
4803
  this._safeMutationObserver(obs => {
4767
- if (!this.element || !(this.element instanceof Node)) {
4804
+ const element = this.domElement;
4805
+ if (!element || !(element instanceof Node)) {
4768
4806
  return;
4769
4807
  }
4770
- obs.observe(this.element, { attributes: true });
4808
+ obs.observe(element, { attributes: true });
4771
4809
  });
4772
4810
  }
4773
4811
  resize() {
4774
- if (!this.element) {
4812
+ const element = this.domElement;
4813
+ if (!element) {
4814
+ return false;
4815
+ }
4816
+ const container = this._container, renderCanvas = this.renderCanvas;
4817
+ if (renderCanvas === undefined) {
4775
4818
  return false;
4776
4819
  }
4777
- const container = this._container, currentSize = container.canvas._standardSize, newSize = {
4778
- width: this.element.offsetWidth,
4779
- height: this.element.offsetHeight,
4820
+ const currentSize = container.canvas._standardSize, newSize = {
4821
+ width: element.offsetWidth,
4822
+ height: element.offsetHeight,
4780
4823
  }, pxRatio = container.retina.pixelRatio, retinaSize = {
4781
4824
  width: newSize.width * pxRatio,
4782
4825
  height: newSize.height * pxRatio,
4783
4826
  };
4784
4827
  if (newSize.height === currentSize.height &&
4785
4828
  newSize.width === currentSize.width &&
4786
- retinaSize.height === this.element.height &&
4787
- retinaSize.width === this.element.width) {
4829
+ retinaSize.height === renderCanvas.height &&
4830
+ retinaSize.width === renderCanvas.width) {
4788
4831
  return false;
4789
4832
  }
4790
4833
  const oldSize = { ...currentSize };
4791
4834
  currentSize.height = newSize.height;
4792
4835
  currentSize.width = newSize.width;
4793
4836
  const canvasSize = this.size;
4794
- this.element.width = canvasSize.width = retinaSize.width;
4795
- this.element.height = canvasSize.height = retinaSize.height;
4837
+ renderCanvas.width = canvasSize.width = retinaSize.width;
4838
+ renderCanvas.height = canvasSize.height = retinaSize.height;
4796
4839
  if (this._container.started) {
4797
4840
  container.particles.setResizeFactor({
4798
4841
  width: currentSize.width / oldSize.width,
@@ -4802,7 +4845,7 @@
4802
4845
  return true;
4803
4846
  }
4804
4847
  setPointerEvents(type) {
4805
- const element = this.element;
4848
+ const element = this.domElement;
4806
4849
  if (!element) {
4807
4850
  return;
4808
4851
  }
@@ -4821,7 +4864,7 @@
4821
4864
  this.render.stop();
4822
4865
  }
4823
4866
  async windowResize() {
4824
- if (!this.element || !this.resize()) {
4867
+ if (!this.domElement || !this.resize()) {
4825
4868
  return;
4826
4869
  }
4827
4870
  const container = this._container, needsRefresh = container.updateActualOptions();
@@ -4837,7 +4880,7 @@
4837
4880
  }
4838
4881
  };
4839
4882
  _initStyle = () => {
4840
- const element = this.element, options = this._container.actualOptions;
4883
+ const element = this.domElement, options = this._container.actualOptions;
4841
4884
  if (!element) {
4842
4885
  return;
4843
4886
  }
@@ -4859,7 +4902,7 @@
4859
4902
  }
4860
4903
  };
4861
4904
  _repairStyle = () => {
4862
- const element = this.element;
4905
+ const element = this.domElement;
4863
4906
  if (!element) {
4864
4907
  return;
4865
4908
  }
@@ -4879,7 +4922,7 @@
4879
4922
  });
4880
4923
  };
4881
4924
  _resetOriginalStyle = () => {
4882
- const element = this.element, originalStyle = this._originalStyle;
4925
+ const element = this.domElement, originalStyle = this._originalStyle;
4883
4926
  if (!element || !originalStyle) {
4884
4927
  return;
4885
4928
  }
@@ -4892,7 +4935,7 @@
4892
4935
  callback(this._mutationObserver);
4893
4936
  };
4894
4937
  _setFullScreenStyle = () => {
4895
- const element = this.element;
4938
+ const element = this.domElement;
4896
4939
  if (!element) {
4897
4940
  return;
4898
4941
  }
@@ -4966,7 +5009,7 @@
4966
5009
  manageListener(globalThis, resizeEvent, handlers.resize, add);
4967
5010
  return;
4968
5011
  }
4969
- const canvasEl = container.canvas.element;
5012
+ const canvasEl = container.canvas.domElement;
4970
5013
  if (this._resizeObserver && !add) {
4971
5014
  if (canvasEl) {
4972
5015
  this._resizeObserver.unobserve(canvasEl);
@@ -5221,8 +5264,6 @@
5221
5264
  this._initPosition(position);
5222
5265
  this.initialVelocity = this._calculateVelocity();
5223
5266
  this.velocity = this.initialVelocity.copy();
5224
- const particles = container.particles;
5225
- particles.setLastZIndex(this.position.z);
5226
5267
  this.zIndexFactor = this.position.z / container.zLayers;
5227
5268
  this.sides = 24;
5228
5269
  let effectDrawer, shapeDrawer;
@@ -5372,7 +5413,7 @@
5372
5413
  return color;
5373
5414
  };
5374
5415
  _initPosition = position => {
5375
- const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5416
+ const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5376
5417
  if (!initialPosition) {
5377
5418
  throw new Error("a valid position cannot be found for particle");
5378
5419
  }
@@ -5506,10 +5547,8 @@
5506
5547
  _container;
5507
5548
  _groupLimits;
5508
5549
  _limit;
5509
- _maxZIndex;
5510
- _minZIndex;
5511
- _needsSort;
5512
5550
  _nextId;
5551
+ _particleBuckets;
5513
5552
  _particleResetPlugins;
5514
5553
  _particleUpdatePlugins;
5515
5554
  _pluginManager;
@@ -5518,19 +5557,17 @@
5518
5557
  _postUpdatePlugins;
5519
5558
  _resizeFactor;
5520
5559
  _updatePlugins;
5521
- _zArray;
5560
+ _zBuckets;
5522
5561
  constructor(pluginManager, container) {
5523
5562
  this._pluginManager = pluginManager;
5524
5563
  this._container = container;
5525
5564
  this._nextId = 0;
5526
5565
  this._array = [];
5527
- this._zArray = [];
5528
5566
  this._pool = [];
5529
5567
  this._limit = 0;
5530
5568
  this._groupLimits = new Map();
5531
- this._needsSort = false;
5532
- this._minZIndex = 0;
5533
- this._maxZIndex = 0;
5569
+ this._particleBuckets = new Map();
5570
+ this._zBuckets = this._createBuckets(this._container.zLayers);
5534
5571
  this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5535
5572
  this.checkParticlePositionPlugins = [];
5536
5573
  this._particleResetPlugins = [];
@@ -5572,7 +5609,7 @@
5572
5609
  return;
5573
5610
  }
5574
5611
  this._array.push(particle);
5575
- this._zArray.push(particle);
5612
+ this._insertParticleIntoBucket(particle);
5576
5613
  this._nextId++;
5577
5614
  this._container.dispatchEvent(EventType.particleAdded, {
5578
5615
  particle,
@@ -5586,12 +5623,14 @@
5586
5623
  }
5587
5624
  clear() {
5588
5625
  this._array = [];
5589
- this._zArray = [];
5626
+ this._particleBuckets.clear();
5627
+ this._resetBuckets(this._container.zLayers);
5590
5628
  }
5591
5629
  destroy() {
5592
5630
  this._array = [];
5593
5631
  this._pool.length = 0;
5594
- this._zArray = [];
5632
+ this._particleBuckets.clear();
5633
+ this._zBuckets = [];
5595
5634
  this.checkParticlePositionPlugins = [];
5596
5635
  this._particleResetPlugins = [];
5597
5636
  this._particleUpdatePlugins = [];
@@ -5600,8 +5639,14 @@
5600
5639
  this._updatePlugins = [];
5601
5640
  }
5602
5641
  drawParticles(delta) {
5603
- for (const particle of this._zArray) {
5604
- particle.draw(delta);
5642
+ for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
5643
+ const bucket = this._zBuckets[i];
5644
+ if (!bucket) {
5645
+ continue;
5646
+ }
5647
+ for (const particle of bucket) {
5648
+ particle.draw(delta);
5649
+ }
5605
5650
  }
5606
5651
  }
5607
5652
  filter(condition) {
@@ -5615,15 +5660,14 @@
5615
5660
  }
5616
5661
  async init() {
5617
5662
  const container = this._container, options = container.actualOptions;
5618
- this._minZIndex = 0;
5619
- this._maxZIndex = 0;
5620
- this._needsSort = false;
5621
5663
  this.checkParticlePositionPlugins = [];
5622
5664
  this._updatePlugins = [];
5623
5665
  this._particleUpdatePlugins = [];
5624
5666
  this._postUpdatePlugins = [];
5625
5667
  this._particleResetPlugins = [];
5626
5668
  this._postParticleUpdatePlugins = [];
5669
+ this._particleBuckets.clear();
5670
+ this._resetBuckets(container.zLayers);
5627
5671
  this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5628
5672
  for (const plugin of container.plugins) {
5629
5673
  if (plugin.redrawInit) {
@@ -5724,79 +5768,25 @@
5724
5768
  }
5725
5769
  this._applyDensity(options.particles, pluginsCount);
5726
5770
  }
5727
- setLastZIndex(zIndex) {
5728
- this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
5729
- }
5730
5771
  setResizeFactor(factor) {
5731
5772
  this._resizeFactor = factor;
5732
5773
  }
5733
5774
  update(delta) {
5734
- const particlesToDelete = new Set();
5735
5775
  this.grid.clear();
5736
5776
  for (const plugin of this._updatePlugins) {
5737
5777
  plugin.update?.(delta);
5738
5778
  }
5739
- const resizeFactor = this._resizeFactor;
5740
- for (const particle of this._array) {
5741
- if (resizeFactor && !particle.ignoresResizeRatio) {
5742
- particle.position.x *= resizeFactor.width;
5743
- particle.position.y *= resizeFactor.height;
5744
- particle.initialPosition.x *= resizeFactor.width;
5745
- particle.initialPosition.y *= resizeFactor.height;
5746
- }
5747
- particle.ignoresResizeRatio = false;
5748
- for (const plugin of this._particleResetPlugins) {
5749
- plugin.particleReset?.(particle);
5750
- }
5751
- for (const plugin of this._particleUpdatePlugins) {
5752
- if (particle.destroyed) {
5753
- break;
5754
- }
5755
- plugin.particleUpdate?.(particle, delta);
5756
- }
5757
- if (particle.destroyed) {
5758
- particlesToDelete.add(particle);
5759
- continue;
5760
- }
5761
- this.grid.insert(particle);
5762
- }
5779
+ const particlesToDelete = this._updateParticlesPhase1(delta);
5763
5780
  for (const plugin of this._postUpdatePlugins) {
5764
5781
  plugin.postUpdate?.(delta);
5765
5782
  }
5766
- for (const particle of this._array) {
5767
- if (particle.destroyed) {
5768
- particlesToDelete.add(particle);
5769
- continue;
5770
- }
5771
- for (const updater of this._container.particleUpdaters) {
5772
- updater.update(particle, delta);
5773
- }
5774
- if (!particle.destroyed && !particle.spawning) {
5775
- for (const plugin of this._postParticleUpdatePlugins) {
5776
- plugin.postParticleUpdate?.(particle, delta);
5777
- }
5778
- }
5779
- else if (particle.destroyed) {
5780
- particlesToDelete.add(particle);
5781
- }
5782
- }
5783
+ this._updateParticlesPhase2(delta, particlesToDelete);
5783
5784
  if (particlesToDelete.size) {
5784
5785
  for (const particle of particlesToDelete) {
5785
5786
  this.remove(particle);
5786
5787
  }
5787
5788
  }
5788
5789
  delete this._resizeFactor;
5789
- if (this._needsSort) {
5790
- const zArray = this._zArray;
5791
- zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
5792
- const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
5793
- if (!firstItem || !lastItem) {
5794
- return;
5795
- }
5796
- this._maxZIndex = firstItem.position.z;
5797
- this._minZIndex = lastItem.position.z;
5798
- this._needsSort = false;
5799
- }
5800
5790
  }
5801
5791
  _addToPool = (...particles) => {
5802
5792
  this._pool.push(...particles);
@@ -5826,13 +5816,52 @@
5826
5816
  this.removeQuantity(particlesCount - particlesNumber, group);
5827
5817
  }
5828
5818
  };
5819
+ _createBuckets = (zLayers) => {
5820
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5821
+ return Array.from({ length: bucketCount }, () => []);
5822
+ };
5823
+ _getBucketIndex = (zIndex) => {
5824
+ const maxBucketIndex = this._zBuckets.length - one;
5825
+ if (maxBucketIndex <= minIndex) {
5826
+ return minIndex;
5827
+ }
5828
+ return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5829
+ };
5830
+ _getParticleInsertIndex = (bucket, particleId) => {
5831
+ let start = minIndex, end = bucket.length;
5832
+ while (start < end) {
5833
+ const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5834
+ if (!middleParticle) {
5835
+ end = middle;
5836
+ continue;
5837
+ }
5838
+ if (middleParticle.id < particleId) {
5839
+ start = middle + one;
5840
+ }
5841
+ else {
5842
+ end = middle;
5843
+ }
5844
+ }
5845
+ return start;
5846
+ };
5829
5847
  _initDensityFactor = densityOptions => {
5830
5848
  const container = this._container;
5831
- if (!container.canvas.element || !densityOptions.enable) {
5849
+ if (!densityOptions.enable) {
5850
+ return defaultDensityFactor;
5851
+ }
5852
+ const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
5853
+ if (!canvasSize.width || !canvasSize.height) {
5832
5854
  return defaultDensityFactor;
5833
5855
  }
5834
- const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
5835
- return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
5856
+ return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5857
+ };
5858
+ _insertParticleIntoBucket = (particle) => {
5859
+ const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5860
+ if (!bucket) {
5861
+ return;
5862
+ }
5863
+ bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
5864
+ this._particleBuckets.set(particle.id, bucketIndex);
5836
5865
  };
5837
5866
  _removeParticle = (index, group, override) => {
5838
5867
  const particle = this._array[index];
@@ -5842,9 +5871,8 @@
5842
5871
  if (particle.group !== group) {
5843
5872
  return false;
5844
5873
  }
5845
- const zIdx = this._zArray.indexOf(particle);
5846
5874
  this._array.splice(index, deleteCount);
5847
- this._zArray.splice(zIdx, deleteCount);
5875
+ this._removeParticleFromBucket(particle);
5848
5876
  particle.destroy(override);
5849
5877
  this._container.dispatchEvent(EventType.particleRemoved, {
5850
5878
  particle,
@@ -5852,6 +5880,98 @@
5852
5880
  this._addToPool(particle);
5853
5881
  return true;
5854
5882
  };
5883
+ _removeParticleFromBucket = (particle) => {
5884
+ const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5885
+ if (!bucket) {
5886
+ this._particleBuckets.delete(particle.id);
5887
+ return;
5888
+ }
5889
+ const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
5890
+ if (bucket[particleIndex]?.id !== particle.id) {
5891
+ this._particleBuckets.delete(particle.id);
5892
+ return;
5893
+ }
5894
+ bucket.splice(particleIndex, deleteCount);
5895
+ this._particleBuckets.delete(particle.id);
5896
+ };
5897
+ _resetBuckets = (zLayers) => {
5898
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5899
+ if (this._zBuckets.length !== bucketCount) {
5900
+ this._zBuckets = this._createBuckets(bucketCount);
5901
+ return;
5902
+ }
5903
+ for (const bucket of this._zBuckets) {
5904
+ bucket.length = minIndex;
5905
+ }
5906
+ };
5907
+ _updateParticleBucket = (particle) => {
5908
+ const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
5909
+ if (currentBucketIndex === undefined) {
5910
+ this._insertParticleIntoBucket(particle);
5911
+ return;
5912
+ }
5913
+ if (currentBucketIndex === newBucketIndex) {
5914
+ return;
5915
+ }
5916
+ const currentBucket = this._zBuckets[currentBucketIndex];
5917
+ if (currentBucket) {
5918
+ const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
5919
+ if (currentBucket[particleIndex]?.id === particle.id) {
5920
+ currentBucket.splice(particleIndex, deleteCount);
5921
+ }
5922
+ }
5923
+ const newBucket = this._zBuckets[newBucketIndex];
5924
+ if (!newBucket) {
5925
+ this._particleBuckets.set(particle.id, newBucketIndex);
5926
+ return;
5927
+ }
5928
+ newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
5929
+ this._particleBuckets.set(particle.id, newBucketIndex);
5930
+ };
5931
+ _updateParticlesPhase1 = (delta) => {
5932
+ const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
5933
+ for (const particle of this._array) {
5934
+ if (resizeFactor && !particle.ignoresResizeRatio) {
5935
+ particle.position.x *= resizeFactor.width;
5936
+ particle.position.y *= resizeFactor.height;
5937
+ particle.initialPosition.x *= resizeFactor.width;
5938
+ particle.initialPosition.y *= resizeFactor.height;
5939
+ }
5940
+ particle.ignoresResizeRatio = false;
5941
+ for (const plugin of this._particleResetPlugins) {
5942
+ plugin.particleReset?.(particle);
5943
+ }
5944
+ for (const plugin of this._particleUpdatePlugins) {
5945
+ if (particle.destroyed) {
5946
+ break;
5947
+ }
5948
+ plugin.particleUpdate?.(particle, delta);
5949
+ }
5950
+ if (particle.destroyed) {
5951
+ particlesToDelete.add(particle);
5952
+ continue;
5953
+ }
5954
+ this.grid.insert(particle);
5955
+ }
5956
+ return particlesToDelete;
5957
+ };
5958
+ _updateParticlesPhase2 = (delta, particlesToDelete) => {
5959
+ for (const particle of this._array) {
5960
+ if (particle.destroyed) {
5961
+ particlesToDelete.add(particle);
5962
+ continue;
5963
+ }
5964
+ for (const updater of this._container.particleUpdaters) {
5965
+ updater.update(particle, delta);
5966
+ }
5967
+ if (!particle.spawning) {
5968
+ for (const plugin of this._postParticleUpdatePlugins) {
5969
+ plugin.postParticleUpdate?.(particle, delta);
5970
+ }
5971
+ }
5972
+ this._updateParticleBucket(particle);
5973
+ }
5974
+ };
5855
5975
  }
5856
5976
 
5857
5977
  class Retina {
@@ -5867,9 +5987,8 @@
5867
5987
  const container = this.container, options = container.actualOptions;
5868
5988
  this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
5869
5989
  this.reduceFactor = defaultReduceFactor;
5870
- const ratio = this.pixelRatio, canvas = container.canvas;
5871
- if (canvas.element) {
5872
- const element = canvas.element;
5990
+ const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
5991
+ if (element) {
5873
5992
  canvas.size.width = element.offsetWidth * ratio;
5874
5993
  canvas.size.height = element.offsetHeight * ratio;
5875
5994
  }