@tsparticles/engine 4.0.0-beta.6 → 4.0.0-beta.8

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.
@@ -60,7 +60,7 @@ export class Engine {
60
60
  return this._domArray;
61
61
  }
62
62
  get version() {
63
- return "4.0.0-beta.6";
63
+ return "4.0.0-beta.8";
64
64
  }
65
65
  addEventListener(type, listener) {
66
66
  this._eventDispatcher.addEventListener(type, listener);
@@ -134,20 +134,7 @@ export class Options {
134
134
  mode: paletteData.blendMode,
135
135
  },
136
136
  particles: {
137
- fill: {
138
- color: paletteData.fill
139
- ? {
140
- value: paletteData.colors,
141
- }
142
- : undefined,
143
- enable: paletteData.fill,
144
- },
145
- stroke: !paletteData.fill
146
- ? paletteData.colors.map(color => ({
147
- color: { value: color },
148
- width: 1,
149
- }))
150
- : undefined,
137
+ palette,
151
138
  },
152
139
  });
153
140
  };
@@ -18,6 +18,7 @@ export class ParticlesOptions {
18
18
  move;
19
19
  number;
20
20
  opacity;
21
+ palette;
21
22
  reduceDuplicates;
22
23
  shape;
23
24
  size;
@@ -45,6 +46,10 @@ export class ParticlesOptions {
45
46
  if (isNull(data)) {
46
47
  return;
47
48
  }
49
+ if (data.palette) {
50
+ this.palette = data.palette;
51
+ this._importPalette(this.palette);
52
+ }
48
53
  if (data.groups !== undefined) {
49
54
  for (const group of Object.keys(data.groups)) {
50
55
  if (!(group in data.groups)) {
@@ -99,4 +104,30 @@ export class ParticlesOptions {
99
104
  }
100
105
  }
101
106
  }
107
+ _importPalette = (palette) => {
108
+ const paletteData = this._pluginManager.getPalette(palette);
109
+ if (!paletteData) {
110
+ return;
111
+ }
112
+ this.load({
113
+ fill: {
114
+ color: paletteData.fill
115
+ ? {
116
+ value: paletteData.colors,
117
+ }
118
+ : undefined,
119
+ enable: paletteData.fill,
120
+ },
121
+ stroke: paletteData.fill
122
+ ? undefined
123
+ : paletteData.colors.map(color => ({
124
+ color: { value: color },
125
+ width: 1,
126
+ })),
127
+ blend: {
128
+ enable: true,
129
+ mode: paletteData.blendMode,
130
+ },
131
+ });
132
+ };
102
133
  }
@@ -326,6 +326,19 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
326
326
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
327
327
  return;
328
328
  }
329
+ switch (data.status) {
330
+ case AnimationStatus.increasing:
331
+ data.value += velocity;
332
+ break;
333
+ case AnimationStatus.decreasing:
334
+ data.value -= velocity;
335
+ break;
336
+ default:
337
+ break;
338
+ }
339
+ if (data.velocity && decay !== identity) {
340
+ data.velocity *= decay;
341
+ }
329
342
  switch (data.status) {
330
343
  case AnimationStatus.increasing:
331
344
  if (data.value >= maxValue) {
@@ -338,9 +351,6 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
338
351
  data.loops ??= minLoops;
339
352
  data.loops++;
340
353
  }
341
- else {
342
- data.value += velocity;
343
- }
344
354
  break;
345
355
  case AnimationStatus.decreasing:
346
356
  if (data.value <= minValue) {
@@ -353,18 +363,14 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
353
363
  data.loops ??= minLoops;
354
364
  data.loops++;
355
365
  }
356
- else {
357
- data.value -= velocity;
358
- }
359
366
  break;
360
367
  default:
361
368
  break;
362
369
  }
363
- if (data.velocity && decay !== identity) {
364
- data.velocity *= decay;
365
- }
366
370
  checkDestroy(particle, destroyType, data.value, minValue, maxValue);
367
- data.value = clamp(data.value, minValue, maxValue);
371
+ if (!particle.destroyed) {
372
+ data.value = clamp(data.value, minValue, maxValue);
373
+ }
368
374
  }
