tsparticles 2.7.1 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v2.7.1
7
+ * v3.0.0-alpha.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -59,6 +59,7 @@ __webpack_require__.r(__webpack_exports__);
59
59
  __webpack_require__.d(__webpack_exports__, {
60
60
  "AnimatableColor": () => (/* reexport */ AnimatableColor),
61
61
  "AnimationOptions": () => (/* reexport */ AnimationOptions),
62
+ "AnimationValueWithRandom": () => (/* reexport */ AnimationValueWithRandom),
62
63
  "Background": () => (/* reexport */ Background),
63
64
  "BackgroundMask": () => (/* reexport */ BackgroundMask),
64
65
  "BackgroundMaskCover": () => (/* reexport */ BackgroundMaskCover),
@@ -85,6 +86,7 @@ __webpack_require__.d(__webpack_exports__, {
85
86
  "MoveGravity": () => (/* reexport */ MoveGravity),
86
87
  "MovePath": () => (/* reexport */ MovePath),
87
88
  "MoveTrail": () => (/* reexport */ MoveTrail),
89
+ "MoveTrailFill": () => (/* reexport */ MoveTrailFill),
88
90
  "Opacity": () => (/* reexport */ Opacity),
89
91
  "OpacityAnimation": () => (/* reexport */ OpacityAnimation),
90
92
  "Options": () => (/* reexport */ Options),
@@ -99,6 +101,8 @@ __webpack_require__.d(__webpack_exports__, {
99
101
  "ParticlesOptions": () => (/* reexport */ ParticlesOptions),
100
102
  "Point": () => (/* reexport */ Point),
101
103
  "Range": () => (/* reexport */ Range),
104
+ "RangedAnimationOptions": () => (/* reexport */ RangedAnimationOptions),
105
+ "RangedAnimationValueWithRandom": () => (/* reexport */ RangedAnimationValueWithRandom),
102
106
  "Rectangle": () => (/* reexport */ Rectangle),
103
107
  "ResizeEvent": () => (/* reexport */ ResizeEvent),
104
108
  "Responsive": () => (/* reexport */ Responsive),
@@ -132,6 +136,7 @@ __webpack_require__.d(__webpack_exports__, {
132
136
  "circleBounceDataFromParticle": () => (/* reexport */ circleBounceDataFromParticle),
133
137
  "clamp": () => (/* reexport */ clamp),
134
138
  "clear": () => (/* reexport */ clear),
139
+ "clearCanvas": () => (/* reexport */ clearCanvas),
135
140
  "collisionVelocity": () => (/* reexport */ collisionVelocity),
136
141
  "colorMix": () => (/* reexport */ colorMix),
137
142
  "colorToHsl": () => (/* reexport */ colorToHsl),
@@ -149,6 +154,7 @@ __webpack_require__.d(__webpack_exports__, {
149
154
  "executeOnSingleOrMultiple": () => (/* reexport */ executeOnSingleOrMultiple),
150
155
  "findItemFromSingleOrMultiple": () => (/* reexport */ findItemFromSingleOrMultiple),
151
156
  "generatedAttribute": () => (/* reexport */ generatedAttribute),
157
+ "getContext": () => (/* reexport */ getContext),
152
158
  "getDistance": () => (/* reexport */ getDistance),
153
159
  "getDistances": () => (/* reexport */ getDistances),
154
160
  "getEasing": () => (/* reexport */ getEasing),
@@ -169,6 +175,7 @@ __webpack_require__.d(__webpack_exports__, {
169
175
  "hasMatchMedia": () => (/* reexport */ hasMatchMedia),
170
176
  "hslToRgb": () => (/* reexport */ hslToRgb),
171
177
  "hslaToRgba": () => (/* reexport */ hslaToRgba),
178
+ "initParticleNumericAnimationValue": () => (/* reexport */ initParticleNumericAnimationValue),
172
179
  "isDivModeEnabled": () => (/* reexport */ isDivModeEnabled),
173
180
  "isInArray": () => (/* reexport */ isInArray),
174
181
  "isPointInside": () => (/* reexport */ isPointInside),
@@ -186,7 +193,7 @@ __webpack_require__.d(__webpack_exports__, {
186
193
  "mouseMoveEvent": () => (/* reexport */ mouseMoveEvent),
187
194
  "mouseOutEvent": () => (/* reexport */ mouseOutEvent),
188
195
  "mouseUpEvent": () => (/* reexport */ mouseUpEvent),
189
- "paintBase": () => (/* reexport */ paintBase),
196
+ "paintCanvas": () => (/* reexport */ paintCanvas),
190
197
  "parseAlpha": () => (/* reexport */ parseAlpha),
191
198
  "randomInRange": () => (/* reexport */ randomInRange),
192
199
  "rangeColorToHsl": () => (/* reexport */ rangeColorToHsl),
@@ -208,50 +215,6 @@ __webpack_require__.d(__webpack_exports__, {
208
215
  "visibilityChangeEvent": () => (/* reexport */ visibilityChangeEvent)
209
216
  });
210
217
 
211
- ;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/EventDispatcher.js
212
- class EventDispatcher {
213
- constructor() {
214
- this._listeners = new Map();
215
- }
216
- addEventListener(type, listener) {
217
- var _a;
218
- this.removeEventListener(type, listener);
219
- if (!this._listeners.get(type)) {
220
- this._listeners.set(type, []);
221
- }
222
- (_a = this._listeners.get(type)) === null || _a === void 0 ? void 0 : _a.push(listener);
223
- }
224
- dispatchEvent(type, args) {
225
- var _a;
226
- (_a = this._listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach(handler => handler(args));
227
- }
228
- hasEventListener(type) {
229
- return !!this._listeners.get(type);
230
- }
231
- removeAllEventListeners(type) {
232
- if (!type) {
233
- this._listeners = new Map();
234
- } else {
235
- this._listeners.delete(type);
236
- }
237
- }
238
- removeEventListener(type, listener) {
239
- const arr = this._listeners.get(type);
240
- if (!arr) {
241
- return;
242
- }
243
- const length = arr.length,
244
- idx = arr.indexOf(listener);
245
- if (idx < 0) {
246
- return;
247
- }
248
- if (length === 1) {
249
- this._listeners.delete(type);
250
- } else {
251
- arr.splice(idx, 1);
252
- }
253
- }
254
- }
255
218
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Vector3d.js
256
219
  class Vector3d {
257
220
  constructor(xOrCoords, y, z) {
@@ -749,6 +712,39 @@ function itemFromSingleOrMultiple(obj, index, useIndex) {
749
712
  function findItemFromSingleOrMultiple(obj, callback) {
750
713
  return obj instanceof Array ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
751
714
  }
715
+ function initParticleNumericAnimationValue(options, pxRatio) {
716
+ const valueRange = options.value,
717
+ animationOptions = options.animation;
718
+ const res = {
719
+ enable: options.animation.enable,
720
+ value: getRangeValue(options.value) * pxRatio,
721
+ max: getRangeMax(valueRange) * pxRatio,
722
+ min: getRangeMin(valueRange) * pxRatio,
723
+ loops: 0,
724
+ maxLoops: getRangeValue(options.animation.count)
725
+ };
726
+ if (animationOptions.enable) {
727
+ res.status = "increasing";
728
+ res.decay = 1 - getRangeValue(animationOptions.decay);
729
+ switch (animationOptions.startValue) {
730
+ case "min":
731
+ res.value = res.min;
732
+ res.status = "increasing";
733
+ break;
734
+ case "random":
735
+ res.value = randomInRange(res);
736
+ res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
737
+ break;
738
+ case "max":
739
+ default:
740
+ res.value = res.max;
741
+ res.status = "decreasing";
742
+ break;
743
+ }
744
+ }
745
+ res.initialValue = res.value;
746
+ return res;
747
+ }
752
748
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/ColorUtils.js
753
749
 
754
750
 
@@ -1032,6 +1028,49 @@ function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1032
1028
  }
1033
1029
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/CanvasUtils.js
1034
1030
 
1031
+ function paintBase(context, dimension, baseColor) {
1032
+ context.fillStyle = baseColor !== null && baseColor !== void 0 ? baseColor : "rgba(0,0,0,0)";
1033
+ context.fillRect(0, 0, dimension.width, dimension.height);
1034
+ }
1035
+ function paintImage(context, dimension, image, opacity) {
1036
+ if (!image) {
1037
+ return;
1038
+ }
1039
+ context.globalAlpha = opacity;
1040
+ context.drawImage(image, 0, 0, dimension.width, dimension.height);
1041
+ context.globalAlpha = 1;
1042
+ }
1043
+ function getContext(canvas) {
1044
+ const context = canvas.getContext("2d");
1045
+ if (!context) {
1046
+ throw new Error("Error tsParticles - No canvas context found");
1047
+ }
1048
+ return context;
1049
+ }
1050
+ function clearCanvas(context, size, options, trailFill, coverColorStyle) {
1051
+ if (options.backgroundMask.enable) {
1052
+ paintCanvas(context, size, options, coverColorStyle);
1053
+ } else {
1054
+ const trail = options.particles.move.trail;
1055
+ if (trail.enable && trail.length > 0 && trailFill) {
1056
+ if (trailFill.color) {
1057
+ paintBase(context, size, getStyleFromRgb(trailFill.color, trailFill.opacity));
1058
+ } else if (trailFill.image) {
1059
+ paintImage(context, size, trailFill.image, trailFill.opacity);
1060
+ }
1061
+ } else {
1062
+ clear(context, size);
1063
+ }
1064
+ }
1065
+ }
1066
+ function paintCanvas(context, size, options, coverColorStyle) {
1067
+ if (options.backgroundMask.enable && coverColorStyle) {
1068
+ clear(context, size);
1069
+ paintBase(context, size, coverColorStyle);
1070
+ } else {
1071
+ paintBase(context, size);
1072
+ }
1073
+ }
1035
1074
  function drawLine(context, begin, end) {
1036
1075
  context.beginPath();
1037
1076
  context.moveTo(begin.x, begin.y);
@@ -1045,10 +1084,6 @@ function drawTriangle(context, p1, p2, p3) {
1045
1084
  context.lineTo(p3.x, p3.y);
1046
1085
  context.closePath();
1047
1086
  }
1048
- function paintBase(context, dimension, baseColor) {
1049
- context.fillStyle = baseColor !== null && baseColor !== void 0 ? baseColor : "rgba(0,0,0,0)";
1050
- context.fillRect(0, 0, dimension.width, dimension.height);
1051
- }
1052
1087
  function clear(context, dimension) {
1053
1088
  context.clearRect(0, 0, dimension.width, dimension.height);
1054
1089
  }
@@ -1202,17 +1237,9 @@ class Canvas {
1202
1237
  return this.container.actualOptions.fullScreen.enable;
1203
1238
  }
1204
1239
  clear() {
1205
- const options = this.container.actualOptions,
1206
- trail = options.particles.move.trail;
1207
- if (options.backgroundMask.enable) {
1208
- this.paint();
1209
- } else if (trail.enable && trail.length > 0 && this._trailFillColor) {
1210
- this._paintBase(getStyleFromRgb(this._trailFillColor, 1 / trail.length));
1211
- } else {
1212
- this.draw(ctx => {
1213
- clear(ctx, this.size);
1214
- });
1215
- }
1240
+ this.draw(ctx => {
1241
+ clearCanvas(ctx, this.size, this.container.actualOptions, this._trailFill, this._coverColorStyle);
1242
+ });
1216
1243
  }
1217
1244
  destroy() {
1218
1245
  var _a, _b;
@@ -1298,63 +1325,28 @@ class Canvas {
1298
1325
  drawPlugin(ctx, plugin, delta);
1299
1326
  });
1300
1327
  }
1301
- init() {
1328
+ async init() {
1302
1329
  var _a;
1303
- this.resize();
1330
+ this._resize();
1304
1331
  this._initStyle();
1305
1332
  this._initCover();
1306
- this._initTrail();
1307
- this.initBackground();
1333
+ try {
1334
+ await this._initTrail();
1335
+ } catch (e) {
1336
+ console.error(e);
1337
+ }
1338
+ this._initBackground();
1308
1339
  if (this.element) {
1309
1340
  (_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.element, {
1310
1341
  attributes: true
1311
1342
  });
1312
1343
  }
1313
- this.initUpdaters();
1314
- this.initPlugins();
1315
- this.paint();
1316
- }
1317
- initBackground() {
1318
- const options = this.container.actualOptions,
1319
- background = options.background,
1320
- element = this.element,
1321
- elementStyle = element === null || element === void 0 ? void 0 : element.style;
1322
- if (!elementStyle) {
1323
- return;
1324
- }
1325
- if (background.color) {
1326
- const color = rangeColorToRgb(background.color);
1327
- elementStyle.backgroundColor = color ? getStyleFromRgb(color, background.opacity) : "";
1328
- } else {
1329
- elementStyle.backgroundColor = "";
1330
- }
1331
- elementStyle.backgroundImage = background.image || "";
1332
- elementStyle.backgroundPosition = background.position || "";
1333
- elementStyle.backgroundRepeat = background.repeat || "";
1334
- elementStyle.backgroundSize = background.size || "";
1335
- }
1336
- initPlugins() {
1337
- this._resizePlugins = [];
1338
- for (const [, plugin] of this.container.plugins) {
1339
- if (plugin.resize) {
1340
- this._resizePlugins.push(plugin);
1341
- }
1342
- if (plugin.particleFillColor || plugin.particleStrokeColor) {
1343
- this._colorPlugins.push(plugin);
1344
- }
1345
- }
1346
- }
1347
- initUpdaters() {
1348
- this._preDrawUpdaters = [];
1349
- this._postDrawUpdaters = [];
1350
- for (const updater of this.container.particles.updaters) {
1351
- if (updater.afterDraw) {
1352
- this._postDrawUpdaters.push(updater);
1353
- }
1354
- if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1355
- this._preDrawUpdaters.push(updater);
1356
- }
1357
- }
1344
+ this._initUpdaters();
1345
+ this._initPlugins();
1346
+ this._paint();
1347
+ this.container.updateActualOptions();
1348
+ this._resize();
1349
+ this._initBackground();
1358
1350
  }
1359
1351
  loadCanvas(canvas) {
1360
1352
  var _a, _b;
@@ -1367,53 +1359,18 @@ class Canvas {
1367
1359
  this._originalStyle = deepExtend({}, this.element.style);
1368
1360
  this.size.height = canvas.offsetHeight;
1369
1361
  this.size.width = canvas.offsetWidth;
1370
- this._context = this.element.getContext("2d");
1362
+ this._context = getContext(canvas);
1371
1363
  (_b = this._mutationObserver) === null || _b === void 0 ? void 0 : _b.observe(this.element, {
1372
1364
  attributes: true
1373
1365
  });
1374
1366
  this.container.retina.init();
1375
- this.initBackground();
1376
- }
1377
- paint() {
1378
- const options = this.container.actualOptions;
1379
- this.draw(ctx => {
1380
- if (options.backgroundMask.enable && options.backgroundMask.cover) {
1381
- clear(ctx, this.size);
1382
- this._paintBase(this._coverColorStyle);
1383
- } else {
1384
- this._paintBase();
1385
- }
1386
- });
1387
- }
1388
- resize() {
1389
- if (!this.element) {
1390
- return;
1391
- }
1392
- const container = this.container,
1393
- pxRatio = container.retina.pixelRatio,
1394
- size = container.canvas.size,
1395
- newSize = {
1396
- width: this.element.offsetWidth * pxRatio,
1397
- height: this.element.offsetHeight * pxRatio
1398
- };
1399
- if (newSize.height === size.height && newSize.width === size.width && newSize.height === this.element.height && newSize.width === this.element.width) {
1400
- return;
1401
- }
1402
- const oldSize = Object.assign({}, size);
1403
- this.element.width = size.width = this.element.offsetWidth * pxRatio;
1404
- this.element.height = size.height = this.element.offsetHeight * pxRatio;
1405
- if (this.container.started) {
1406
- this.resizeFactor = {
1407
- width: size.width / oldSize.width,
1408
- height: size.height / oldSize.height
1409
- };
1410
- }
1367
+ this._initBackground();
1411
1368
  }
1412
1369
  async windowResize() {
1413
1370
  if (!this.element) {
1414
1371
  return;
1415
1372
  }
1416
- this.resize();
1373
+ this._resize();
1417
1374
  const container = this.container,
1418
1375
  needsRefresh = container.updateActualOptions();
1419
1376
  container.particles.setDensity();
@@ -1474,6 +1431,25 @@ class Canvas {
1474
1431
  }
1475
1432
  return [fColor, sColor];
1476
1433
  }
1434
+ _initBackground() {
1435
+ const options = this.container.actualOptions,
1436
+ background = options.background,
1437
+ element = this.element,
1438
+ elementStyle = element === null || element === void 0 ? void 0 : element.style;
1439
+ if (!elementStyle) {
1440
+ return;
1441
+ }
1442
+ if (background.color) {
1443
+ const color = rangeColorToRgb(background.color);
1444
+ elementStyle.backgroundColor = color ? getStyleFromRgb(color, background.opacity) : "";
1445
+ } else {
1446
+ elementStyle.backgroundColor = "";
1447
+ }
1448
+ elementStyle.backgroundImage = background.image || "";
1449
+ elementStyle.backgroundPosition = background.position || "";
1450
+ elementStyle.backgroundRepeat = background.repeat || "";
1451
+ elementStyle.backgroundSize = background.size || "";
1452
+ }
1477
1453
  _initCover() {
1478
1454
  const options = this.container.actualOptions,
1479
1455
  cover = options.backgroundMask.cover,
@@ -1489,6 +1465,17 @@ class Canvas {
1489
1465
  this._coverColorStyle = getStyleFromRgb(coverColor, coverColor.a);
1490
1466
  }
1491
1467
  }
1468
+ _initPlugins() {
1469
+ this._resizePlugins = [];
1470
+ for (const [, plugin] of this.container.plugins) {
1471
+ if (plugin.resize) {
1472
+ this._resizePlugins.push(plugin);
1473
+ }
1474
+ if (plugin.particleFillColor || plugin.particleStrokeColor) {
1475
+ this._colorPlugins.push(plugin);
1476
+ }
1477
+ }
1478
+ }
1492
1479
  _initStyle() {
1493
1480
  const element = this.element,
1494
1481
  options = this.container.actualOptions;
@@ -1512,20 +1499,58 @@ class Canvas {
1512
1499
  element.style.setProperty(key, value, "important");
1513
1500
  }
1514
1501
  }
1515
- _initTrail() {
1502
+ async _initTrail() {
1516
1503
  const options = this.container.actualOptions,
1517
1504
  trail = options.particles.move.trail,
1518
- fillColor = rangeColorToRgb(trail.fillColor);
1519
- if (fillColor) {
1505
+ trailFill = trail.fill;
1506
+ if (!trail.enable) {
1507
+ return;
1508
+ }
1509
+ if (trailFill.color) {
1510
+ const fillColor = rangeColorToRgb(trailFill.color);
1511
+ if (!fillColor) {
1512
+ return;
1513
+ }
1520
1514
  const trail = options.particles.move.trail;
1521
- this._trailFillColor = Object.assign(Object.assign({}, fillColor), {
1522
- a: 1 / trail.length
1515
+ this._trailFill = {
1516
+ color: Object.assign({}, fillColor),
1517
+ opacity: 1 / trail.length
1518
+ };
1519
+ } else {
1520
+ await new Promise((resolve, reject) => {
1521
+ if (!trailFill.image) {
1522
+ return;
1523
+ }
1524
+ const img = document.createElement("img");
1525
+ img.addEventListener("load", () => {
1526
+ this._trailFill = {
1527
+ image: img,
1528
+ opacity: 1 / trail.length
1529
+ };
1530
+ resolve();
1531
+ });
1532
+ img.addEventListener("error", evt => {
1533
+ reject(evt.error);
1534
+ });
1535
+ img.src = trailFill.image;
1523
1536
  });
1524
1537
  }
1525
1538
  }
1526
- _paintBase(baseColor) {
1539
+ _initUpdaters() {
1540
+ this._preDrawUpdaters = [];
1541
+ this._postDrawUpdaters = [];
1542
+ for (const updater of this.container.particles.updaters) {
1543
+ if (updater.afterDraw) {
1544
+ this._postDrawUpdaters.push(updater);
1545
+ }
1546
+ if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1547
+ this._preDrawUpdaters.push(updater);
1548
+ }
1549
+ }
1550
+ }
1551
+ _paint() {
1527
1552
  this.draw(ctx => {
1528
- paintBase(ctx, this.size, baseColor);
1553
+ paintCanvas(ctx, this.size, this.container.actualOptions, this._coverColorStyle);
1529
1554
  });
1530
1555
  }
1531
1556
  _repairStyle() {
@@ -1536,7 +1561,7 @@ class Canvas {
1536
1561
  }
1537
1562
  (_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
1538
1563
  this._initStyle();
1539
- this.initBackground();
1564
+ this._initBackground();
1540
1565
  (_b = this._mutationObserver) === null || _b === void 0 ? void 0 : _b.observe(element, {
1541
1566
  attributes: true
1542
1567
  });
@@ -1554,6 +1579,30 @@ class Canvas {
1554
1579
  element.style.width = originalStyle.width;
1555
1580
  element.style.height = originalStyle.height;
1556
1581
  }
1582
+ _resize() {
1583
+ if (!this.element) {
1584
+ return;
1585
+ }
1586
+ const container = this.container,
1587
+ pxRatio = container.retina.pixelRatio,
1588
+ size = container.canvas.size,
1589
+ newSize = {
1590
+ width: this.element.offsetWidth * pxRatio,
1591
+ height: this.element.offsetHeight * pxRatio
1592
+ };
1593
+ if (newSize.height === size.height && newSize.width === size.width && newSize.height === this.element.height && newSize.width === this.element.width) {
1594
+ return;
1595
+ }
1596
+ const oldSize = Object.assign({}, size);
1597
+ this.element.width = size.width = this.element.offsetWidth * pxRatio;
1598
+ this.element.height = size.height = this.element.offsetHeight * pxRatio;
1599
+ if (this.container.started) {
1600
+ this.resizeFactor = {
1601
+ width: size.width / oldSize.width,
1602
+ height: size.height / oldSize.height
1603
+ };
1604
+ }
1605
+ }
1557
1606
  _setFullScreenStyle() {
1558
1607
  const element = this.element;
1559
1608
  if (!element) {
@@ -2470,6 +2519,55 @@ class CollisionsOverlap {
2470
2519
  }
2471
2520
  }
2472
2521
  }
2522
+ ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/AnimationOptions.js
2523
+
2524
+ class AnimationOptions {
2525
+ constructor() {
2526
+ this.count = 0;
2527
+ this.enable = false;
2528
+ this.speed = 1;
2529
+ this.decay = 0;
2530
+ this.sync = false;
2531
+ }
2532
+ load(data) {
2533
+ if (!data) {
2534
+ return;
2535
+ }
2536
+ if (data.count !== undefined) {
2537
+ this.count = setRangeValue(data.count);
2538
+ }
2539
+ if (data.enable !== undefined) {
2540
+ this.enable = data.enable;
2541
+ }
2542
+ if (data.speed !== undefined) {
2543
+ this.speed = setRangeValue(data.speed);
2544
+ }
2545
+ if (data.decay !== undefined) {
2546
+ this.decay = setRangeValue(data.decay);
2547
+ }
2548
+ if (data.sync !== undefined) {
2549
+ this.sync = data.sync;
2550
+ }
2551
+ }
2552
+ }
2553
+ class RangedAnimationOptions extends AnimationOptions {
2554
+ constructor() {
2555
+ super();
2556
+ this.startValue = "random";
2557
+ }
2558
+ load(data) {
2559
+ super.load(data);
2560
+ if (!data) {
2561
+ return;
2562
+ }
2563
+ if (data.minimumValue !== undefined) {
2564
+ this.minimumValue = data.minimumValue;
2565
+ }
2566
+ if (data.startValue !== undefined) {
2567
+ this.startValue = data.startValue;
2568
+ }
2569
+ }
2570
+ }
2473
2571
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Random.js
2474
2572
  class Random {
2475
2573
  constructor() {
@@ -2491,6 +2589,8 @@ class Random {
2491
2589
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/ValueWithRandom.js
2492
2590
 
2493
2591
 
2592
+
2593
+
2494
2594
  class ValueWithRandom {
2495
2595
  constructor() {
2496
2596
  this.random = new Random();
@@ -2510,6 +2610,44 @@ class ValueWithRandom {
2510
2610
  }
2511
2611
  }
2512
2612
  }
2613
+ class AnimationValueWithRandom extends ValueWithRandom {
2614
+ constructor() {
2615
+ super();
2616
+ this.animation = new AnimationOptions();
2617
+ }
2618
+ get anim() {
2619
+ return this.animation;
2620
+ }
2621
+ set anim(value) {
2622
+ this.animation = value;
2623
+ }
2624
+ load(data) {
2625
+ var _a;
2626
+ super.load(data);
2627
+ if (!data) {
2628
+ return;
2629
+ }
2630
+ const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
2631
+ if (animation !== undefined) {
2632
+ this.animation.load(animation);
2633
+ }
2634
+ }
2635
+ }
2636
+ class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
2637
+ constructor() {
2638
+ super();
2639
+ this.animation = new RangedAnimationOptions();
2640
+ }
2641
+ load(data) {
2642
+ super.load(data);
2643
+ if (!data) {
2644
+ return;
2645
+ }
2646
+ if (data.animation !== undefined) {
2647
+ this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
2648
+ }
2649
+ }
2650
+ }
2513
2651
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js
2514
2652
 
2515
2653
  class ParticlesBounceFactor extends ValueWithRandom {
@@ -2704,14 +2842,36 @@ class MovePath {
2704
2842
  }
2705
2843
  }
2706
2844
  }
2845
+ ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveTrailFill.js
2846
+
2847
+ class MoveTrailFill {
2848
+ load(data) {
2849
+ if (!data) {
2850
+ return;
2851
+ }
2852
+ if (data.color !== undefined) {
2853
+ this.color = OptionsColor.create(this.color, data.color);
2854
+ }
2855
+ if (data.image !== undefined) {
2856
+ this.image = data.image;
2857
+ }
2858
+ }
2859
+ }
2707
2860
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveTrail.js
2708
2861
 
2709
2862
  class MoveTrail {
2710
2863
  constructor() {
2711
2864
  this.enable = false;
2712
2865
  this.length = 10;
2713
- this.fillColor = new OptionsColor();
2714
- this.fillColor.value = "#000000";
2866
+ this.fill = new MoveTrailFill();
2867
+ }
2868
+ get fillColor() {
2869
+ return this.fill.color;
2870
+ }
2871
+ set fillColor(value) {
2872
+ this.fill.load({
2873
+ color: value
2874
+ });
2715
2875
  }
2716
2876
  load(data) {
2717
2877
  if (!data) {
@@ -2720,7 +2880,11 @@ class MoveTrail {
2720
2880
  if (data.enable !== undefined) {
2721
2881
  this.enable = data.enable;
2722
2882
  }
2723
- this.fillColor = OptionsColor.create(this.fillColor, data.fillColor);
2883
+ if (data.fill !== undefined || data.fillColor !== undefined) {
2884
+ this.fill.load(data.fill || {
2885
+ color: data.fillColor
2886
+ });
2887
+ }
2724
2888
  if (data.length !== undefined) {
2725
2889
  this.length = data.length;
2726
2890
  }
@@ -2888,47 +3052,13 @@ class Move {
2888
3052
  }
2889
3053
  }
2890
3054
  }
2891
- ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/AnimationOptions.js
2892
-
2893
- class AnimationOptions {
2894
- constructor() {
2895
- this.count = 0;
2896
- this.enable = false;
2897
- this.speed = 1;
2898
- this.decay = 0;
2899
- this.sync = false;
2900
- }
2901
- load(data) {
2902
- if (!data) {
2903
- return;
2904
- }
2905
- if (data.count !== undefined) {
2906
- this.count = setRangeValue(data.count);
2907
- }
2908
- if (data.enable !== undefined) {
2909
- this.enable = data.enable;
2910
- }
2911
- if (data.speed !== undefined) {
2912
- this.speed = setRangeValue(data.speed);
2913
- }
2914
- if (data.decay !== undefined) {
2915
- this.decay = setRangeValue(data.decay);
2916
- }
2917
- if (data.sync !== undefined) {
2918
- this.sync = data.sync;
2919
- }
2920
- }
2921
- }
2922
3055
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Opacity/OpacityAnimation.js
2923
3056
 
2924
- class OpacityAnimation extends AnimationOptions {
3057
+ class OpacityAnimation extends RangedAnimationOptions {
2925
3058
  constructor() {
2926
3059
  super();
2927
3060
  this.destroy = "none";
2928
- this.enable = false;
2929
3061
  this.speed = 2;
2930
- this.startValue = "random";
2931
- this.sync = false;
2932
3062
  }
2933
3063
  get opacity_min() {
2934
3064
  return this.minimumValue;
@@ -2937,34 +3067,22 @@ class OpacityAnimation extends AnimationOptions {
2937
3067
  this.minimumValue = value;
2938
3068
  }
2939
3069
  load(data) {
2940
- var _a;
3070
+ if ((data === null || data === void 0 ? void 0 : data.opacity_min) !== undefined && data.minimumValue === undefined) {
3071
+ data.minimumValue = data.opacity_min;
3072
+ }
3073
+ super.load(data);
2941
3074
  if (!data) {
2942
3075
  return;
2943
3076
  }
2944
- super.load(data);
2945
3077
  if (data.destroy !== undefined) {
2946
3078
  this.destroy = data.destroy;
2947
3079
  }
2948
- if (data.enable !== undefined) {
2949
- this.enable = data.enable;
2950
- }
2951
- this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.opacity_min;
2952
- if (data.speed !== undefined) {
2953
- this.speed = data.speed;
2954
- }
2955
- if (data.startValue !== undefined) {
2956
- this.startValue = data.startValue;
2957
- }
2958
- if (data.sync !== undefined) {
2959
- this.sync = data.sync;
2960
- }
2961
3080
  }
2962
3081
  }
2963
3082
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Opacity/Opacity.js
2964
3083
 
2965
3084
 
2966
-
2967
- class Opacity extends ValueWithRandom {
3085
+ class Opacity extends RangedAnimationValueWithRandom {
2968
3086
  constructor() {
2969
3087
  super();
2970
3088
  this.animation = new OpacityAnimation();
@@ -2977,18 +3095,6 @@ class Opacity extends ValueWithRandom {
2977
3095
  set anim(value) {
2978
3096
  this.animation = value;
2979
3097
  }
2980
- load(data) {
2981
- var _a;
2982
- if (!data) {
2983
- return;
2984
- }
2985
- super.load(data);
2986
- const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
2987
- if (animation !== undefined) {
2988
- this.animation.load(animation);
2989
- this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
2990
- }
2991
- }
2992
3098
  }
2993
3099
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Number/ParticlesDensity.js
2994
3100
  class ParticlesDensity {
@@ -3099,106 +3205,37 @@ class Shadow {
3099
3205
  }
3100
3206
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Shape/Shape.js
3101
3207
 
3102
- const charKey = "character",
3103
- charAltKey = "char",
3104
- imageKey = "image",
3105
- imageAltKey = "images",
3106
- polygonKey = "polygon",
3107
- polygonAltKey = "star";
3108
3208
  class Shape {
3109
3209
  constructor() {
3110
3210
  this.options = {};
3111
3211
  this.type = "circle";
3112
3212
  }
3113
- get character() {
3114
- var _a;
3115
- return (_a = this.options[charKey]) !== null && _a !== void 0 ? _a : this.options[charAltKey];
3116
- }
3117
- set character(value) {
3118
- this.options[charAltKey] = this.options[charKey] = value;
3119
- }
3120
- get custom() {
3121
- return this.options;
3122
- }
3123
- set custom(value) {
3124
- this.options = value;
3125
- }
3126
- get image() {
3127
- var _a;
3128
- return (_a = this.options[imageKey]) !== null && _a !== void 0 ? _a : this.options[imageAltKey];
3129
- }
3130
- set image(value) {
3131
- this.options[imageAltKey] = this.options[imageKey] = value;
3132
- }
3133
- get images() {
3134
- return this.image;
3135
- }
3136
- set images(value) {
3137
- this.image = value;
3138
- }
3139
- get polygon() {
3140
- var _a;
3141
- return (_a = this.options[polygonKey]) !== null && _a !== void 0 ? _a : this.options[polygonAltKey];
3142
- }
3143
- set polygon(value) {
3144
- this.options[polygonAltKey] = this.options[polygonKey] = value;
3145
- }
3146
- get stroke() {
3147
- return [];
3148
- }
3149
- set stroke(_value) {}
3150
3213
  load(data) {
3151
- var _a, _b, _c;
3214
+ var _a;
3152
3215
  if (!data) {
3153
3216
  return;
3154
3217
  }
3155
- const options = (_a = data.options) !== null && _a !== void 0 ? _a : data.custom;
3218
+ const options = data.options;
3156
3219
  if (options !== undefined) {
3157
3220
  for (const shape in options) {
3158
3221
  const item = options[shape];
3159
3222
  if (item) {
3160
- this.options[shape] = deepExtend((_b = this.options[shape]) !== null && _b !== void 0 ? _b : {}, item);
3223
+ this.options[shape] = deepExtend((_a = this.options[shape]) !== null && _a !== void 0 ? _a : {}, item);
3161
3224
  }
3162
3225
  }
3163
3226
  }
3164
- this.loadShape(data.character, charKey, charAltKey, true);
3165
- this.loadShape(data.polygon, polygonKey, polygonAltKey, false);
3166
- this.loadShape((_c = data.image) !== null && _c !== void 0 ? _c : data.images, imageKey, imageAltKey, true);
3167
3227
  if (data.type !== undefined) {
3168
3228
  this.type = data.type;
3169
3229
  }
3170
3230
  }
3171
- loadShape(item, mainKey, altKey, altOverride) {
3172
- var _a, _b;
3173
- if (!item) {
3174
- return;
3175
- }
3176
- const isArray = item instanceof Array;
3177
- const emptyValue = isArray ? [] : {},
3178
- mainDifferentValues = isArray !== this.options[mainKey] instanceof Array,
3179
- altDifferentValues = isArray !== this.options[altKey] instanceof Array;
3180
- if (mainDifferentValues) {
3181
- this.options[mainKey] = emptyValue;
3182
- }
3183
- if (altDifferentValues && altOverride) {
3184
- this.options[altKey] = emptyValue;
3185
- }
3186
- this.options[mainKey] = deepExtend((_a = this.options[mainKey]) !== null && _a !== void 0 ? _a : emptyValue, item);
3187
- if (!this.options[altKey] || altOverride) {
3188
- this.options[altKey] = deepExtend((_b = this.options[altKey]) !== null && _b !== void 0 ? _b : emptyValue, item);
3189
- }
3190
- }
3191
3231
  }
3192
3232
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Size/SizeAnimation.js
3193
3233
 
3194
- class SizeAnimation extends AnimationOptions {
3234
+ class SizeAnimation extends RangedAnimationOptions {
3195
3235
  constructor() {
3196
3236
  super();
3197
3237
  this.destroy = "none";
3198
- this.enable = false;
3199
3238
  this.speed = 5;
3200
- this.startValue = "random";
3201
- this.sync = false;
3202
3239
  }
3203
3240
  get size_min() {
3204
3241
  return this.minimumValue;
@@ -3207,34 +3244,22 @@ class SizeAnimation extends AnimationOptions {
3207
3244
  this.minimumValue = value;
3208
3245
  }
3209
3246
  load(data) {
3210
- var _a;
3247
+ if ((data === null || data === void 0 ? void 0 : data.size_min) !== undefined && data.minimumValue === undefined) {
3248
+ data.minimumValue = data.size_min;
3249
+ }
3211
3250
  super.load(data);
3212
3251
  if (!data) {
3213
3252
  return;
3214
3253
  }
3215
- if (data.destroy !== undefined) {
3216
- this.destroy = data.destroy;
3217
- }
3218
- if (data.enable !== undefined) {
3219
- this.enable = data.enable;
3220
- }
3221
- this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.size_min;
3222
- if (data.speed !== undefined) {
3223
- this.speed = data.speed;
3224
- }
3225
- if (data.startValue !== undefined) {
3226
- this.startValue = data.startValue;
3227
- }
3228
- if (data.sync !== undefined) {
3229
- this.sync = data.sync;
3254
+ if (data.destroy !== undefined) {
3255
+ this.destroy = data.destroy;
3230
3256
  }
3231
3257
  }
3232
3258
  }
3233
3259
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Size/Size.js
3234
3260
 
3235
3261
 
3236
-
3237
- class Size extends ValueWithRandom {
3262
+ class Size extends RangedAnimationValueWithRandom {
3238
3263
  constructor() {
3239
3264
  super();
3240
3265
  this.animation = new SizeAnimation();
@@ -3247,18 +3272,6 @@ class Size extends ValueWithRandom {
3247
3272
  set anim(value) {
3248
3273
  this.animation = value;
3249
3274
  }
3250
- load(data) {
3251
- var _a;
3252
- super.load(data);
3253
- if (!data) {
3254
- return;
3255
- }
3256
- const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
3257
- if (animation !== undefined) {
3258
- this.animation.load(animation);
3259
- this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3260
- }
3261
- }
3262
3275
  }
3263
3276
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Stroke.js
3264
3277
 
@@ -3340,7 +3353,7 @@ class ParticlesOptions {
3340
3353
  this.zIndex = new ZIndex();
3341
3354
  }
3342
3355
  load(data) {
3343
- var _a, _b, _c, _d, _e, _f;
3356
+ var _a, _b, _c, _d;
3344
3357
  if (!data) {
3345
3358
  return;
3346
3359
  }
@@ -3372,9 +3385,9 @@ class ParticlesOptions {
3372
3385
  if (data.interactivity !== undefined) {
3373
3386
  this.interactivity = deepExtend({}, data.interactivity);
3374
3387
  }
3375
- const strokeToLoad = (_e = data.stroke) !== null && _e !== void 0 ? _e : (_f = data.shape) === null || _f === void 0 ? void 0 : _f.stroke;
3376
- if (strokeToLoad) {
3377
- this.stroke = executeOnSingleOrMultiple(strokeToLoad, t => {
3388
+ const stroke = data.stroke;
3389
+ if (stroke) {
3390
+ this.stroke = executeOnSingleOrMultiple(stroke, t => {
3378
3391
  const tmp = new Stroke();
3379
3392
  tmp.load(t);
3380
3393
  return tmp;
@@ -3438,6 +3451,7 @@ class Options {
3438
3451
  this.fpsLimit = 120;
3439
3452
  this.interactivity = new Interactivity(engine, container);
3440
3453
  this.manualParticles = [];
3454
+ this.name = "default";
3441
3455
  this.particles = loadParticlesOptions(this._engine, this._container);
3442
3456
  this.pauseOnBlur = true;
3443
3457
  this.pauseOnOutsideViewport = true;
@@ -3717,7 +3731,7 @@ class Particle {
3717
3731
  return this._getRollColor((_a = this.bubble.color) !== null && _a !== void 0 ? _a : getHslFromAnimation(this.strokeColor));
3718
3732
  }
3719
3733
  init(id, position, overrideOptions, group) {
3720
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3734
+ var _a, _b, _c, _d, _e, _f, _g;
3721
3735
  const container = this.container,
3722
3736
  engine = this._engine;
3723
3737
  this.id = id;
@@ -3769,39 +3783,8 @@ class Particle {
3769
3783
  this.pathGenerator.init(container);
3770
3784
  }
3771
3785
  }
3772
- const zIndexValue = getRangeValue(this.options.zIndex.value);
3773
3786
  container.retina.initParticle(this);
3774
- const sizeOptions = this.options.size,
3775
- sizeRange = sizeOptions.value,
3776
- sizeAnimation = sizeOptions.animation;
3777
- this.size = {
3778
- enable: sizeOptions.animation.enable,
3779
- value: getRangeValue(sizeOptions.value) * container.retina.pixelRatio,
3780
- max: getRangeMax(sizeRange) * pxRatio,
3781
- min: getRangeMin(sizeRange) * pxRatio,
3782
- loops: 0,
3783
- maxLoops: getRangeValue(sizeOptions.animation.count)
3784
- };
3785
- if (sizeAnimation.enable) {
3786
- this.size.status = "increasing";
3787
- this.size.decay = 1 - getRangeValue(sizeAnimation.decay);
3788
- switch (sizeAnimation.startValue) {
3789
- case "min":
3790
- this.size.value = this.size.min;
3791
- this.size.status = "increasing";
3792
- break;
3793
- case "random":
3794
- this.size.value = randomInRange(this.size);
3795
- this.size.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
3796
- break;
3797
- case "max":
3798
- default:
3799
- this.size.value = this.size.max;
3800
- this.size.status = "decreasing";
3801
- break;
3802
- }
3803
- }
3804
- this.size.initialValue = this.size.value;
3787
+ this.size = initParticleNumericAnimationValue(this.options.size, pxRatio);
3805
3788
  this.bubble = {
3806
3789
  inRange: false
3807
3790
  };
@@ -3809,30 +3792,10 @@ class Particle {
3809
3792
  inRange: false,
3810
3793
  factor: 1
3811
3794
  };
3812
- this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
3813
- this.initialPosition = this.position.copy();
3814
- const canvasSize = container.canvas.size,
3815
- moveCenter = Object.assign({}, this.options.move.center),
3816
- isCenterPercent = moveCenter.mode === "percent";
3817
- this.moveCenter = {
3818
- x: moveCenter.x * (isCenterPercent ? canvasSize.width / 100 : 1),
3819
- y: moveCenter.y * (isCenterPercent ? canvasSize.height / 100 : 1),
3820
- radius: (_f = this.options.move.center.radius) !== null && _f !== void 0 ? _f : 0,
3821
- mode: (_g = this.options.move.center.mode) !== null && _g !== void 0 ? _g : "percent"
3822
- };
3823
- this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
3824
- switch (this.options.move.direction) {
3825
- case "inside":
3826
- this.outType = "inside";
3827
- break;
3828
- case "outside":
3829
- this.outType = "outside";
3830
- break;
3831
- }
3795
+ this._initPosition(position);
3832
3796
  this.initialVelocity = this._calculateVelocity();
3833
3797
  this.velocity = this.initialVelocity.copy();
3834
3798
  this.moveDecay = 1 - getRangeValue(this.options.move.decay);
3835
- this.offset = Vector.origin;
3836
3799
  const particles = container.particles;
3837
3800
  particles.needsSort = particles.needsSort || particles.lastZIndex < this.position.z;
3838
3801
  particles.lastZIndex = this.position.z;
@@ -3858,13 +3821,13 @@ class Particle {
3858
3821
  updater.init(this);
3859
3822
  }
3860
3823
  for (const mover of container.particles.movers) {
3861
- (_h = mover.init) === null || _h === void 0 ? void 0 : _h.call(mover, this);
3824
+ (_f = mover.init) === null || _f === void 0 ? void 0 : _f.call(mover, this);
3862
3825
  }
3863
3826
  if (drawer === null || drawer === void 0 ? void 0 : drawer.particleInit) {
3864
3827
  drawer.particleInit(container, this);
3865
3828
  }
3866
3829
  for (const [, plugin] of container.plugins) {
3867
- (_j = plugin.particleCreated) === null || _j === void 0 ? void 0 : _j.call(plugin, this);
3830
+ (_g = plugin.particleCreated) === null || _g === void 0 ? void 0 : _g.call(plugin, this);
3868
3831
  }
3869
3832
  }
3870
3833
  isInsideCanvas() {
@@ -3989,6 +3952,32 @@ class Particle {
3989
3952
  }
3990
3953
  return color;
3991
3954
  }
3955
+ _initPosition(position) {
3956
+ var _a, _b;
3957
+ const container = this.container,
3958
+ zIndexValue = getRangeValue(this.options.zIndex.value);
3959
+ this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
3960
+ this.initialPosition = this.position.copy();
3961
+ const canvasSize = container.canvas.size,
3962
+ moveCenter = Object.assign({}, this.options.move.center),
3963
+ isCenterPercent = moveCenter.mode === "percent";
3964
+ this.moveCenter = {
3965
+ x: moveCenter.x * (isCenterPercent ? canvasSize.width / 100 : 1),
3966
+ y: moveCenter.y * (isCenterPercent ? canvasSize.height / 100 : 1),
3967
+ radius: (_a = this.options.move.center.radius) !== null && _a !== void 0 ? _a : 0,
3968
+ mode: (_b = this.options.move.center.mode) !== null && _b !== void 0 ? _b : "percent"
3969
+ };
3970
+ this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
3971
+ switch (this.options.move.direction) {
3972
+ case "inside":
3973
+ this.outType = "inside";
3974
+ break;
3975
+ case "outside":
3976
+ this.outType = "outside";
3977
+ break;
3978
+ }
3979
+ this.offset = Vector.origin;
3980
+ }
3992
3981
  _loadShapeData(shapeOptions, reduceDuplicates) {
3993
3982
  const shapeData = shapeOptions.options[this.shape];
3994
3983
  if (shapeData) {
@@ -4288,8 +4277,8 @@ class Particles {
4288
4277
  }
4289
4278
  particle.destroy(override);
4290
4279
  this.array.splice(i--, 1);
4291
- const zIdx = this.zArray.indexOf(particle);
4292
- this.zArray.splice(zIdx, 1);
4280
+ const idx = this.zArray.indexOf(particle);
4281
+ this.zArray.splice(idx, 1);
4293
4282
  this.pool.push(particle);
4294
4283
  deleted++;
4295
4284
  this._engine.dispatchEvent("particleRemoved", {
@@ -4711,10 +4700,7 @@ class Container {
4711
4700
  this.plugins.set(id, plugin);
4712
4701
  }
4713
4702
  this.retina.init();
4714
- this.canvas.init();
4715
- this.updateActualOptions();
4716
- this.canvas.initBackground();
4717
- this.canvas.resize();
4703
+ await this.canvas.init();
4718
4704
  this.zLayers = this.actualOptions.zLayers;
4719
4705
  this.duration = getRangeValue(this.actualOptions.duration) * 1000;
4720
4706
  this._delay = getRangeValue(this.actualOptions.delay) * 1000;
@@ -4917,158 +4903,48 @@ class Container {
4917
4903
  }
4918
4904
  }
4919
4905
  }
4920
- ;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Loader.js
4921
-
4922
-
4923
-
4924
-
4925
- async function getDataFromUrl(jsonUrl, index) {
4926
- const url = itemFromSingleOrMultiple(jsonUrl, index);
4927
- if (!url) {
4928
- return;
4929
- }
4930
- const response = await fetch(url);
4931
- if (response.ok) {
4932
- return response.json();
4933
- }
4934
- console.error(`tsParticles - Error ${response.status} while retrieving config file`);
4935
- }
4936
- class Loader {
4937
- constructor(engine) {
4938
- this._engine = engine;
4906
+ ;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/EventDispatcher.js
4907
+ class EventDispatcher {
4908
+ constructor() {
4909
+ this._listeners = new Map();
4939
4910
  }
4940
- load(tagId, options, index) {
4941
- const params = {
4942
- index,
4943
- remote: false
4944
- };
4945
- if (typeof tagId === "string") {
4946
- params.tagId = tagId;
4947
- } else {
4948
- params.options = tagId;
4949
- }
4950
- if (typeof options === "number") {
4951
- params.index = options;
4952
- } else {
4953
- params.options = options !== null && options !== void 0 ? options : params.options;
4911
+ addEventListener(type, listener) {
4912
+ var _a;
4913
+ this.removeEventListener(type, listener);
4914
+ if (!this._listeners.get(type)) {
4915
+ this._listeners.set(type, []);
4954
4916
  }
4955
- return this.loadOptions(params);
4917
+ (_a = this._listeners.get(type)) === null || _a === void 0 ? void 0 : _a.push(listener);
4956
4918
  }
4957
- async loadJSON(tagId, jsonUrl, index) {
4958
- let url, id;
4959
- if (typeof jsonUrl === "number" || jsonUrl === undefined) {
4960
- url = tagId;
4961
- } else {
4962
- id = tagId;
4963
- url = jsonUrl;
4964
- }
4965
- return this.loadRemoteOptions({
4966
- tagId: id,
4967
- url,
4968
- index,
4969
- remote: true
4970
- });
4919
+ dispatchEvent(type, args) {
4920
+ var _a;
4921
+ (_a = this._listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach(handler => handler(args));
4971
4922
  }
4972
- async loadOptions(params) {
4973
- var _a, _b, _c;
4974
- const tagId = (_a = params.tagId) !== null && _a !== void 0 ? _a : `tsparticles${Math.floor(getRandom() * 10000)}`,
4975
- {
4976
- index,
4977
- url: jsonUrl,
4978
- remote
4979
- } = params,
4980
- options = remote ? await getDataFromUrl(jsonUrl, index) : params.options;
4981
- let domContainer = (_b = params.element) !== null && _b !== void 0 ? _b : document.getElementById(tagId);
4982
- if (!domContainer) {
4983
- domContainer = document.createElement("div");
4984
- domContainer.id = tagId;
4985
- (_c = document.querySelector("body")) === null || _c === void 0 ? void 0 : _c.append(domContainer);
4986
- }
4987
- const currentOptions = itemFromSingleOrMultiple(options, index),
4988
- dom = this._engine.dom(),
4989
- oldIndex = dom.findIndex(v => v.id === tagId);
4990
- if (oldIndex >= 0) {
4991
- const old = this._engine.domItem(oldIndex);
4992
- if (old && !old.destroyed) {
4993
- old.destroy();
4994
- dom.splice(oldIndex, 1);
4995
- }
4996
- }
4997
- let canvasEl;
4998
- if (domContainer.tagName.toLowerCase() === "canvas") {
4999
- canvasEl = domContainer;
5000
- canvasEl.dataset[generatedAttribute] = "false";
5001
- } else {
5002
- const existingCanvases = domContainer.getElementsByTagName("canvas");
5003
- if (existingCanvases.length) {
5004
- canvasEl = existingCanvases[0];
5005
- canvasEl.dataset[generatedAttribute] = "false";
5006
- } else {
5007
- canvasEl = document.createElement("canvas");
5008
- canvasEl.dataset[generatedAttribute] = "true";
5009
- domContainer.appendChild(canvasEl);
5010
- }
5011
- }
5012
- if (!canvasEl.style.width) {
5013
- canvasEl.style.width = "100%";
5014
- }
5015
- if (!canvasEl.style.height) {
5016
- canvasEl.style.height = "100%";
5017
- }
5018
- const newItem = new Container(this._engine, tagId, currentOptions);
5019
- if (oldIndex >= 0) {
5020
- dom.splice(oldIndex, 0, newItem);
4923
+ hasEventListener(type) {
4924
+ return !!this._listeners.get(type);
4925
+ }
4926
+ removeAllEventListeners(type) {
4927
+ if (!type) {
4928
+ this._listeners = new Map();
5021
4929
  } else {
5022
- dom.push(newItem);
4930
+ this._listeners.delete(type);
5023
4931
  }
5024
- newItem.canvas.loadCanvas(canvasEl);
5025
- await newItem.start();
5026
- return newItem;
5027
4932
  }
5028
- async loadRemoteOptions(params) {
5029
- return this.loadOptions(params);
5030
- }
5031
- async set(id, domContainer, options, index) {
5032
- const params = {
5033
- index,
5034
- remote: false
5035
- };
5036
- if (typeof id === "string") {
5037
- params.tagId = id;
5038
- } else {
5039
- params.element = id;
4933
+ removeEventListener(type, listener) {
4934
+ const arr = this._listeners.get(type);
4935
+ if (!arr) {
4936
+ return;
5040
4937
  }
5041
- if (domContainer instanceof HTMLElement) {
5042
- params.element = domContainer;
5043
- } else {
5044
- params.options = domContainer;
4938
+ const length = arr.length,
4939
+ idx = arr.indexOf(listener);
4940
+ if (idx < 0) {
4941
+ return;
5045
4942
  }
5046
- if (typeof options === "number") {
5047
- params.index = options;
4943
+ if (length === 1) {
4944
+ this._listeners.delete(type);
5048
4945
  } else {
5049
- params.options = options !== null && options !== void 0 ? options : params.options;
4946
+ arr.splice(idx, 1);
5050
4947
  }
5051
- return this.loadOptions(params);
5052
- }
5053
- async setJSON(id, domContainer, jsonUrl, index) {
5054
- let url, newId, newIndex, element;
5055
- if (id instanceof HTMLElement) {
5056
- element = id;
5057
- url = domContainer;
5058
- newIndex = jsonUrl;
5059
- } else {
5060
- newId = id;
5061
- element = domContainer;
5062
- url = jsonUrl;
5063
- newIndex = index;
5064
- }
5065
- return this.loadRemoteOptions({
5066
- tagId: newId,
5067
- url,
5068
- index: newIndex,
5069
- element,
5070
- remote: true
5071
- });
5072
4948
  }
5073
4949
  }
5074
4950
  ;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Plugins.js
@@ -5188,14 +5064,46 @@ class Plugins {
5188
5064
 
5189
5065
 
5190
5066
 
5067
+
5068
+
5069
+
5070
+ async function getDataFromUrl(data) {
5071
+ const url = itemFromSingleOrMultiple(data.url, data.index);
5072
+ if (!url) {
5073
+ return data.fallback;
5074
+ }
5075
+ const response = await fetch(url);
5076
+ if (response.ok) {
5077
+ return response.json();
5078
+ }
5079
+ console.error(`tsParticles - Error ${response.status} while retrieving config file`);
5080
+ return data.fallback;
5081
+ }
5191
5082
  class Engine {
5192
5083
  constructor() {
5084
+ this._configs = new Map();
5193
5085
  this._domArray = [];
5194
5086
  this._eventDispatcher = new EventDispatcher();
5195
- this._initialized = false;
5196
- this._loader = new Loader(this);
5197
5087
  this.plugins = new Plugins(this);
5198
5088
  }
5089
+ get configs() {
5090
+ const res = {};
5091
+ for (const [name, config] of this._configs) {
5092
+ res[name] = config;
5093
+ }
5094
+ return res;
5095
+ }
5096
+ addConfig(nameOrConfig, config) {
5097
+ var _a;
5098
+ if (typeof nameOrConfig === "string") {
5099
+ if (config) {
5100
+ config.name = nameOrConfig;
5101
+ this._configs.set(nameOrConfig, config);
5102
+ }
5103
+ } else {
5104
+ this._configs.set((_a = nameOrConfig.name) !== null && _a !== void 0 ? _a : "default", nameOrConfig);
5105
+ }
5106
+ }
5199
5107
  addEventListener(type, listener) {
5200
5108
  this._eventDispatcher.addEventListener(type, listener);
5201
5109
  }
@@ -5252,19 +5160,64 @@ class Engine {
5252
5160
  }
5253
5161
  dom.splice(index, 1);
5254
5162
  }
5255
- init() {
5256
- if (!this._initialized) {
5257
- this._initialized = true;
5163
+ async load(params) {
5164
+ var _a, _b, _c;
5165
+ const id = (_a = params.id) !== null && _a !== void 0 ? _a : `tsparticles${Math.floor(getRandom() * 10000)}`,
5166
+ {
5167
+ index,
5168
+ url
5169
+ } = params,
5170
+ options = url ? await getDataFromUrl({
5171
+ fallback: params.options,
5172
+ index,
5173
+ url: url
5174
+ }) : params.options;
5175
+ let domContainer = (_b = params.element) !== null && _b !== void 0 ? _b : document.getElementById(id);
5176
+ if (!domContainer) {
5177
+ domContainer = document.createElement("div");
5178
+ domContainer.id = id;
5179
+ (_c = document.querySelector("body")) === null || _c === void 0 ? void 0 : _c.append(domContainer);
5258
5180
  }
5259
- }
5260
- async load(tagId, options) {
5261
- return this._loader.load(tagId, options);
5262
- }
5263
- async loadFromArray(tagId, options, index) {
5264
- return this._loader.load(tagId, options, index);
5265
- }
5266
- async loadJSON(tagId, pathConfigJson, index) {
5267
- return this._loader.loadJSON(tagId, pathConfigJson, index);
5181
+ const currentOptions = itemFromSingleOrMultiple(options, index),
5182
+ dom = this.dom(),
5183
+ oldIndex = dom.findIndex(v => v.id === id);
5184
+ if (oldIndex >= 0) {
5185
+ const old = this.domItem(oldIndex);
5186
+ if (old && !old.destroyed) {
5187
+ old.destroy();
5188
+ dom.splice(oldIndex, 1);
5189
+ }
5190
+ }
5191
+ let canvasEl;
5192
+ if (domContainer.tagName.toLowerCase() === "canvas") {
5193
+ canvasEl = domContainer;
5194
+ canvasEl.dataset[generatedAttribute] = "false";
5195
+ } else {
5196
+ const existingCanvases = domContainer.getElementsByTagName("canvas");
5197
+ if (existingCanvases.length) {
5198
+ canvasEl = existingCanvases[0];
5199
+ canvasEl.dataset[generatedAttribute] = "false";
5200
+ } else {
5201
+ canvasEl = document.createElement("canvas");
5202
+ canvasEl.dataset[generatedAttribute] = "true";
5203
+ domContainer.appendChild(canvasEl);
5204
+ }
5205
+ }
5206
+ if (!canvasEl.style.width) {
5207
+ canvasEl.style.width = "100%";
5208
+ }
5209
+ if (!canvasEl.style.height) {
5210
+ canvasEl.style.height = "100%";
5211
+ }
5212
+ const newItem = new Container(this, id, currentOptions);
5213
+ if (oldIndex >= 0) {
5214
+ dom.splice(oldIndex, 0, newItem);
5215
+ } else {
5216
+ dom.push(newItem);
5217
+ }
5218
+ newItem.canvas.loadCanvas(canvasEl);
5219
+ await newItem.start();
5220
+ return newItem;
5268
5221
  }
5269
5222
  async refresh() {
5270
5223
  for (const instance of this.dom()) {
@@ -5274,16 +5227,10 @@ class Engine {
5274
5227
  removeEventListener(type, listener) {
5275
5228
  this._eventDispatcher.removeEventListener(type, listener);
5276
5229
  }
5277
- async set(id, element, options) {
5278
- return this._loader.set(id, element, options);
5279
- }
5280
- async setJSON(id, element, pathConfigJson, index) {
5281
- return this._loader.setJSON(id, element, pathConfigJson, index);
5282
- }
5283
5230
  setOnClickHandler(callback) {
5284
5231
  const dom = this.dom();
5285
5232
  if (!dom.length) {
5286
- throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");
5233
+ throw new Error("Can only set click handlers after calling tsParticles.load()");
5287
5234
  }
5288
5235
  for (const domItem of dom) {
5289
5236
  domItem.addClickHandler(callback);
@@ -5397,7 +5344,14 @@ const rgbColorManager = new RgbColorManager(),
5397
5344
  addColorManager(rgbColorManager);
5398
5345
  addColorManager(hslColorManager);
5399
5346
  const tsParticles = new Engine();
5400
- tsParticles.init();
5347
+
5348
+
5349
+
5350
+
5351
+
5352
+
5353
+
5354
+
5401
5355
 
5402
5356
 
5403
5357
 
@@ -7088,10 +7042,16 @@ async function loadRollUpdater(engine) {
7088
7042
  ;// CONCATENATED MODULE: ../pjs/dist/esm/index.js
7089
7043
  const initPjs = engine => {
7090
7044
  const particlesJS = (tagId, options) => {
7091
- return engine.load(tagId, options);
7045
+ return engine.load({
7046
+ id: tagId,
7047
+ options: options
7048
+ });
7092
7049
  };
7093
7050
  particlesJS.load = (tagId, pathConfigJson, callback) => {
7094
- engine.loadJSON(tagId, pathConfigJson).then(container => {
7051
+ engine.load({
7052
+ id: tagId,
7053
+ url: pathConfigJson
7054
+ }).then(container => {
7095
7055
  if (container) {
7096
7056
  callback(container);
7097
7057
  }
@@ -9608,42 +9568,14 @@ class OpacityUpdater {
9608
9568
  }
9609
9569
  init(particle) {
9610
9570
  const opacityOptions = particle.options.opacity;
9611
- particle.opacity = {
9612
- enable: opacityOptions.animation.enable,
9613
- max: getRangeMax(opacityOptions.value),
9614
- min: getRangeMin(opacityOptions.value),
9615
- value: getRangeValue(opacityOptions.value),
9616
- loops: 0,
9617
- maxLoops: getRangeValue(opacityOptions.animation.count)
9618
- };
9571
+ particle.opacity = initParticleNumericAnimationValue(opacityOptions, 1);
9619
9572
  const opacityAnimation = opacityOptions.animation;
9620
9573
  if (opacityAnimation.enable) {
9621
- particle.opacity.decay = 1 - getRangeValue(opacityAnimation.decay);
9622
- particle.opacity.status = "increasing";
9623
- const opacityRange = opacityOptions.value;
9624
- particle.opacity.min = getRangeMin(opacityRange);
9625
- particle.opacity.max = getRangeMax(opacityRange);
9626
- switch (opacityAnimation.startValue) {
9627
- case "min":
9628
- particle.opacity.value = particle.opacity.min;
9629
- particle.opacity.status = "increasing";
9630
- break;
9631
- case "random":
9632
- particle.opacity.value = randomInRange(particle.opacity);
9633
- particle.opacity.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
9634
- break;
9635
- case "max":
9636
- default:
9637
- particle.opacity.value = particle.opacity.max;
9638
- particle.opacity.status = "decreasing";
9639
- break;
9640
- }
9641
9574
  particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / 100 * this.container.retina.reduceFactor;
9642
9575
  if (!opacityAnimation.sync) {
9643
9576
  particle.opacity.velocity *= getRandom();
9644
9577
  }
9645
9578
  }
9646
- particle.opacity.initialValue = particle.opacity.value;
9647
9579
  }
9648
9580
  isEnabled(particle) {
9649
9581
  var _a, _b, _c, _d;