@tsparticles/preset-snow 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) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -959,7 +959,7 @@
959
959
  }
960
960
  }
961
961
  else {
962
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases[canvasFirstIndex];
962
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
963
963
  if (foundCanvas) {
964
964
  canvasEl = foundCanvas;
965
965
  canvasEl.dataset[generatedAttribute] = generatedFalse;
@@ -996,7 +996,7 @@
996
996
  return this._domArray;
997
997
  }
998
998
  get version() {
999
- return "4.0.0-beta.16";
999
+ return "4.0.0-beta.17";
1000
1000
  }
1001
1001
  addEventListener(type, listener) {
1002
1002
  this._eventDispatcher.addEventListener(type, listener);
@@ -1027,7 +1027,11 @@
1027
1027
  }
1028
1028
  async load(params) {
1029
1029
  await this.init();
1030
- const { Container } = await Promise.resolve().then(function () { return Container$1; }), id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
1030
+ let domSourceElement;
1031
+ if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
1032
+ domSourceElement = params.element;
1033
+ }
1034
+ const { Container } = await Promise.resolve().then(function () { return Container$1; }), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
1031
1035
  dispatchCallback: (eventType, args) => {
1032
1036
  this.dispatchEvent(eventType, args);
1033
1037
  },
@@ -1054,8 +1058,10 @@
1054
1058
  else {
1055
1059
  items.push(newItem);
1056
1060
  }
1057
- const domContainer = getDomContainer(id, params.element), canvasEl = getCanvasFromContainer(domContainer);
1058
- newItem.canvas.loadCanvas(canvasEl);
1061
+ const sourceCanvas = typeof OffscreenCanvas !== "undefined" && params.element instanceof OffscreenCanvas
1062
+ ? params.element
1063
+ : getCanvasFromContainer(getDomContainer(id, domSourceElement));
1064
+ newItem.canvas.loadCanvas(sourceCanvas);
1059
1065
  await newItem.start();
1060
1066
  return newItem;
1061
1067
  }
@@ -2848,7 +2854,7 @@
2848
2854
  }
2849
2855
 