369
375
  export function cloneStyle(style) {
370
376
  const clonedStyle = safeDocument().createElement("div").style;
@@ -60,7 +60,7 @@ export class Engine {
60
60
  return this._domArray;
61
61
  }
62
62
  get version() {
63
- return "4.0.0-beta.6";
63
+ return "4.0.0-beta.8";
64
64
  }
65
65
  addEventListener(type, listener) {
66
66
  this._eventDispatcher.addEventListener(type, listener);
@@ -134,20 +134,7 @@ export class Options {
134
134
  mode: paletteData.blendMode,
135
135
  },
136
136
  particles: {
137
- fill: {
138
- color: paletteData.fill
139
- ? {
140
- value: paletteData.colors,
141
- }
142
- : undefined,
143
- enable: paletteData.fill,
144
- },
145
- stroke: !paletteData.fill
146
- ? paletteData.colors.map(color => ({
147
- color: { value: color },
148
- width: 1,
149
- }))
150
- : undefined,
137
+ palette,
151
138
  },
152
139
  });
153
140
  };
@@ -18,6 +18,7 @@ export class ParticlesOptions {
18
18
  move;
19
19
  number;
20
20
  opacity;
21
+ palette;
21
22
  reduceDuplicates;
22
23
  shape;
23
24
  size;
@@ -45,6 +46,10 @@ export class ParticlesOptions {
45
46
  if (isNull(data)) {
46
47
  return;
47
48
  }
49
+ if (data.palette) {
50
+ this.palette = data.palette;
51
+ this._importPalette(this.palette);
52
+ }
48
53
  if (data.groups !== undefined) {
49
54
  for (const group of Object.keys(data.groups)) {
50
55
  if (!(group in data.groups)) {
@@ -99,4 +104,30 @@ export class ParticlesOptions {
99
104
  }
100
105
  }
101
106
  }
107
+ _importPalette = (palette) => {
108
+ const paletteData = this._pluginManager.getPalette(palette);
109
+ if (!paletteData) {
110
+ return;
111
+ }
112
+ this.load({
113
+ fill: {
114
+ color: paletteData.fill
115
+ ? {
116
+ value: paletteData.colors,
117
+ }
118
+ : undefined,
119
+ enable: paletteData.fill,
120
+ },
121
+ stroke: paletteData.fill
122
+ ? undefined
123
+ : paletteData.colors.map(color => ({
124
+ color: { value: color },
125
+ width: 1,
126
+ })),
127
+ blend: {
128
+ enable: true,
129
+ mode: paletteData.blendMode,
130
+ },
131
+ });
132
+ };
102
133
  }
@@ -326,6 +326,19 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
326
326
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
327
327
  return;
328
328
  }
329
+ switch (data.status) {
330
+ case AnimationStatus.increasing:
331
+ data.value += velocity;
332
+ break;
333
+ case AnimationStatus.decreasing:
334
+ data.value -= velocity;
335
+ break;
336
+ default:
337
+ break;
338
+ }
339
+ if (data.velocity && decay !== identity) {
340
+ data.velocity *= decay;
341
+ }
329
342
  switch (data.status) {
330
343
  case AnimationStatus.increasing:
331
344
  if (data.value >= maxValue) {
@@ -338,9 +351,6 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
338
351
  data.loops ??= minLoops;
339
352
  data.loops++;
340
353
  }
341
- else {
342
- data.value += velocity;
343
- }
344
354
  break;
345
355
  case AnimationStatus.decreasing:
346
356
  if (data.value <= minValue) {
@@ -353,18 +363,14 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
353
363
  data.loops ??= minLoops;
354
364
  data.loops++;
355
365
  }
356
- else {
357
- data.value -= velocity;
358
- }
359
366
  break;
360
367
  default:
361
368
  break;
362
369
  }
363
- if (data.velocity && decay !== identity) {
364
- data.velocity *= decay;
365
- }
366
370
  checkDestroy(particle, destroyType, data.value, minValue, maxValue);
367
- data.value = clamp(data.value, minValue, maxValue);
371
+ if (!particle.destroyed) {
372
+ data.value = clamp(data.value, minValue, maxValue);
373
+ }
368
374
  }
369
375
  export function cloneStyle(style) {
370
376
  const clonedStyle = safeDocument().createElement("div").style;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * tsParticles Engine v4.0.0-beta.6
2
+ * tsParticles Engine v4.0.0-beta.8
3
3
  * Author: Matteo Bruni
4
4
  * MIT license: https://opensource.org/licenses/MIT
5
5
  * Website: https://particles.js.org/
@@ -60,7 +60,7 @@ export class Engine {
60
60
  return this._domArray;
61
61
  }
62
62
  get version() {
63
- return "4.0.0-beta.6";
63
+ return "4.0.0-beta.8";
64
64
  }
65
65
  addEventListener(type, listener) {
66
66
  this._eventDispatcher.addEventListener(type, listener);
@@ -134,20 +134,7 @@ export class Options {
134
134
  mode: paletteData.blendMode,
135
135
  },
136
136
  particles: {
137
- fill: {
138
- color: paletteData.fill
139
- ? {
140
- value: paletteData.colors,
141
- }
142
- : undefined,
143
- enable: paletteData.fill,
144
- },
145
- stroke: !paletteData.fill
146
- ? paletteData.colors.map(color => ({
147
- color: { value: color },
148
- width: 1,
149
- }))
150
- : undefined,
137
+ palette,
151
138
  },
152
139
  });
