@tsparticles/preset-fire 4.0.0-beta.15 → 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.15 */
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.15";
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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.15");
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));
@@ -3916,7 +3922,7 @@
3916
3922
  }
3917
3923
 
3918
3924
  async function loadExternalPushInteraction(engine) {
3919
- engine.checkVersion("4.0.0-beta.15");
3925
+ engine.checkVersion("4.0.0-beta.17");
3920
3926
  await engine.pluginManager.register((e) => {
3921
3927
  ensureInteractivityPluginLoaded(e);
3922
3928
  e.pluginManager.addInteractor?.("externalPush", container => {
@@ -4287,6 +4293,25 @@
4287
4293
  };
4288
4294
  }
4289
4295
 
4296
+ const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
4297
+ const transferredCanvas = transferredCanvases.get(canvas);
4298
+ if (transferredCanvas) {
4299
+ return transferredCanvas;
4300
+ }
4301
+ if (typeof canvas.transferControlToOffscreen !== "function") {
4302
+ throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4303
+ }
4304
+ try {
4305
+ const offscreenCanvas = canvas.transferControlToOffscreen();
4306
+ transferredCanvases.set(canvas, offscreenCanvas);
4307
+ return offscreenCanvas;
4308
+ }
4309
+ catch {
4310
+ throw new TypeError("OffscreenCanvas transfer failed");
4311
+ }
4312
+ }, isHtmlCanvasElement = (canvas) => {
4313
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4314
+ };
4290
4315
  function setStyle(canvas, style, important = false) {
4291
4316
  if (!style) {
4292
4317
  return;
@@ -4317,8 +4342,9 @@
4317
4342
  }
4318
4343
  }
4319
4344
  class CanvasManager {
4320
- element;
4345
+ domElement;
4321
4346
  render;
4347
+ renderCanvas;
4322
4348
  size;
4323
4349
  zoom = defaultZoom;
4324
4350
  _container;
@@ -4353,9 +4379,10 @@
4353
4379
  destroy() {
4354
4380
  this.stop();
4355
4381
  if (this._generated) {
4356
- const element = this.element;
4382
+ const element = this.domElement;
4357
4383
  element?.remove();
4358
- this.element = undefined;
4384
+ this.domElement = undefined;
4385
+ this.renderCanvas = undefined;
4359
4386
  }
4360
4387
  else {
4361
4388
  this._resetOriginalStyle();
@@ -4388,16 +4415,17 @@
4388
4415
  this._initStyle();
4389
4416
  this.initBackground();
4390
4417
  this._safeMutationObserver(obs => {
4391
- if (!this.element || !(this.element instanceof Node)) {
4418
+ const element = this.domElement;
4419
+ if (!element || !(element instanceof Node)) {
4392
4420
  return;
4393
4421
  }
4394
- obs.observe(this.element, { attributes: true });
4422
+ obs.observe(element, { attributes: true });
4395
4423
  });
4396
4424
  this.initPlugins();
4397
4425
  this.render.init();
4398
4426
  }
4399
4427
  initBackground() {
4400
- const { _container } = this, options = _container.actualOptions, background = options.background, element = this.element;
4428
+ const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
4401
4429
  if (!element) {
4402
4430
  return;
4403
4431
  }
@@ -4422,21 +4450,30 @@
4422
4450
  }
4423
4451
  }
4424
4452
  loadCanvas(canvas) {
4425
- if (this._generated && this.element) {
4426
- this.element.remove();
4453
+ if (this._generated && this.domElement) {
4454
+ this.domElement.remove();
4455
+ }
4456
+ const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4457
+ this.domElement = domCanvas;
4458
+ this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4459
+ this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
4460
+ const domElement = this.domElement;
4461
+ if (domElement) {
4462
+ domElement.ariaHidden = "true";
4463
+ this._originalStyle = cloneStyle(domElement.style);
4464
+ }
4465
+ const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
4466
+ if (domElement) {
4467
+ standardSize.height = domElement.offsetHeight;
4468
+ standardSize.width = domElement.offsetWidth;
4469
+ }
4470
+ else {
4471
+ standardSize.height = renderCanvas.height;
4472
+ standardSize.width = renderCanvas.width;
4427
4473
  }
4428
- const container = this._container;
4429
- this._generated =
4430
- generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
4431
- this.element = canvas;
4432
- this.element.ariaHidden = "true";
4433
- this._originalStyle = cloneStyle(this.element.style);
4434
- const standardSize = this._standardSize;
4435
- standardSize.height = canvas.offsetHeight;
4436
- standardSize.width = canvas.offsetWidth;
4437
4474
  const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
4438
- canvas.height = retinaSize.height = standardSize.height * pxRatio;
4439
- canvas.width = retinaSize.width = standardSize.width * pxRatio;
4475
+ renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4476
+ renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4440
4477
  const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4441
4478
  this.render.setContextSettings({
4442
4479
  alpha: true,
@@ -4444,42 +4481,48 @@
4444
4481
  desynchronized: true,
4445
4482
  willReadFrequently: false,
4446
4483
  });
4447
- this.render.setContext(this.element.getContext("2d", this.render.settings));
4484
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4448
4485
  this._safeMutationObserver(obs => {
4449
4486
  obs.disconnect();
4450
4487
  });
4451
4488
  container.retina.init();
4452
4489
  this.initBackground();
4453
4490
  this._safeMutationObserver(obs => {
4454
- if (!this.element || !(this.element instanceof Node)) {
4491
+ const element = this.domElement;
4492
+ if (!element || !(element instanceof Node)) {
4455
4493
  return;
4456
4494
  }
4457
- obs.observe(this.element, { attributes: true });
4495
+ obs.observe(element, { attributes: true });
4458
4496
  });
4459
4497
  }
4460
4498
  resize() {
4461
- if (!this.element) {
4499
+ const element = this.domElement;
4500
+ if (!element) {
4501
+ return false;
4502
+ }
4503
+ const container = this._container, renderCanvas = this.renderCanvas;
4504
+ if (renderCanvas === undefined) {
4462
4505
  return false;
4463
4506
  }
4464
- const container = this._container, currentSize = container.canvas._standardSize, newSize = {
4465
- width: this.element.offsetWidth,
4466
- height: this.element.offsetHeight,
4507
+ const currentSize = container.canvas._standardSize, newSize = {
4508
+ width: element.offsetWidth,
4509
+ height: element.offsetHeight,
4467
4510
  }, pxRatio = container.retina.pixelRatio, retinaSize = {
4468
4511
  width: newSize.width * pxRatio,
4469
4512
  height: newSize.height * pxRatio,
4470
4513
  };
4471
4514
  if (newSize.height === currentSize.height &&
4472
4515
  newSize.width === currentSize.width &&
4473
- retinaSize.height === this.element.height &&
4474
- retinaSize.width === this.element.width) {
4516
+ retinaSize.height === renderCanvas.height &&
4517
+ retinaSize.width === renderCanvas.width) {
4475
4518
  return false;
4476
4519
  }
4477
4520
  const oldSize = { ...currentSize };
4478
4521
  currentSize.height = newSize.height;
4479
4522
  currentSize.width = newSize.width;
4480
4523
  const canvasSize = this.size;
4481
- this.element.width = canvasSize.width = retinaSize.width;
4482
- this.element.height = canvasSize.height = retinaSize.height;
4524
+ renderCanvas.width = canvasSize.width = retinaSize.width;
4525
+ renderCanvas.height = canvasSize.height = retinaSize.height;
4483
4526
  if (this._container.started) {
4484
4527
  container.particles.setResizeFactor({
4485
4528
  width: currentSize.width / oldSize.width,
@@ -4489,7 +4532,7 @@
4489
4532
  return true;
4490
4533
  }
4491
4534
  setPointerEvents(type) {
4492
- const element = this.element;
4535
+ const element = this.domElement;
4493
4536
  if (!element) {
4494
4537
  return;
4495
4538
  }
@@ -4508,7 +4551,7 @@
4508
4551
  this.render.stop();
4509
4552
  }
4510
4553
  async windowResize() {
4511
- if (!this.element || !this.resize()) {
4554
+ if (!this.domElement || !this.resize()) {
4512
4555
  return;
4513
4556
  }
4514
4557
  const container = this._container, needsRefresh = container.updateActualOptions();
@@ -4524,7 +4567,7 @@
4524
4567
  }
4525
4568
  };
4526
4569
  _initStyle = () => {
4527
- const element = this.element, options = this._container.actualOptions;
4570
+ const element = this.domElement, options = this._container.actualOptions;
4528
4571
  if (!element) {
4529
4572
  return;
4530
4573
  }
@@ -4546,7 +4589,7 @@
4546
4589
  }
4547
4590
  };
4548
4591
  _repairStyle = () => {
4549
- const element = this.element;
4592
+ const element = this.domElement;
4550
4593
  if (!element) {
4551
4594
  return;
4552
4595
  }
@@ -4566,7 +4609,7 @@
4566
4609
  });
4567
4610
  };
4568
4611
  _resetOriginalStyle = () => {
4569
- const element = this.element, originalStyle = this._originalStyle;
4612
+ const element = this.domElement, originalStyle = this._originalStyle;
4570
4613
  if (!element || !originalStyle) {
4571
4614
  return;
4572
4615
  }
@@ -4579,7 +4622,7 @@
4579
4622
  callback(this._mutationObserver);
4580
4623
  };
4581
4624
  _setFullScreenStyle = () => {
4582
- const element = this.element;
4625
+ const element = this.domElement;
4583
4626
  if (!element) {
4584
4627
  return;
4585
4628
  }
@@ -4653,7 +4696,7 @@
4653
4696
  manageListener(globalThis, resizeEvent, handlers.resize, add);
4654
4697
  return;
4655
4698
  }
4656
- const canvasEl = container.canvas.element;
4699
+ const canvasEl = container.canvas.domElement;
4657
4700
  if (this._resizeObserver && !add) {
4658
4701
  if (canvasEl) {
4659
4702
  this._resizeObserver.unobserve(canvasEl);
@@ -4908,8 +4951,6 @@
4908
4951
  this._initPosition(position);
4909
4952
  this.initialVelocity = this._calculateVelocity();
4910
4953
  this.velocity = this.initialVelocity.copy();
4911
- const particles = container.particles;
4912
- particles.setLastZIndex(this.position.z);
4913
4954
  this.zIndexFactor = this.position.z / container.zLayers;
4914
4955
  this.sides = 24;
4915
4956
  let effectDrawer, shapeDrawer;
@@ -5059,7 +5100,7 @@
5059
5100
  return color;
5060
5101
  };
5061
5102
  _initPosition = position => {
5062
- const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5103
+ const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5063
5104
  if (!initialPosition) {
5064
5105
  throw new Error("a valid position cannot be found for particle");
5065
5106
  }
@@ -5193,10 +5234,8 @@
5193
5234
  _container;
5194
5235
  _groupLimits;
5195
5236
  _limit;
5196
- _maxZIndex;
5197
- _minZIndex;
5198
- _needsSort;
5199
5237
  _nextId;
5238
+ _particleBuckets;
5200
5239
  _particleResetPlugins;
5201
5240
  _particleUpdatePlugins;
5202
5241
  _pluginManager;
@@ -5205,19 +5244,17 @@
5205
5244
  _postUpdatePlugins;
5206
5245
  _resizeFactor;
5207
5246
  _updatePlugins;
5208
- _zArray;
5247
+ _zBuckets;
5209
5248
  constructor(pluginManager, container) {
5210
5249
  this._pluginManager = pluginManager;
5211
5250
  this._container = container;
5212
5251
  this._nextId = 0;
5213
5252
  this._array = [];
5214
- this._zArray = [];
5215
5253
  this._pool = [];
5216
5254
  this._limit = 0;
5217
5255
  this._groupLimits = new Map();
5218
- this._needsSort = false;
5219
- this._minZIndex = 0;
5220
- this._maxZIndex = 0;
5256
+ this._particleBuckets = new Map();
5257
+ this._zBuckets = this._createBuckets(this._container.zLayers);
5221
5258
  this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5222
5259
  this.checkParticlePositionPlugins = [];
5223
5260
  this._particleResetPlugins = [];
@@ -5259,7 +5296,7 @@
5259
5296
  return;
5260
5297
  }
5261
5298
  this._array.push(particle);
5262
- this._zArray.push(particle);
5299
+ this._insertParticleIntoBucket(particle);
5263
5300
  this._nextId++;
5264
5301
  this._container.dispatchEvent(EventType.particleAdded, {
5265
5302
  particle,
@@ -5273,12 +5310,14 @@
5273
5310
  }
5274
5311
  clear() {
5275
5312
  this._array = [];
5276
- this._zArray = [];
5313
+ this._particleBuckets.clear();
5314
+ this._resetBuckets(this._container.zLayers);
5277
5315
  }
5278
5316
  destroy() {
5279
5317
  this._array = [];
5280
5318
  this._pool.length = 0;
5281
- this._zArray = [];
5319
+ this._particleBuckets.clear();
5320
+ this._zBuckets = [];
5282
5321
  this.checkParticlePositionPlugins = [];
5283
5322
  this._particleResetPlugins = [];
5284
5323
  this._particleUpdatePlugins = [];
@@ -5287,8 +5326,14 @@
5287
5326
  this._updatePlugins = [];
5288
5327
  }
5289
5328
  drawParticles(delta) {
5290
- for (const particle of this._zArray) {
5291
- particle.draw(delta);
5329
+ for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
5330
+ const bucket = this._zBuckets[i];
5331
+ if (!bucket) {
5332
+ continue;
5333
+ }
5334
+ for (const particle of bucket) {
5335
+ particle.draw(delta);
5336
+ }
5292
5337
  }
5293
5338
  }
5294
5339
  filter(condition) {
@@ -5302,15 +5347,14 @@
5302
5347
  }
5303
5348
  async init() {
5304
5349
  const container = this._container, options = container.actualOptions;
5305
- this._minZIndex = 0;
5306
- this._maxZIndex = 0;
5307
- this._needsSort = false;
5308
5350
  this.checkParticlePositionPlugins = [];
5309
5351
  this._updatePlugins = [];
5310
5352
  this._particleUpdatePlugins = [];
5311
5353
  this._postUpdatePlugins = [];
5312
5354
  this._particleResetPlugins = [];
5313
5355
  this._postParticleUpdatePlugins = [];
5356
+ this._particleBuckets.clear();
5357
+ this._resetBuckets(container.zLayers);
5314
5358
  this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5315
5359
  for (const plugin of container.plugins) {
5316
5360
  if (plugin.redrawInit) {
@@ -5411,79 +5455,25 @@
5411
5455
  }
5412
5456
  this._applyDensity(options.particles, pluginsCount);
5413
5457
  }
5414
- setLastZIndex(zIndex) {
5415
- this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
5416
- }
5417
5458
  setResizeFactor(factor) {
5418
5459
  this._resizeFactor = factor;
5419
5460
  }
5420
5461
  update(delta) {
5421
- const particlesToDelete = new Set();
5422
5462
  this.grid.clear();
5423
5463
  for (const plugin of this._updatePlugins) {
5424
5464
  plugin.update?.(delta);
5425
5465
  }
5426
- const resizeFactor = this._resizeFactor;
5427
- for (const particle of this._array) {
5428
- if (resizeFactor && !particle.ignoresResizeRatio) {
5429
- particle.position.x *= resizeFactor.width;
5430
- particle.position.y *= resizeFactor.height;
5431
- particle.initialPosition.x *= resizeFactor.width;
5432
- particle.initialPosition.y *= resizeFactor.height;
5433
- }
5434
- particle.ignoresResizeRatio = false;
5435
- for (const plugin of this._particleResetPlugins) {
5436
- plugin.particleReset?.(particle);
5437
- }
5438
- for (const plugin of this._particleUpdatePlugins) {
5439
- if (particle.destroyed) {
5440
- break;
5441
- }
5442
- plugin.particleUpdate?.(particle, delta);
5443
- }
5444
- if (particle.destroyed) {
5445
- particlesToDelete.add(particle);
5446
- continue;
5447
- }
5448
- this.grid.insert(particle);
5449
- }
5466
+ const particlesToDelete = this._updateParticlesPhase1(delta);
5450
5467
  for (const plugin of this._postUpdatePlugins) {
5451
5468
  plugin.postUpdate?.(delta);
5452
5469
  }
5453
- for (const particle of this._array) {
5454
- if (particle.destroyed) {
5455
- particlesToDelete.add(particle);
5456
- continue;
5457
- }
5458
- for (const updater of this._container.particleUpdaters) {
5459
- updater.update(particle, delta);
5460
- }
5461
- if (!particle.destroyed && !particle.spawning) {
5462
- for (const plugin of this._postParticleUpdatePlugins) {
5463
- plugin.postParticleUpdate?.(particle, delta);
5464
- }
5465
- }
5466
- else if (particle.destroyed) {
5467
- particlesToDelete.add(particle);
5468
- }
5469
- }
5470
+ this._updateParticlesPhase2(delta, particlesToDelete);
5470
5471
  if (particlesToDelete.size) {
5471
5472
  for (const particle of particlesToDelete) {
5472
5473
  this.remove(particle);
5473
5474
  }
5474
5475
  }
5475
5476
  delete this._resizeFactor;
5476
- if (this._needsSort) {
5477
- const zArray = this._zArray;
5478
- zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
5479
- const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
5480
- if (!firstItem || !lastItem) {
5481
- return;
5482
- }
5483
- this._maxZIndex = firstItem.position.z;
5484
- this._minZIndex = lastItem.position.z;
5485
- this._needsSort = false;
5486
- }
5487
5477
  }
5488
5478
  _addToPool = (...particles) => {
5489
5479
  this._pool.push(...particles);
@@ -5513,13 +5503,52 @@
5513
5503
  this.removeQuantity(particlesCount - particlesNumber, group);
5514
5504
  }
5515
5505
  };
5506
+ _createBuckets = (zLayers) => {
5507
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5508
+ return Array.from({ length: bucketCount }, () => []);
5509
+ };
5510
+ _getBucketIndex = (zIndex) => {
5511
+ const maxBucketIndex = this._zBuckets.length - one;
5512
+ if (maxBucketIndex <= minIndex) {
5513
+ return minIndex;
5514
+ }
5515
+ return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5516
+ };
5517
+ _getParticleInsertIndex = (bucket, particleId) => {
5518
+ let start = minIndex, end = bucket.length;
5519
+ while (start < end) {
5520
+ const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5521
+ if (!middleParticle) {
5522
+ end = middle;
5523
+ continue;
5524
+ }
5525
+ if (middleParticle.id < particleId) {
5526
+ start = middle + one;
5527
+ }
5528
+ else {
5529
+ end = middle;
5530
+ }
5531
+ }
5532
+ return start;
5533
+ };
5516
5534
  _initDensityFactor = densityOptions => {
5517
5535
  const container = this._container;
5518
- if (!container.canvas.element || !densityOptions.enable) {
5536
+ if (!densityOptions.enable) {
5537
+ return defaultDensityFactor;
5538
+ }
5539
+ const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
5540
+ if (!canvasSize.width || !canvasSize.height) {
5519
5541
  return defaultDensityFactor;
5520
5542
  }
5521
- const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
5522
- return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
5543
+ return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5544
+ };
5545
+ _insertParticleIntoBucket = (particle) => {
5546
+ const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5547
+ if (!bucket) {
5548
+ return;
5549
+ }
5550
+ bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
5551
+ this._particleBuckets.set(particle.id, bucketIndex);
5523
5552
  };
5524
5553
  _removeParticle = (index, group, override) => {
5525
5554
  const particle = this._array[index];
@@ -5529,9 +5558,8 @@
5529
5558
  if (particle.group !== group) {
5530
5559
  return false;
5531
5560
  }
5532
- const zIdx = this._zArray.indexOf(particle);
5533
5561
  this._array.splice(index, deleteCount);
5534
- this._zArray.splice(zIdx, deleteCount);
5562
+ this._removeParticleFromBucket(particle);
5535
5563
  particle.destroy(override);
5536
5564
  this._container.dispatchEvent(EventType.particleRemoved, {
5537
5565
  particle,
@@ -5539,6 +5567,98 @@
5539
5567
  this._addToPool(particle);
5540
5568
  return true;
5541
5569
  };
5570
+ _removeParticleFromBucket = (particle) => {
5571
+ const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5572
+ if (!bucket) {
5573
+ this._particleBuckets.delete(particle.id);
5574
+ return;
5575
+ }
5576
+ const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
5577
+ if (bucket[particleIndex]?.id !== particle.id) {
5578
+ this._particleBuckets.delete(particle.id);
5579
+ return;
5580
+ }
5581
+ bucket.splice(particleIndex, deleteCount);
5582
+ this._particleBuckets.delete(particle.id);
5583
+ };
5584
+ _resetBuckets = (zLayers) => {
5585
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5586
+ if (this._zBuckets.length !== bucketCount) {
5587
+ this._zBuckets = this._createBuckets(bucketCount);
5588
+ return;
5589
+ }
5590
+ for (const bucket of this._zBuckets) {
5591
+ bucket.length = minIndex;
5592
+ }
5593
+ };
5594
+ _updateParticleBucket = (particle) => {
5595
+ const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
5596
+ if (currentBucketIndex === undefined) {
5597
+ this._insertParticleIntoBucket(particle);
5598
+ return;
5599
+ }
5600
+ if (currentBucketIndex === newBucketIndex) {
5601
+ return;
5602
+ }
5603
+ const currentBucket = this._zBuckets[currentBucketIndex];
5604
+ if (currentBucket) {
5605
+ const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
5606
+ if (currentBucket[particleIndex]?.id === particle.id) {
5607
+ currentBucket.splice(particleIndex, deleteCount);
5608
+ }
5609
+ }
5610
+ const newBucket = this._zBuckets[newBucketIndex];
5611
+ if (!newBucket) {
5612
+ this._particleBuckets.set(particle.id, newBucketIndex);
5613
+ return;
5614
+ }
5615
+ newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
5616
+ this._particleBuckets.set(particle.id, newBucketIndex);
5617
+ };
5618
+ _updateParticlesPhase1 = (delta) => {
5619
+ const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
5620
+ for (const particle of this._array) {
5621
+ if (resizeFactor && !particle.ignoresResizeRatio) {
5622
+ particle.position.x *= resizeFactor.width;
5623
+ particle.position.y *= resizeFactor.height;
5624
+ particle.initialPosition.x *= resizeFactor.width;
5625
+ particle.initialPosition.y *= resizeFactor.height;
5626
+ }
5627
+ particle.ignoresResizeRatio = false;
5628
+ for (const plugin of this._particleResetPlugins) {
5629
+ plugin.particleReset?.(particle);
5630
+ }
5631
+ for (const plugin of this._particleUpdatePlugins) {
5632
+ if (particle.destroyed) {
5633
+ break;
5634
+ }
5635
+ plugin.particleUpdate?.(particle, delta);
5636
+ }
5637
+ if (particle.destroyed) {
5638
+ particlesToDelete.add(particle);
5639
+ continue;
5640
+ }
5641
+ this.grid.insert(particle);
5642
+ }
5643
+ return particlesToDelete;
5644
+ };
5645
+ _updateParticlesPhase2 = (delta, particlesToDelete) => {
5646
+ for (const particle of this._array) {
5647
+ if (particle.destroyed) {
5648
+ particlesToDelete.add(particle);
5649
+ continue;
5650
+ }
5651
+ for (const updater of this._container.particleUpdaters) {
5652
+ updater.update(particle, delta);
5653
+ }
5654
+ if (!particle.spawning) {
5655
+ for (const plugin of this._postParticleUpdatePlugins) {
5656
+ plugin.postParticleUpdate?.(particle, delta);
5657
+ }
5658
+ }
5659
+ this._updateParticleBucket(particle);
5660
+ }
5661
+ };
5542
5662
  }
5543
5663
 
5544
5664
  class Retina {
@@ -5554,9 +5674,8 @@
5554
5674
  const container = this.container, options = container.actualOptions;
5555
5675
  this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
5556
5676
  this.reduceFactor = defaultReduceFactor;
5557
- const ratio = this.pixelRatio, canvas = container.canvas;
5558
- if (canvas.element) {
5559
- const element = canvas.element;
5677
+ const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
5678
+ if (element) {
5560
5679
  canvas.size.width = element.offsetWidth * ratio;
5561
5680
  canvas.size.height = element.offsetHeight * ratio;
5562
5681
  }
@@ -6245,7 +6364,7 @@
6245
6364
  return;
6246
6365
  }
6247
6366
  const html = interactivityEl, canvas = container.canvas;
6248
- canvas.setPointerEvents(html === canvas.element ? "initial" : "none");
6367
+ canvas.setPointerEvents(html === canvas.domElement ? "initial" : "none");
6249
6368
  if (add && !(options.interactivity?.events.onHover.enable || options.interactivity?.events.onClick.enable)) {
6250
6369
  return;
6251
6370
  }
@@ -6272,7 +6391,7 @@
6272
6391
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6273
6392
  };
6274
6393
  _manageListeners = add => {
6275
- const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.element;
6394
+ const handlers = this._handlers, container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6276
6395
  if (detectType === InteractivityDetect.window) {
6277
6396
  interactionManager.interactivityData.element = safeDocument();
6278
6397
  }
@@ -6319,7 +6438,7 @@
6319
6438
  mouse.clicking = false;
6320
6439
  };
6321
6440
  _mouseTouchMove = e => {
6322
- const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.element;
6441
+ const container = this._container, interactionManager = this._interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6323
6442
  if (!interactivity.element) {
6324
6443
  return;
6325
6444
  }
@@ -6480,7 +6599,7 @@
6480
6599
  if (!lastTouch) {
6481
6600
  return;
6482
6601
  }
6483
- const element = container.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
6602
+ const element = container.canvas.domElement, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
6484
6603
  x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
6485
6604
  y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
6486
6605
  };