2850
2856
  async function loadCircleShape(engine) {
2851
- engine.checkVersion("4.0.0-beta.16");
2857
+ engine.checkVersion("4.0.0-beta.17");
2852
2858
  await engine.pluginManager.register(e => {
2853
2859
  e.pluginManager.addShape(["circle"], () => {
2854
2860
  return Promise.resolve(new CircleDrawer());
@@ -2896,7 +2902,7 @@
2896
2902
  }
2897
2903
 
2898
2904
  async function loadHexColorPlugin(engine) {
2899
- engine.checkVersion("4.0.0-beta.16");
2905
+ engine.checkVersion("4.0.0-beta.17");
2900
2906
  await engine.pluginManager.register(e => {
2901
2907
  e.pluginManager.addColorManager("hex", new HexColorManager());
2902
2908
  });
@@ -2949,7 +2955,7 @@
2949
2955
  }
2950
2956
 
2951
2957
  async function loadHslColorPlugin(engine) {
2952
- engine.checkVersion("4.0.0-beta.16");
2958
+ engine.checkVersion("4.0.0-beta.17");
2953
2959
  await engine.pluginManager.register(e => {
2954
2960
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2955
2961
  });
@@ -2973,7 +2979,7 @@
2973
2979
  }
2974
2980
 
2975
2981
  async function loadMovePlugin(engine) {
2976
- engine.checkVersion("4.0.0-beta.16");
2982
+ engine.checkVersion("4.0.0-beta.17");
2977
2983
  await engine.pluginManager.register(e => {
2978
2984
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2979
2985
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -3034,7 +3040,7 @@
3034
3040
  }
3035
3041
 
3036
3042
  async function loadOpacityUpdater(engine) {
3037
- engine.checkVersion("4.0.0-beta.16");
3043
+ engine.checkVersion("4.0.0-beta.17");
3038
3044
  await engine.pluginManager.register(e => {
3039
3045
  e.pluginManager.addParticleUpdater("opacity", container => {
3040
3046
  return Promise.resolve(new OpacityUpdater(container));
@@ -3386,7 +3392,7 @@
3386
3392
  }
3387
3393
 
3388
3394
  async function loadOutModesUpdater(engine) {
3389
- engine.checkVersion("4.0.0-beta.16");
3395
+ engine.checkVersion("4.0.0-beta.17");
3390
3396
  await engine.pluginManager.register(e => {
3391
3397
  e.pluginManager.addParticleUpdater("outModes", container => {
3392
3398
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3457,7 +3463,7 @@
3457
3463
  }
3458
3464
 
3459
3465
  async function loadPaintUpdater(engine) {
3460
- engine.checkVersion("4.0.0-beta.16");
3466
+ engine.checkVersion("4.0.0-beta.17");
3461
3467
  await engine.pluginManager.register(e => {
3462
3468
  e.pluginManager.addParticleUpdater("paint", container => {
3463
3469
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3512,7 +3518,7 @@
3512
3518
  }
3513
3519
 
3514
3520
  async function loadRgbColorPlugin(engine) {
3515
- engine.checkVersion("4.0.0-beta.16");
3521
+ engine.checkVersion("4.0.0-beta.17");
3516
3522
  await engine.pluginManager.register(e => {
3517
3523
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3518
3524
  });
@@ -3555,7 +3561,7 @@
3555
3561
  }
3556
3562
 
3557
3563
  async function loadSizeUpdater(engine) {
3558
- engine.checkVersion("4.0.0-beta.16");
3564
+ engine.checkVersion("4.0.0-beta.17");
3559
3565
  await engine.pluginManager.register(e => {
3560
3566
  e.pluginManager.addParticleUpdater("size", container => {
3561
3567
  return Promise.resolve(new SizeUpdater(container));
@@ -3564,7 +3570,7 @@
3564
3570
  }
3565
3571
 
3566
3572
  async function loadBasic(engine) {
3567
- engine.checkVersion("4.0.0-beta.16");
3573
+ engine.checkVersion("4.0.0-beta.17");
3568
3574
  await engine.pluginManager.register(async (e) => {
3569
3575
  await Promise.all([
3570
3576
  loadHexColorPlugin(e),
@@ -3719,7 +3725,7 @@
3719
3725
  }
3720
3726
 
3721
3727
  async function loadWobbleUpdater(engine) {
3722
- engine.checkVersion("4.0.0-beta.16");
3728
+ engine.checkVersion("4.0.0-beta.17");
3723
3729
  await engine.pluginManager.register(e => {
3724
3730
  e.pluginManager.addParticleUpdater("wobble", container => {
3725
3731
  return Promise.resolve(new WobbleUpdater(container));
@@ -4069,6 +4075,25 @@
4069
4075
  };
4070
4076
  }
4071
4077
 
4078
+ const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
4079
+ const transferredCanvas = transferredCanvases.get(canvas);
4080
+ if (transferredCanvas) {
4081
+ return transferredCanvas;
4082
+ }
4083
+ if (typeof canvas.transferControlToOffscreen !== "function") {
4084
+ throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4085
+ }
4086
+ try {
4087
+ const offscreenCanvas = canvas.transferControlToOffscreen();
4088
+ transferredCanvases.set(canvas, offscreenCanvas);
4089
+ return offscreenCanvas;
4090
+ }
4091
+ catch {
4092
+ throw new TypeError("OffscreenCanvas transfer failed");
4093
+ }
4094
+ }, isHtmlCanvasElement = (canvas) => {
4095
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4096
+ };
4072
4097
  function setStyle(canvas, style, important = false) {
4073
4098
  if (!style) {
4074
4099
  return;
@@ -4099,8 +4124,9 @@
4099
4124
  }
4100
4125
  }
4101
4126
  class CanvasManager {
4102
- element;
4127
+ domElement;
4103
4128
  render;
4129
+ renderCanvas;
4104
4130
  size;
4105
4131
  zoom = defaultZoom;
4106
4132
  _container;
@@ -4135,9 +4161,10 @@
4135
4161
  destroy() {
4136
4162
  this.stop();
4137
4163
  if (this._generated) {
4138
- const element = this.element;
4164
+ const element = this.domElement;
4139
4165
  element?.remove();
4140
- this.element = undefined;
4166
+ this.domElement = undefined;
4167
+ this.renderCanvas = undefined;
4141
4168
  }
4142
4169
  else {
4143
4170
  this._resetOriginalStyle();
@@ -4170,16 +4197,17 @@
4170
4197
  this._initStyle();
4171
4198
  this.initBackground();
4172
4199
  this._safeMutationObserver(obs => {
4173
- if (!this.element || !(this.element instanceof Node)) {
4200
+ const element = this.domElement;
4201
+ if (!element || !(element instanceof Node)) {
4174
4202
  return;
4175
4203
  }
4176
- obs.observe(this.element, { attributes: true });
4204
+ obs.observe(element, { attributes: true });
4177
4205
  });
4178
4206
  this.initPlugins();
4179
4207
  this.render.init();
4180
4208
  }
4181
4209
  initBackground() {
4182
- const { _container } = this, options = _container.actualOptions, background = options.background, element = this.element;
4210
+ const { _container } = this, options = _container.actualOptions, background = options.background, element = this.domElement;
4183
4211
  if (!element) {
4184
4212
  return;
4185
4213
  }
@@ -4204,21 +4232,30 @@
4204
4232
  }
4205
4233
  }
4206
4234
  loadCanvas(canvas) {
4207
- if (this._generated && this.element) {
4208
- this.element.remove();
4235
+ if (this._generated && this.domElement) {
4236
+ this.domElement.remove();
4237
+ }
4238
+ const container = this._container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4239
+ this.domElement = domCanvas;
4240
+ this._generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4241
+ this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
4242
+ const domElement = this.domElement;
4243
+ if (domElement) {
4244
+ domElement.ariaHidden = "true";
4245
+ this._originalStyle = cloneStyle(domElement.style);
4246
+ }
4247
+ const standardSize = this._standardSize, renderCanvas = this.renderCanvas;
4248
+ if (domElement) {
4249
+ standardSize.height = domElement.offsetHeight;
4250
+ standardSize.width = domElement.offsetWidth;
4251
+ }
4252
+ else {
4253
+ standardSize.height = renderCanvas.height;
4254
+ standardSize.width = renderCanvas.width;
4209
4255
  }
4210
- const container = this._container;
4211
- this._generated =
4212
- generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
4213
- this.element = canvas;
4214
- this.element.ariaHidden = "true";
4215
- this._originalStyle = cloneStyle(this.element.style);
4216
- const standardSize = this._standardSize;
4217
- standardSize.height = canvas.offsetHeight;
4218
- standardSize.width = canvas.offsetWidth;
4219
4256
  const pxRatio = this._container.retina.pixelRatio, retinaSize = this.size;
4220
- canvas.height = retinaSize.height = standardSize.height * pxRatio;
4221
- canvas.width = retinaSize.width = standardSize.width * pxRatio;
4257
+ renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4258
+ renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4222
4259
  const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4223
4260
  this.render.setContextSettings({
4224
4261
  alpha: true,
@@ -4226,42 +4263,48 @@
4226
4263
  desynchronized: true,
4227
4264
  willReadFrequently: false,
4228
4265
  });
4229
- this.render.setContext(this.element.getContext("2d", this.render.settings));
4266
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4230
4267
  this._safeMutationObserver(obs => {
4231
4268
  obs.disconnect();
4232
4269
  });
4233
4270
  container.retina.init();
4234
4271
  this.initBackground();
4235
4272
  this._safeMutationObserver(obs => {
4236
- if (!this.element || !(this.element instanceof Node)) {
4273
+ const element = this.domElement;
4274
+ if (!element || !(element instanceof Node)) {
4237
4275
  return;
4238
4276
  }
4239
- obs.observe(this.element, { attributes: true });
4277
+ obs.observe(element, { attributes: true });
4240
4278
  });
4241
4279
  }
4242
4280
  resize() {
4243
- if (!this.element) {
4281
+ const element = this.domElement;
4282
+ if (!element) {
4283
+ return false;
4284
+ }
4285
+ const container = this._container, renderCanvas = this.renderCanvas;
4286
+ if (renderCanvas === undefined) {
4244
4287
  return false;
4245
4288
  }
4246
- const container = this._container, currentSize = container.canvas._standardSize, newSize = {
4247
- width: this.element.offsetWidth,
4248
- height: this.element.offsetHeight,
4289
+ const currentSize = container.canvas._standardSize, newSize = {
4290
+ width: element.offsetWidth,
4291
+ height: element.offsetHeight,
4249
4292
  }, pxRatio = container.retina.pixelRatio, retinaSize = {
4250
4293
  width: newSize.width * pxRatio,
4251
4294
  height: newSize.height * pxRatio,
4252
4295
  };
4253
4296
  if (newSize.height === currentSize.height &&
4254
4297
  newSize.width === currentSize.width &&
4255
- retinaSize.height === this.element.height &&
4256
- retinaSize.width === this.element.width) {
4298
+ retinaSize.height === renderCanvas.height &&
4299
+ retinaSize.width === renderCanvas.width) {
4257
4300
  return false;
4258
4301
  }
4259
4302
  const oldSize = { ...currentSize };
4260
4303
  currentSize.height = newSize.height;
4261
4304
  currentSize.width = newSize.width;
4262
4305
  const canvasSize = this.size;
4263
- this.element.width = canvasSize.width = retinaSize.width;
4264
- this.element.height = canvasSize.height = retinaSize.height;
4306
+ renderCanvas.width = canvasSize.width = retinaSize.width;
4307
+ renderCanvas.height = canvasSize.height = retinaSize.height;
4265
4308
  if (this._container.started) {
4266
4309
  container.particles.setResizeFactor({
4267
4310
  width: currentSize.width / oldSize.width,
@@ -4271,7 +4314,7 @@
4271
4314
  return true;
4272
4315
  }
4273
4316
  setPointerEvents(type) {
4274
- const element = this.element;
4317
+ const element = this.domElement;
4275
4318
  if (!element) {
4276
4319
  return;
4277
4320
  }
@@ -4290,7 +4333,7 @@
4290
4333
  this.render.stop();
4291
4334
  }
4292
4335
  async windowResize() {
4293
- if (!this.element || !this.resize()) {
4336
+ if (!this.domElement || !this.resize()) {
4294
4337
  return;
4295
4338
  }
4296
4339
  const container = this._container, needsRefresh = container.updateActualOptions();
@@ -4306,7 +4349,7 @@
4306
4349
  }
4307
4350
  };
4308
4351
  _initStyle = () => {
4309
- const element = this.element, options = this._container.actualOptions;
4352
+ const element = this.domElement, options = this._container.actualOptions;
4310
4353
  if (!element) {
4311
4354
  return;
4312
4355
  }
@@ -4328,7 +4371,7 @@
4328
4371
  }
4329
4372
  };
4330
4373
  _repairStyle = () => {
4331
- const element = this.element;
4374
+ const element = this.domElement;
4332
4375
  if (!element) {
4333
4376
  return;
4334
4377
  }
@@ -4348,7 +4391,7 @@
4348
4391
  });
4349
4392
  };
4350
4393
  _resetOriginalStyle = () => {
4351
- const element = this.element, originalStyle = this._originalStyle;
4394
+ const element = this.domElement, originalStyle = this._originalStyle;
4352
4395
  if (!element || !originalStyle) {
4353
4396
  return;
4354
4397
  }
@@ -4361,7 +4404,7 @@
4361
4404
  callback(this._mutationObserver);
4362
4405
  };
4363
4406
  _setFullScreenStyle = () => {
4364
- const element = this.element;
4407
+ const element = this.domElement;
4365
4408
  if (!element) {
4366
4409
  return;
4367
4410
  }
@@ -4435,7 +4478,7 @@
4435
4478
  manageListener(globalThis, resizeEvent, handlers.resize, add);
4436
4479
  return;
4437
4480
  }
4438
- const canvasEl = container.canvas.element;
4481
+ const canvasEl = container.canvas.domElement;
4439
4482
  if (this._resizeObserver && !add) {
4440
4483
  if (canvasEl) {
4441
4484
  this._resizeObserver.unobserve(canvasEl);
@@ -4690,8 +4733,6 @@
4690
4733
  this._initPosition(position);
4691
4734
  this.initialVelocity = this._calculateVelocity();
4692
4735
  this.velocity = this.initialVelocity.copy();
4693
- const particles = container.particles;
4694
- particles.setLastZIndex(this.position.z);
4695
4736
  this.zIndexFactor = this.position.z / container.zLayers;
4696
4737
  this.sides = 24;
4697
4738
  let effectDrawer, shapeDrawer;
@@ -4841,7 +4882,7 @@
4841
4882
  return color;
4842
4883
  };
4843
4884
  _initPosition = position => {
4844
- const container = this._container, zIndexValue = getRangeValue(this.options.zIndex.value), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
4885
+ const container = this._container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this._calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
4845
4886
  if (!initialPosition) {
4846
4887
  throw new Error("a valid position cannot be found for particle");
4847
4888
  }
@@ -4975,10 +5016,8 @@
4975
5016
  _container;
4976
5017
  _groupLimits;
4977
5018
  _limit;
4978
- _maxZIndex;
4979
- _minZIndex;
4980
- _needsSort;
4981
5019
  _nextId;
5020
+ _particleBuckets;
4982
5021
  _particleResetPlugins;
4983
5022
  _particleUpdatePlugins;
4984
5023
  _pluginManager;
@@ -4987,19 +5026,17 @@
4987
5026
  _postUpdatePlugins;
4988
5027
  _resizeFactor;
4989
5028
  _updatePlugins;
4990
- _zArray;
5029
+ _zBuckets;
4991
5030
  constructor(pluginManager, container) {
4992
5031
  this._pluginManager = pluginManager;
4993
5032
  this._container = container;
4994
5033
  this._nextId = 0;
4995
5034
  this._array = [];
4996
- this._zArray = [];
4997
5035
  this._pool = [];
4998
5036
  this._limit = 0;
4999
5037
  this._groupLimits = new Map();
5000
- this._needsSort = false;
5001
- this._minZIndex = 0;
5002
- this._maxZIndex = 0;
5038
+ this._particleBuckets = new Map();
5039
+ this._zBuckets = this._createBuckets(this._container.zLayers);
5003
5040
  this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5004
5041
  this.checkParticlePositionPlugins = [];
5005
5042
  this._particleResetPlugins = [];
@@ -5041,7 +5078,7 @@
5041
5078
  return;
5042
5079
  }
5043
5080
  this._array.push(particle);
5044
- this._zArray.push(particle);
5081
+ this._insertParticleIntoBucket(particle);
5045
5082
  this._nextId++;
5046
5083
  this._container.dispatchEvent(EventType.particleAdded, {
5047
5084
  particle,
@@ -5055,12 +5092,14 @@
5055
5092
  }
5056
5093
  clear() {
5057
5094
  this._array = [];
5058
- this._zArray = [];
5095
+ this._particleBuckets.clear();
5096
+ this._resetBuckets(this._container.zLayers);
5059
5097
  }
5060
5098
  destroy() {
5061
5099
  this._array = [];
5062
5100
  this._pool.length = 0;
5063
- this._zArray = [];
5101
+ this._particleBuckets.clear();
5102
+ this._zBuckets = [];
5064
5103
  this.checkParticlePositionPlugins = [];
5065
5104
  this._particleResetPlugins = [];
5066
5105
  this._particleUpdatePlugins = [];
@@ -5069,8 +5108,14 @@
5069
5108
  this._updatePlugins = [];
5070
5109
  }
5071
5110
  drawParticles(delta) {
5072
- for (const particle of this._zArray) {
5073
- particle.draw(delta);
5111
+ for (let i = this._zBuckets.length - one; i >= minIndex; i--) {
5112
+ const bucket = this._zBuckets[i];
5113
+ if (!bucket) {
5114
+ continue;
5115
+ }
5116
+ for (const particle of bucket) {
5117
+ particle.draw(delta);
5118
+ }
5074
5119
  }
5075
5120
  }
5076
5121
  filter(condition) {
@@ -5084,15 +5129,14 @@
5084
5129
  }
5085
5130
  async init() {
5086
5131
  const container = this._container, options = container.actualOptions;
5087
- this._minZIndex = 0;
5088
- this._maxZIndex = 0;
5089
- this._needsSort = false;
5090
5132
  this.checkParticlePositionPlugins = [];
5091
5133
  this._updatePlugins = [];
5092
5134
  this._particleUpdatePlugins = [];
5093
5135
  this._postUpdatePlugins = [];
5094
5136
  this._particleResetPlugins = [];
5095
5137
  this._postParticleUpdatePlugins = [];
5138
+ this._particleBuckets.clear();
5139
+ this._resetBuckets(container.zLayers);
5096
5140
  this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5097
5141
  for (const plugin of container.plugins) {
5098
5142
  if (plugin.redrawInit) {
@@ -5193,79 +5237,25 @@
5193
5237
  }
5194
5238
  this._applyDensity(options.particles, pluginsCount);
5195
5239
  }
5196
- setLastZIndex(zIndex) {
5197
- this._needsSort ||= zIndex >= this._maxZIndex || (zIndex > this._minZIndex && zIndex < this._maxZIndex);
5198
- }
5199
5240
  setResizeFactor(factor) {
5200
5241
  this._resizeFactor = factor;
5201
5242
  }
5202
5243
  update(delta) {
5203
- const particlesToDelete = new Set();
5204
5244
  this.grid.clear();
5205
5245
  for (const plugin of this._updatePlugins) {
5206
5246
  plugin.update?.(delta);
5207
5247
  }
5208
- const resizeFactor = this._resizeFactor;
5209
- for (const particle of this._array) {
5210
- if (resizeFactor && !particle.ignoresResizeRatio) {
5211
- particle.position.x *= resizeFactor.width;
5212
- particle.position.y *= resizeFactor.height;
5213
- particle.initialPosition.x *= resizeFactor.width;
5214
- particle.initialPosition.y *= resizeFactor.height;
5215
- }
5216
- particle.ignoresResizeRatio = false;
5217
- for (const plugin of this._particleResetPlugins) {
5218
- plugin.particleReset?.(particle);
5219
- }
5220
- for (const plugin of this._particleUpdatePlugins) {
5221
- if (particle.destroyed) {
5222
- break;
5223
- }
5224
- plugin.particleUpdate?.(particle, delta);
5225
- }
5226
- if (particle.destroyed) {
5227
- particlesToDelete.add(particle);
5228
- continue;
5229
- }
5230
- this.grid.insert(particle);
5231
- }
5248
+ const particlesToDelete = this._updateParticlesPhase1(delta);
5232
5249
  for (const plugin of this._postUpdatePlugins) {
5233
5250
  plugin.postUpdate?.(delta);
5234
5251
  }
5235
- for (const particle of this._array) {
5236
- if (particle.destroyed) {
5237
- particlesToDelete.add(particle);
5238
- continue;
5239
- }
5240
- for (const updater of this._container.particleUpdaters) {
5241
- updater.update(particle, delta);
5242
- }
5243
- if (!particle.destroyed && !particle.spawning) {
5244
- for (const plugin of this._postParticleUpdatePlugins) {
5245
- plugin.postParticleUpdate?.(particle, delta);
5246
- }
5247
- }
5248
- else if (particle.destroyed) {
5249
- particlesToDelete.add(particle);
5250
- }
5251
- }
5252
+ this._updateParticlesPhase2(delta, particlesToDelete);
5252
5253
  if (particlesToDelete.size) {
5253
5254
  for (const particle of particlesToDelete) {
5254
5255
  this.remove(particle);
5255
5256
  }
5256
5257
  }
5257
5258
  delete this._resizeFactor;
5258
- if (this._needsSort) {
5259
- const zArray = this._zArray;
5260
- zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
5261
- const firstItem = zArray[minIndex], lastItem = zArray[zArray.length - lengthOffset];
5262
- if (!firstItem || !lastItem) {
5263
- return;
5264
- }
5265
- this._maxZIndex = firstItem.position.z;
5266
- this._minZIndex = lastItem.position.z;
5267
- this._needsSort = false;
5268
- }
5269
5259
  }
5270
5260
  _addToPool = (...particles) => {
5271
5261
  this._pool.push(...particles);
@@ -5295,13 +5285,52 @@
5295
5285
  this.removeQuantity(particlesCount - particlesNumber, group);
5296
5286
  }
5297
5287
  };
5288
+ _createBuckets = (zLayers) => {
5289
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5290
+ return Array.from({ length: bucketCount }, () => []);
5291
+ };
5292
+ _getBucketIndex = (zIndex) => {
5293
+ const maxBucketIndex = this._zBuckets.length - one;
5294
+ if (maxBucketIndex <= minIndex) {
5295
+ return minIndex;
5296
+ }
5297
+ return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5298
+ };
5299
+ _getParticleInsertIndex = (bucket, particleId) => {
5300
+ let start = minIndex, end = bucket.length;
5301
+ while (start < end) {
5302
+ const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5303
+ if (!middleParticle) {
5304
+ end = middle;
5305
+ continue;
5306
+ }
5307
+ if (middleParticle.id < particleId) {
5308
+ start = middle + one;
5309
+ }
5310
+ else {
5311
+ end = middle;
5312
+ }
5313
+ }
5314
+ return start;
5315
+ };
5298
5316
  _initDensityFactor = densityOptions => {
5299
5317
  const container = this._container;
5300
- if (!container.canvas.element || !densityOptions.enable) {
5318
+ if (!densityOptions.enable) {
5319
+ return defaultDensityFactor;
5320
+ }
5321
+ const canvasSize = container.canvas.size, pxRatio = container.retina.pixelRatio;
5322
+ if (!canvasSize.width || !canvasSize.height) {
5301
5323
  return defaultDensityFactor;
5302
5324
  }
5303
- const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
5304
- return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
5325
+ return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5326
+ };
5327
+ _insertParticleIntoBucket = (particle) => {
5328
+ const bucketIndex = this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5329
+ if (!bucket) {
5330
+ return;
5331
+ }
5332
+ bucket.splice(this._getParticleInsertIndex(bucket, particle.id), empty, particle);
5333
+ this._particleBuckets.set(particle.id, bucketIndex);
5305
5334
  };
5306
5335
  _removeParticle = (index, group, override) => {
5307
5336
  const particle = this._array[index];
@@ -5311,9 +5340,8 @@
5311
5340
  if (particle.group !== group) {
5312
5341
  return false;
5313
5342
  }
5314
- const zIdx = this._zArray.indexOf(particle);
5315
5343
  this._array.splice(index, deleteCount);
5316
- this._zArray.splice(zIdx, deleteCount);
5344
+ this._removeParticleFromBucket(particle);
5317
5345
  particle.destroy(override);
5318
5346
  this._container.dispatchEvent(EventType.particleRemoved, {
5319
5347
  particle,
@@ -5321,6 +5349,98 @@
5321
5349
  this._addToPool(particle);
5322
5350
  return true;
5323
5351
  };
5352
+ _removeParticleFromBucket = (particle) => {
5353
+ const bucketIndex = this._particleBuckets.get(particle.id) ?? this._getBucketIndex(particle.position.z), bucket = this._zBuckets[bucketIndex];
5354
+ if (!bucket) {
5355
+ this._particleBuckets.delete(particle.id);
5356
+ return;
5357
+ }
5358
+ const particleIndex = this._getParticleInsertIndex(bucket, particle.id);
5359
+ if (bucket[particleIndex]?.id !== particle.id) {
5360
+ this._particleBuckets.delete(particle.id);
5361
+ return;
5362
+ }
5363
+ bucket.splice(particleIndex, deleteCount);
5364
+ this._particleBuckets.delete(particle.id);
5365
+ };
5366
+ _resetBuckets = (zLayers) => {
5367
+ const bucketCount = Math.max(Math.floor(zLayers), one);
5368
+ if (this._zBuckets.length !== bucketCount) {
5369
+ this._zBuckets = this._createBuckets(bucketCount);
5370
+ return;
5371
+ }
5372
+ for (const bucket of this._zBuckets) {
5373
+ bucket.length = minIndex;
5374
+ }
5375
+ };
5376
+ _updateParticleBucket = (particle) => {
5377
+ const newBucketIndex = this._getBucketIndex(particle.position.z), currentBucketIndex = this._particleBuckets.get(particle.id);
5378
+ if (currentBucketIndex === undefined) {
5379
+ this._insertParticleIntoBucket(particle);
5380
+ return;
5381
+ }
5382
+ if (currentBucketIndex === newBucketIndex) {
5383
+ return;
5384
+ }
5385
+ const currentBucket = this._zBuckets[currentBucketIndex];
5386
+ if (currentBucket) {
5387
+ const particleIndex = this._getParticleInsertIndex(currentBucket, particle.id);
5388
+ if (currentBucket[particleIndex]?.id === particle.id) {
5389
+ currentBucket.splice(particleIndex, deleteCount);
5390
+ }
5391
+ }
5392
+ const newBucket = this._zBuckets[newBucketIndex];
5393
+ if (!newBucket) {
5394
+ this._particleBuckets.set(particle.id, newBucketIndex);
5395
+ return;
5396
+ }
5397
+ newBucket.splice(this._getParticleInsertIndex(newBucket, particle.id), empty, particle);
5398
+ this._particleBuckets.set(particle.id, newBucketIndex);
5399
+ };
5400
+ _updateParticlesPhase1 = (delta) => {
5401
+ const particlesToDelete = new Set(), resizeFactor = this._resizeFactor;
5402
+ for (const particle of this._array) {
5403
+ if (resizeFactor && !particle.ignoresResizeRatio) {
5404
+ particle.position.x *= resizeFactor.width;
5405
+ particle.position.y *= resizeFactor.height;
5406
+ particle.initialPosition.x *= resizeFactor.width;
5407
+ particle.initialPosition.y *= resizeFactor.height;
5408
+ }
5409
+ particle.ignoresResizeRatio = false;
5410
+ for (const plugin of this._particleResetPlugins) {
5411
+ plugin.particleReset?.(particle);
5412
+ }
5413
+ for (const plugin of this._particleUpdatePlugins) {
5414
+ if (particle.destroyed) {
5415
+ break;
5416
+ }
5417
+ plugin.particleUpdate?.(particle, delta);
5418
+ }
5419
+ if (particle.destroyed) {
5420
+ particlesToDelete.add(particle);
5421
+ continue;
5422
+ }
5423
+ this.grid.insert(particle);
5424
+ }
5425
+ return particlesToDelete;
5426
+ };
5427
+ _updateParticlesPhase2 = (delta, particlesToDelete) => {
5428
+ for (const particle of this._array) {
5429
+ if (particle.destroyed) {
5430
+ particlesToDelete.add(particle);
5431
+ continue;
5432
+ }
5433
+ for (const updater of this._container.particleUpdaters) {
5434
+ updater.update(particle, delta);
5435
+ }
5436
+ if (!particle.spawning) {
5437
+ for (const plugin of this._postParticleUpdatePlugins) {
5438
+ plugin.postParticleUpdate?.(particle, delta);
5439
+ }
5440
+ }
5441
+ this._updateParticleBucket(particle);
5442
+ }
5443
+ };
5324
5444
  }
5325
5445
 
5326
5446
  class Retina {
@@ -5336,9 +5456,8 @@
5336
5456
  const container = this.container, options = container.actualOptions;
5337
5457
  this.pixelRatio = options.detectRetina ? devicePixelRatio : defaultRatio;
5338
5458
  this.reduceFactor = defaultReduceFactor;
5339
- const ratio = this.pixelRatio, canvas = container.canvas;
5340
- if (canvas.element) {
5341
- const element = canvas.element;
5459
+ const ratio = this.pixelRatio, canvas = container.canvas, element = canvas.domElement;
5460
+ if (element) {
5342
5461
  canvas.size.width = element.offsetWidth * ratio;
5343
5462
  canvas.size.height = element.offsetHeight * ratio;
5344
5463
  }