153
140
  };
@@ -18,6 +18,7 @@ export class ParticlesOptions {
18
18
  move;
19
19
  number;
20
20
  opacity;
21
+ palette;
21
22
  reduceDuplicates;
22
23
  shape;
23
24
  size;
@@ -45,6 +46,10 @@ export class ParticlesOptions {
45
46
  if (isNull(data)) {
46
47
  return;
47
48
  }
49
+ if (data.palette) {
50
+ this.palette = data.palette;
51
+ this._importPalette(this.palette);
52
+ }
48
53
  if (data.groups !== undefined) {
49
54
  for (const group of Object.keys(data.groups)) {
50
55
  if (!(group in data.groups)) {
@@ -99,4 +104,30 @@ export class ParticlesOptions {
99
104
  }
100
105
  }
101
106
  }
107
+ _importPalette = (palette) => {
108
+ const paletteData = this._pluginManager.getPalette(palette);
109
+ if (!paletteData) {
110
+ return;
111
+ }
112
+ this.load({
113
+ fill: {
114
+ color: paletteData.fill
115
+ ? {
116
+ value: paletteData.colors,
117
+ }
118
+ : undefined,
119
+ enable: paletteData.fill,
120
+ },
121
+ stroke: paletteData.fill
122
+ ? undefined
123
+ : paletteData.colors.map(color => ({
124
+ color: { value: color },
125
+ width: 1,
126
+ })),
127
+ blend: {
128
+ enable: true,
129
+ mode: paletteData.blendMode,
130
+ },
131
+ });
132
+ };
102
133
  }
@@ -326,6 +326,19 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
326
326
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
327
327
  return;
328
328
  }
329
+ switch (data.status) {
330
+ case AnimationStatus.increasing:
331
+ data.value += velocity;
332
+ break;
333
+ case AnimationStatus.decreasing:
334
+ data.value -= velocity;
335
+ break;
336
+ default:
337
+ break;
338
+ }
339
+ if (data.velocity && decay !== identity) {
340
+ data.velocity *= decay;
341
+ }
329
342
  switch (data.status) {
330
343
  case AnimationStatus.increasing:
331
344
  if (data.value >= maxValue) {
@@ -338,9 +351,6 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
338
351
  data.loops ??= minLoops;
339
352
  data.loops++;
340
353
  }
341
- else {
342
- data.value += velocity;
343
- }
344
354
  break;
345
355
  case AnimationStatus.decreasing:
346
356
  if (data.value <= minValue) {
@@ -353,18 +363,14 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
353
363
  data.loops ??= minLoops;
354
364
  data.loops++;
355
365
  }
356
- else {
357
- data.value -= velocity;
358
- }
359
366
  break;
360
367
  default:
361
368
  break;
362
369
  }
363
- if (data.velocity && decay !== identity) {
364
- data.velocity *= decay;
365
- }
366
370
  checkDestroy(particle, destroyType, data.value, minValue, maxValue);
367
- data.value = clamp(data.value, minValue, maxValue);
371
+ if (!particle.destroyed) {
372
+ data.value = clamp(data.value, minValue, maxValue);
373
+ }
368
374
  }
369
375
  export function cloneStyle(style) {
370
376
  const clonedStyle = safeDocument().createElement("div").style;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/engine",
3
- "version": "4.0.0-beta.6",
3
+ "version": "4.0.0-beta.8",
4
4
  "description": "Easily create highly customizable particle, confetti and fireworks animations and use them as animated backgrounds for your website. Ready to use components available also for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Riot.js, Inferno.",
5
5
  "homepage": "https://particles.js.org",
6
6
  "scripts": {
package/report.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>@tsparticles/engine [2 Apr 2026 at 15:13]</title>
6
+ <title>@tsparticles/engine [7 Apr 2026 at 13:11]</title>
7
7
  <link
8
8
  rel="shortcut icon"
9
9
  href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII="