@tsparticles/preset-firefly 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.
@@ -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-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) :
@@ -965,7 +965,7 @@
965
965
  }
966
966
  }
967
967
  else {
968
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases[canvasFirstIndex];
968
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
969
969
  if (foundCanvas) {
970
970
  canvasEl = foundCanvas;
971
971
  canvasEl.dataset[generatedAttribute] = generatedFalse;
@@ -1002,7 +1002,7 @@
1002
1002
  return this._domArray;
1003
1003
  }
1004
1004
  get version() {
1005
- return "4.0.0-beta.16";
1005
+ return "4.0.0-beta.17";
1006
1006
  }
1007
1007
  addEventListener(type, listener) {
1008
1008
  this._eventDispatcher.addEventListener(type, listener);
@@ -1033,7 +1033,11 @@
1033
1033
  }
1034
1034
  async load(params) {
1035
1035
  await this.init();
1036
- 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({
1036
+ let domSourceElement;
1037
+ if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
1038
+ domSourceElement = params.element;
1039
+ }
1040
+ 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({
1037
1041
  dispatchCallback: (eventType, args) => {
1038
1042
  this.dispatchEvent(eventType, args);
1039
1043
  },
@@ -1060,8 +1064,10 @@
1060
1064
  else {
1061
1065
  items.push(newItem);
1062
1066
  }
1063
- const domContainer = getDomContainer(id, params.element), canvasEl = getCanvasFromContainer(domContainer);
1064
- newItem.canvas.loadCanvas(canvasEl);
1067
+ const sourceCanvas = typeof OffscreenCanvas !== "undefined" && params.element instanceof OffscreenCanvas
1068
+ ? params.element
1069
+ : getCanvasFromContainer(getDomContainer(id, domSourceElement));
1070
+ newItem.canvas.loadCanvas(sourceCanvas);
1065
1071
  await newItem.start();
1066
1072
  return newItem;
1067
1073
  }
@@ -2854,7 +2860,7 @@
2854
2860
  }
2855
2861
 
2856
2862
  async function loadCircleShape(engine) {
2857
- engine.checkVersion("4.0.0-beta.16");
2863
+ engine.checkVersion("4.0.0-beta.17");
2858
2864
  await engine.pluginManager.register(e => {
2859
2865
  e.pluginManager.addShape(["circle"], () => {
2860
2866
  return Promise.resolve(new CircleDrawer());
@@ -2902,7 +2908,7 @@
2902
2908
  }
2903
2909
 
2904
2910
  async function loadHexColorPlugin(engine) {
2905
- engine.checkVersion("4.0.0-beta.16");
2911
+ engine.checkVersion("4.0.0-beta.17");
2906
2912
  await engine.pluginManager.register(e => {
2907
2913
  e.pluginManager.addColorManager("hex", new HexColorManager());
2908
2914
  });
@@ -2955,7 +2961,7 @@
2955
2961
  }
2956
2962
 
2957
2963
  async function loadHslColorPlugin(engine) {
2958
- engine.checkVersion("4.0.0-beta.16");
2964
+ engine.checkVersion("4.0.0-beta.17");
2959
2965
  await engine.pluginManager.register(e => {
2960
2966
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2961
2967
  });
@@ -2979,7 +2985,7 @@
2979
2985
  }
2980
2986
 
2981
2987
  async function loadMovePlugin(engine) {
2982
- engine.checkVersion("4.0.0-beta.16");
2988
+ engine.checkVersion("4.0.0-beta.17");
2983
2989
  await engine.pluginManager.register(e => {
2984
2990
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2985
2991
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -3040,7 +3046,7 @@
3040
3046
  }
3041
3047
 
3042
3048
  async function loadOpacityUpdater(engine) {
3043
- engine.checkVersion("4.0.0-beta.16");
3049
+ engine.checkVersion("4.0.0-beta.17");
3044
3050
  await engine.pluginManager.register(e => {
3045
3051
  e.pluginManager.addParticleUpdater("opacity", container => {
3046
3052
  return Promise.resolve(new OpacityUpdater(container));
@@ -3392,7 +3398,7 @@
3392
3398
  }
3393
3399
 
3394
3400
  async function loadOutModesUpdater(engine) {
3395
- engine.checkVersion("4.0.0-beta.16");
3401
+ engine.checkVersion("4.0.0-beta.17");
3396
3402
  await engine.pluginManager.register(e => {
3397
3403
  e.pluginManager.addParticleUpdater("outModes", container => {
3398
3404
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3463,7 +3469,7 @@
3463
3469
  }
3464
3470
 
3465
3471
  async function loadPaintUpdater(engine) {
3466
- engine.checkVersion("4.0.0-beta.16");
3472
+ engine.checkVersion("4.0.0-beta.17");
3467
3473
  await engine.pluginManager.register(e => {
3468
3474
  e.pluginManager.addParticleUpdater("paint", container => {
3469
3475
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3518,7 +3524,7 @@
3518
3524
  }
3519
3525
 
3520
3526
  async function loadRgbColorPlugin(engine) {
3521
- engine.checkVersion("4.0.0-beta.16");
3527
+ engine.checkVersion("4.0.0-beta.17");
3522
3528
  await engine.pluginManager.register(e => {
3523
3529
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3524
3530
  });
@@ -3561,7 +3567,7 @@
3561
3567
  }
3562
3568
 
3563
3569
  async function loadSizeUpdater(engine) {
3564
- engine.checkVersion("4.0.0-beta.16");
3570
+ engine.checkVersion("4.0.0-beta.17");
3565
3571
  await engine.pluginManager.register(e => {
3566
3572
  e.pluginManager.addParticleUpdater("size", container => {
3567
3573
  return Promise.resolve(new SizeUpdater(container));
@@ -3570,7 +3576,7 @@
3570
3576
  }
3571
3577
 
3572
3578
  async function loadBasic(engine) {
3573
- engine.checkVersion("4.0.0-beta.16");
3579
+ engine.checkVersion("4.0.0-beta.17");
3574
3580
  await engine.pluginManager.register(async (e) => {
3575
3581
  await Promise.all([
3576
3582
  loadHexColorPlugin(e),
@@ -3807,7 +3813,7 @@
3807
3813
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3808
3814
 
3809
3815
  async function loadInteractivityPlugin(engine) {
3810
- engine.checkVersion("4.0.0-beta.16");
3816
+ engine.checkVersion("4.0.0-beta.17");
3811
3817
  await engine.pluginManager.register(e => {
3812
3818
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3813
3819
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -4035,7 +4041,7 @@
4035
4041
  }
4036
4042
 
4037
4043
  async function loadExternalTrailInteraction(engine) {
4038
- engine.checkVersion("4.0.0-beta.16");
4044
+ engine.checkVersion("4.0.0-beta.17");
4039
4045
  await engine.pluginManager.register((e) => {
4040
4046
  ensureInteractivityPluginLoaded(e);
4041
4047
  e.pluginManager.addInteractor?.("externalTrail", container => {
@@ -4203,7 +4209,7 @@
4203
4209
  }
4204
4210
 
4205
4211
  async function loadLifeUpdater(engine) {
4206
- engine.checkVersion("4.0.0-beta.16");
4212
+ engine.checkVersion("4.0.0-beta.17");
4207
4213
  await engine.pluginManager.register(e => {
4208
4214
  e.pluginManager.addParticleUpdater("life", container => {
4209
4215
  return Promise.resolve(new LifeUpdater(container));
@@ -4595,6 +4601,25 @@
4595
4601
  };
4596
4602
  }
4597
4603
 
4604
+ const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
4605
+ const transferredCanvas = transferredCanvases.get(canvas);
4606
+ if (transferredCanvas) {
4607
+ return transferredCanvas;
4608
+ }
4609
+ if (typeof canvas.transferControlToOffscreen !== "function") {
4610
+ throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4611
+ }
4612
+ try {
4613
+ const offscreenCanvas = canvas.transferControlToOffscreen();
4614
+ transferredCanvases.set(canvas, offscreenCanvas);
4615
+ return offscreenCanvas;
4616
+ }
4617
+ catch {
4618
+ throw new TypeError("OffscreenCanvas transfer failed");
4619
+ }
4620
+ }, isHtmlCanvasElement = (canvas) => {
4621
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4622
+ };
4598
4623
  function setStyle(canvas, style, important = false) {
4599
4624
  if (!style) {
4600
4625
  return;
@@ -4625,8 +4650,9 @@
4625
4650
  }
4626
4651
  }
4627
4652
  class CanvasManager {
4628
- element;
4653
+ domElement;
4629
4654
  render;
4655
+ renderCanvas;
4630
4656
  size;
4631
4657
  zoom = defaultZoom;
4632
4658
  _container;
@@ -4661,9 +4687,10 @@
4661
4687
  destroy() {
4662
4688
  this.stop();
4663
4689
  if (this._generated) {
4664
- const element = this.element;
4690
+ const element = this.domElement;
4665
4691
  element?.remove();
4666
- this.element = undefined;
4692
+ this.domElement = undefined;
4693
+ this.renderCanvas = undefined;
4667
4694
  }
4668
4695
  else {
4669
4696
  this._resetOriginalStyle();
@@ -4696,16 +4723,17 @@
4696
4723
  this._initStyle();
4697
4724
  this.initBackground();
4698
4725
  this._safeMutationObserver(obs => {
4699
- if (!this.element || !(this.element instanceof Node)) {
4726
+ const element = this.domElement;
4727
+ if (!element || !(element instanceof Node)) {
4700
4728
  return;
4701
4729
  }
4702
- obs.observe(this.element, { attributes: true });
4730
+ obs.observe(element, { attributes: true });
4703
4731
  });
4704
4732
  this.initPlugins();
4705
4733
  this.render.init();
4706
4734
  }
4707
4735
  initBackground() {
4708
- const { _container } = this, options = _container.actualOptions, background = options.background, element = this.element;
4736
+ const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
4709
4737
  if (!element) {
4710
4738
  return;
4711
4739
  }
@@ -4730,21 +4758,30 @@
4730
4758
  }
4731
4759
  }
4732
4760
  loadCanvas(canvas) {
4733
- if (this._generated && this.element) {
4734
- this.element.remove();
4761
+ if (this._generated && this.domElement) {
4762
+ this.domElement.remove();
4763
+ }
4764
+ const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4765
+ this.domElement = domCanvas;
4766
+ this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4767
+ this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
4768
+ const domElement = this.domElement;
4769
+ if (domElement) {
4770
+ domElement.ariaHidden = "true";
4771
+ this._originalStyle = cloneStyle(domElement.style);
4772
+ }
4773
+ const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
4774
+ if (domElement) {
4775
+ standardSize.height = domElement.offsetHeight;
4776
+ standardSize.width = domElement.offsetWidth;
4777
+ }
4778
+ else {
4779
+ standardSize.height = renderCanvas.height;
4780
+ standardSize.width = renderCanvas.width;
4735
4781
  }
4736
- const container = this._container;
4737
- this._generated =
4738
- generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
4739
- this.element = canvas;
4740
- this.element.ariaHidden = "true";
4741
- this._originalStyle = cloneStyle(this.element.style);
4742
- const standardSize = this._standardSize;
4743
- standardSize.height = canvas.offsetHeight;
4744
- standardSize.width = canvas.offsetWidth;
4745
4782
  const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
4746
- canvas.height = retinaSize.height = standardSize.height * pxRatio;
4747
- canvas.width = retinaSize.width = standardSize.width * pxRatio;
4783
+ renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4784
+ renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4748
4785
  const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4749
4786
  this.render.setContextSettings({
4750
4787
  alpha: true,
@@ -4752,42 +4789,48 @@
4752
4789
  desynchronized: true,
4753
4790
  willReadFrequently: false,
4754
4791
  });
4755
- this.render.setContext(this.element.getContext("2d", this.render.settings));
4792
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4756
4793
  this._safeMutationObserver(obs => {
4757
4794
  obs.disconnect();
4758
4795
  });
4759
4796
  container.retina.init();
4760
4797
  this.initBackground();
4761
4798
  this._safeMutationObserver(obs => {
4762
- if (!this.element || !(this.element instanceof Node)) {
4799
+ const element = this.domElement;
4800
+ if (!element || !(element instanceof Node)) {
4763
4801
  return;
4764
4802
  }
4765
- obs.observe(this.element, { attributes: true });
4803
+ obs.observe(element, { attributes: true });
4766
4804
  });
4767
4805
  }
4768
4806
  resize() {
4769
- if (!this.element) {
4807
+ const element = this.domElement;
4808
+ if (!element) {
4809
+ return false;
4810
+ }
4811
+ const container = this._container, renderCanvas = this.renderCanvas;
4812
+ if (renderCanvas === undefined) {
4770
4813
  return false;
4771
4814
  }
4772
- const container = this._container, currentSize = container.canvas._standardSize, newSize = {
4773
- width: this.element.offsetWidth,
4774
- height: this.element.offsetHeight,
4815
+ const currentSize = container.canvas._standardSize, newSize = {
4816
+ width: element.offsetWidth,
4817
+ height: element.offsetHeight,
4775
4818
  }, pxRatio = container.retina.pixelRatio, retinaSize = {
4776
4819
  width: newSize.width * pxRatio,
4777
4820
  height: newSize.height * pxRatio,
4778
4821
  };
4779
4822
  if (newSize.height === currentSize.height &&
4780
4823
  newSize.width === currentSize.width &&
4781
- retinaSize.height === this.element.height &&
4782
- retinaSize.width === this.element.width) {
4824
+ retinaSize.height === renderCanvas.height &&
4825
+ retinaSize.width === renderCanvas.width) {
4783
4826
  return false;
4784
4827
  }
4785
4828
  const oldSize = { ...currentSize };
4786
4829
  currentSize.height = newSize.height;
4787
4830
  currentSize.width = newSize.width;
4788
4831
  const canvasSize = this.size;
4789
- this.element.width = canvasSize.width = retinaSize.width;
4790
- this.element.height = canvasSize.height = retinaSize.height;
4832
+ renderCanvas.width = canvasSize.width = retinaSize.width;
4833
+ renderCanvas.height = canvasSize.height = retinaSize.height;
4791
4834
  if (this._container.started) {
4792
4835
  container.particles.setResizeFactor({
4793
4836
  width: currentSize.width / oldSize.width,
@@ -4797,7 +4840,7 @@
4797
4840
  return true;
4798
4841
  }
4799
4842
  setPointerEvents(type) {
4800
- const element = this.element;
4843
+ const element = this.domElement;
4801
4844
  if (!element) {
4802
4845
  return;
4803
4846
  }
@@ -4816,7 +4859,7 @@
4816
4859
  this.render.stop();
4817
4860
  }
4818
4861
  async windowResize() {
4819
- if (!this.element || !this.resize()) {
4862
+ if (!this.domElement || !this.resize()) {
4820
4863
  return;
4821
4864
  }
4822
4865
  const container = this._container, needsRefresh = container.updateActualOptions();
@@ -4832,7 +4875,7 @@
4832
4875
  }
4833
4876
  };
4834
4877
  _initStyle = () => {
4835
- const element = this.element, options = this._container.actualOptions;
4878
+ const element = this.domElement, options = this._container.actualOptions;
4836
4879
  if (!element) {
4837
4880
  return;
4838
4881
  }
@@ -4854,7 +4897,7 @@
4854
4897
  }
4855
4898
  };
4856
4899
  _repairStyle = () => {
4857
- const element = this.element;
4900
+ const element = this.domElement;
4858
4901
  if (!element) {
4859
4902
  return;
4860
4903
  }
@@ -4874,7 +4917,7 @@
4874
4917
  });
4875
4918
  };
4876
4919
  _resetOriginalStyle = () => {
4877
- const element = this.element, originalStyle = this._originalStyle;
4920
+ const element = this.domElement, originalStyle = this._originalStyle;
4878
4921
  if (!element || !originalStyle) {
4879
4922
  return;
4880
4923
  }
@@ -4887,7 +4930,7 @@
4887
4930
  callback(this._mutationObserver);
4888
4931
  };
4889
4932
  _setFullScreenStyle = () => {
4890
- const element = this.element;
4933
+ const element = this.domElement;
4891
4934
  if (!element) {
4892
4935
  return;
4893
4936
  }
@@ -4961,7 +5004,7 @@
4961
5004
  manageListener(globalThis, resizeEvent, handlers.resize, add);
4962
5005
  return;
4963
5006
  }
4964
- const canvasEl = container.canvas.element;
5007
+ const canvasEl = container.canvas.domElement;
4965
5008
  if (this._resizeObserver && !add) {
4966
5009
  if (canvasEl) {
4967
5010
  this._resizeObserver.unobserve(canvasEl);
@@ -5216,8 +5259,6 @@
5216
5259
  this._initPosition(position);
5217
5260
  this.initialVelocity = this._calculateVelocity();
5218
5261
  this.velocity = this.initialVelocity.copy();
5219
- const particles = container.particles;
5220
- particles.setLastZIndex(this.position.z);
5221
5262
  this.zIndexFactor = this.position.z / container.zLayers;
5222
5263
  this.sides = 24;
5223
5264
  let effectDrawer, shapeDrawer;
@@ -5367,7 +5408,7 @@
5367
5408
  return color;
5368
5409
  };
5369
5410
  _initPosition = position => {
5370
- const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5411
+ const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5371
5412
  if (!initialPosition) {
5372
5413
  throw new Error("a valid position cannot be found for particle");
5373
5414
  }
@@ -5501,10 +5542,8 @@
5501
5542
  _container;
5502
5543
  _groupLimits;
5503
5544
  _limit;
5504
- _maxZIndex;
5505
- _minZIndex;
5506
- _needsSort;
5507
5545
  _nextId;
5546
+ _particleBuckets;
5508
5547
  _particleResetPlugins;
5509
5548
  _particleUpdatePlugins;
5510
5549
  _pluginManager;
@@ -5513,19 +5552,17 @@
5513
5552
  _postUpdatePlugins;
5514
5553
  _resizeFactor;
5515
5554
  _updatePlugins;
5516
- _zArray;
5555
+ _zBuckets;
5517
5556
  constructor(pluginManager, container) {
5518
5557
  this._pluginManager = pluginManager;
5519
5558
  this._container = container;
5520
5559
  this._nextId = 0;
5521
5560
  this._array = [];
5522
- this._zArray = [];
5523
5561
  this._pool = [];
5524
5562
  this._limit = 0;
5525
5563
  this._groupLimits = new Map();
5526
- this._needsSort = false;
5527
- this._minZIndex = 0;
5528
- this._maxZIndex = 0;
5564
+ this._particleBuckets = new Map();
5565
+ this._zBuckets = this._createBuckets(this._container.zLayers);
5529
5566
  this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5530
5567
  this.checkParticlePositionPlugins = [];
5531
5568
  this._particleResetPlugins = [];
@@ -5567,7 +5604,7 @@
5567
5604
  return;
5568
5605
  }
5569
5606
  this._array.push(particle);
5570
- this._zArray.push(particle);
5607
+ this._insertParticleIntoBucket(particle);
5571
5608
  this._nextId++;
5572
5609
  this._container.dispatchEvent(EventType.particleAdded, {
5573
5610
  particle,
@@ -5581,12 +5618,14 @@
5581
5618
  }
5582
5619
  clear() {
5583
5620
  this._array = [];
5584
- this._zArray = [];
5621
+ this._particleBuckets.clear();
5622
+ this._resetBuckets(this._container.zLayers);
5585
5623
  }
5586
5624
  destroy() {
5587
5625
  this._array = [];
5588
5626
  this._pool.length = 0;
5589
- this._zArray = [];
5627
+ this._particleBuckets.clear();
5628
+ this._zBuckets = [];
5590
5629
  this.checkParticlePositionPlugins = [];
5591
5630
  this._particleResetPlugins = [];
5592
5631
  this._particleUpdatePlugins = [];
@@ -5595,8 +5634,14 @@
5595
5634
  this._updatePlugins = [];
5596
5635
  }
5597
5636
  drawParticles(delta) {
5598
- for (const particle of this._zArray) {
5599
- particle.draw(delta);
5637
+ for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
5638
+ const bucket = this._zBuckets[i];
5639
+ if (!bucket) {
5640
+ continue;
5641
+ }
5642
+ for (const particle of bucket) {
5643
+ particle.draw(delta);
5644
+ }
5600
5645
  }
5601
5646
  }
5602
5647
  filter(condition) {
@@ -5610,15 +5655,14 @@
5610
5655
  }
5611
5656
  async init() {
5612
5657
  const container = this._container, options = container.actualOptions;
5613
- this._minZIndex = 0;
5614
- this._maxZIndex = 0;
5615
- this._needsSort = false;
5616
5658
  this.checkParticlePositionPlugins = [];
5617
5659
  this._updatePlugins = [];
5618
5660
  this._particleUpdatePlugins = [];
5619
5661
  this._postUpdatePlugins = [];
5620
5662
  this._particleResetPlugins = [];
5621
5663
  this._postParticleUpdatePlugins = [];
5664
+ this._particleBuckets.clear();
5665
+ this._resetBuckets(container.zLayers);
5622
5666
  this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5623
5667
  for (const plugin of container.plugins) {
5624
5668
  if (plugin.redrawInit) {
@@ -5719,79 +5763,25 @@
5719
5763
  }
5720
5764
  this._applyDensity(options.particles, pluginsCount);
5721
5765
  }
5722
- setLastZIndex(zIndex) {
5723
- this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
5724
- }
5725
5766
  setResizeFactor(factor) {
5726
5767
  this._resizeFactor = factor;
5727
5768
  }
5728
5769
  update(delta) {
5729
- const particlesToDelete = new Set();
5730
5770
  this.grid.clear();
5731
5771
  for (const plugin of this._updatePlugins) {
5732
5772
  plugin.update?.(delta);
5733
5773
  }
5734
- const resizeFactor = this._resizeFactor;
5735
- for (const particle of this._array) {
5736
- if (resizeFactor && !particle.ignoresResizeRatio) {
5737
- particle.position.x *= resizeFactor.width;
5738
- particle.position.y *= resizeFactor.height;
5739
- particle.initialPosition.x *= resizeFactor.width;
5740
- particle.initialPosition.y *= resizeFactor.height;
5741
- }
5742
- particle.ignoresResizeRatio = false;
5743
- for (const plugin of this._particleResetPlugins) {
5744
- plugin.particleReset?.(particle);
5745
- }
5746
- for (const plugin of this._particleUpdatePlugins) {
5747
- if (particle.destroyed) {
5748
- break;
5749
- }
5750
- plugin.particleUpdate?.(particle, delta);
5751
- }
5752
- if (particle.destroyed) {
5753
- particlesToDelete.add(particle);
5754
- continue;
5755
- }
5756
- this.grid.insert(particle);
5757
- }
5774
+ const particlesToDelete = this._updateParticlesPhase1(delta);
5758
5775
  for (const plugin of this._postUpdatePlugins) {
5759
5776
  plugin.postUpdate?.(delta);
5760
5777
  }
5761
- for (const particle of this._array) {
5762
- if (particle.destroyed) {
5763
- particlesToDelete.add(particle);
5764
- continue;
5765
- }
5766
- for (const updater of this._container.particleUpdaters) {
5767
- updater.update(particle, delta);
5768
- }
5769
- if (!particle.destroyed && !particle.spawning) {
5770
- for (const plugin of this._postParticleUpdatePlugins) {
5771
- plugin.postParticleUpdate?.(particle, delta);
5772
- }
5773
- }
5774
- else if (particle.destroyed) {
5775
- particlesToDelete.add(particle);
5776
- }
5777
- }
5778
+ this._updateParticlesPhase2(delta, particlesToDelete);
5778
5779
  if (particlesToDelete.size) {
5779
5780
  for (const particle of particlesToDelete) {
5780
5781
  this.remove(particle);
5781
5782
  }
5782
5783
  }
5783
5784
  delete this._resizeFactor;
5784
- if (this._needsSort) {
5785
- const zArray = this._zArray;
5786
- zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
5787
- const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
5788
- if (!firstItem || !lastItem) {
5789
- return;
5790
- }
5791
- this._maxZIndex = firstItem.position.z;
5792
- this._minZIndex = lastItem.position.z;
5793
- this._needsSort = false;
5794
- }
5795
5785
  }
5796
5786
  _addToPool = (...particles) => {
5797
5787
  this._pool.push(...particles);
@@ -5821,13 +5811,52 @@
5821
5811
  this.removeQuantity(particlesCount - particlesNumber, group);
5822
5812
  }
5823
5813
  };
5814
+ _createBuckets = (zLayers) => {
5815
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5816
+ return Array.from({ length: bucketCount }, () => []);
5817
+ };
5818
+ _getBucketIndex = (zIndex) => {
5819
+ const maxBucketIndex = this._zBuckets.length - one;
5820
+ if (maxBucketIndex <= minIndex) {
5821
+ return minIndex;
5822
+ }
5823
+ return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5824
+ };
5825
+ _getParticleInsertIndex = (bucket, particleId) => {
5826
+ let start = minIndex, end = bucket.length;
5827
+ while (start < end) {
5828
+ const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5829
+ if (!middleParticle) {
5830
+ end = middle;
5831
+ continue;
5832
+ }
5833
+ if (middleParticle.id < particleId) {
5834
+ start = middle + one;
5835
+ }
5836
+ else {
5837
+ end = middle;
5838
+ }
5839
+ }
5840
+ return start;
5841
+ };
5824
5842
  _initDensityFactor = densityOptions => {
5825
5843
  const container = this._container;
5826
- if (!container.canvas.element || !densityOptions.enable) {
5844
+ if (!densityOptions.enable) {
5845
+ return defaultDensityFactor;
5846
+ }
5847
+ const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
5848
+ if (!canvasSize.width || !canvasSize.height) {
5827
5849
  return defaultDensityFactor;
5828
5850
  }
5829
- const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
5830
- return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
5851
+ return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5852
+ };
5853
+ _insertParticleIntoBucket = (particle) => {
5854
+ const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5855
+ if (!bucket) {
5856
+ return;
5857
+ }
5858
+ bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
5859
+ this._particleBuckets.set(particle.id, bucketIndex);
5831
5860
  };
5832
5861
  _removeParticle = (index, group, override) => {
5833
5862
  const particle = this._array[index];
@@ -5837,9 +5866,8 @@
5837
5866
  if (particle.group !== group) {
5838
5867
  return false;
5839
5868
  }
5840
- const zIdx = this._zArray.indexOf(particle);
5841
5869
  this._array.splice(index, deleteCount);
5842
- this._zArray.splice(zIdx, deleteCount);
5870
+ this._removeParticleFromBucket(particle);
5843
5871
  particle.destroy(override);
5844
5872
  this._container.dispatchEvent(EventType.particleRemoved, {
5845
5873
  particle,
@@ -5847,6 +5875,98 @@
5847
5875
  this._addToPool(particle);
5848
5876
  return true;
5849
5877
  };
5878
+ _removeParticleFromBucket = (particle) => {
5879
+ const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5880
+ if (!bucket) {
5881
+ this._particleBuckets.delete(particle.id);
5882
+ return;
5883
+ }
5884
+ const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
5885
+ if (bucket[particleIndex]?.id !== particle.id) {
5886
+ this._particleBuckets.delete(particle.id);
5887
+ return;
5888
+ }
5889
+ bucket.splice(particleIndex, deleteCount);
5890
+ this._particleBuckets.delete(particle.id);
5891
+ };
5892
+ _resetBuckets = (zLayers) => {
5893
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5894
+ if (this._zBuckets.length !== bucketCount) {
5895
+ this._zBuckets = this._createBuckets(bucketCount);
5896
+ return;
5897
+ }
5898
+ for (const bucket of this._zBuckets) {
5899
+ bucket.length = minIndex;
5900
+ }
5901
+ };
5902
+ _updateParticleBucket = (particle) => {
5903
+ const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
5904
+ if (currentBucketIndex === undefined) {
5905
+ this._insertParticleIntoBucket(particle);
5906
+ return;
5907
+ }
5908
+ if (currentBucketIndex === newBucketIndex) {
5909
+ return;
5910
+ }
5911
+ const currentBucket = this._zBuckets[currentBucketIndex];
5912
+ if (currentBucket) {
5913
+ const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
5914
+ if (currentBucket[particleIndex]?.id === particle.id) {
5915
+ currentBucket.splice(particleIndex, deleteCount);
5916
+ }
5917
+ }
5918
+ const newBucket = this._zBuckets[newBucketIndex];
5919
+ if (!newBucket) {
5920
+ this._particleBuckets.set(particle.id, newBucketIndex);
5921
+ return;
5922
+ }
5923
+ newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
5924
+ this._particleBuckets.set(particle.id, newBucketIndex);
5925
+ };
5926
+ _updateParticlesPhase1 = (delta) => {
5927
+ const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
5928
+ for (const particle of this._array) {
5929
+ if (resizeFactor && !particle.ignoresResizeRatio) {
5930
+ particle.position.x *= resizeFactor.width;
5931
+ particle.position.y *= resizeFactor.height;
5932
+ particle.initialPosition.x *= resizeFactor.width;
5933
+ particle.initialPosition.y *= resizeFactor.height;
5934
+ }
5935
+ particle.ignoresResizeRatio = false;
5936
+ for (const plugin of this._particleResetPlugins) {
5937
+ plugin.particleReset?.(particle);
5938
+ }
5939
+ for (const plugin of this._particleUpdatePlugins) {
5940
+ if (particle.destroyed) {
5941
+ break;
5942
+ }
5943
+ plugin.particleUpdate?.(particle, delta);
5944
+ }
5945
+ if (particle.destroyed) {
5946
+ particlesToDelete.add(particle);
5947
+ continue;
5948
+ }
5949
+ this.grid.insert(particle);
5950
+ }
5951
+ return particlesToDelete;
5952
+ };
5953
+ _updateParticlesPhase2 = (delta, particlesToDelete) => {
5954
+ for (const particle of this._array) {
5955
+ if (particle.destroyed) {
5956
+ particlesToDelete.add(particle);
5957
+ continue;
5958
+ }
5959
+ for (const updater of this._container.particleUpdaters) {
5960
+ updater.update(particle, delta);
5961
+ }
5962
+ if (!particle.spawning) {
5963
+ for (const plugin of this._postParticleUpdatePlugins) {
5964
+ plugin.postParticleUpdate?.(particle, delta);
5965
+ }
5966
+ }
5967
+ this._updateParticleBucket(particle);
5968
+ }
5969
+ };
5850
5970
  }
5851
5971
 
5852
5972
  class Retina {
@@ -5862,9 +5982,8 @@
5862
5982
  const container = this.container, options = container.actualOptions;
5863
5983
  this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
5864
5984
  this.reduceFactor = defaultReduceFactor;
5865
- const ratio = this.pixelRatio, canvas = container.canvas;
5866
- if (canvas.element) {
5867
- const element = canvas.element;
5985
+ const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
5986
+ if (element) {
5868
5987
  canvas.size.width = element.offsetWidth * ratio;
5869
5988
  canvas.size.height = element.offsetHeight * ratio;
5870
5989
  }
@@ -6553,7 +6672,7 @@
6553
6672
  return;
6554
6673
  }
6555
6674
  const html = interactivityEl, canvas = container.canvas;
6556
- canvas.setPointerEvents(html === canvas.element ? "initial" : "none");
6675
+ canvas.setPointerEvents(html === canvas.domElement ? "initial" : "none");
6557
6676
  if (add && !(options.interactivity?.events.onHover.enable || options.interactivity?.events.onClick.enable)) {
6558
6677
  return;
6559
6678
  }
@@ -6580,7 +6699,7 @@
6580
6699
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6581
6700
  };
6582
6701
  _manageListeners = add => {
6583
- const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.element;
6702
+ const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6584
6703
  if (detectType === InteractivityDetect.window) {
6585
6704
  interactionManager.interactivityData.element = safeDocument();
6586
6705
  }
@@ -6627,7 +6746,7 @@
6627
6746
  mouse.clicking = false;
6628
6747
  };
6629
6748
  _mouseTouchMove = e => {
6630
- const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.element;
6749
+ const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6631
6750
  if (!interactivity.element) {
6632
6751
  return;
6633
6752
  }
@@ -6788,7 +6907,7 @@
6788
6907
  if (!lastTouch) {
6789
6908
  return;
6790
6909
  }
6791
- const element = container.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
6910
+ const element = container.canvas.domElement, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
6792
6911
  x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
6793
6912
  y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
6794
6913
  };