@tsparticles/updater-destroy 4.0.0-beta.11 → 4.0.0-beta.12

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.
package/310.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_updater_destroy=this.webpackChunk_tsparticles_updater_destroy||[]).push([[310],{310(e,t,o){o.d(t,{DestroyUpdater:()=>c});var i,l,s=o(303);class r{bottom;left;right;top;load(e){(0,s.isNull)(e)||(void 0!==e.bottom&&(this.bottom=(0,s.setRangeValue)(e.bottom)),void 0!==e.left&&(this.left=(0,s.setRangeValue)(e.left)),void 0!==e.right&&(this.right=(0,s.setRangeValue)(e.right)),void 0!==e.top&&(this.top=(0,s.setRangeValue)(e.top)))}}(i=l||(l={})).explode="explode",i.none="none",i.split="split";class a{maxSizeFactor;speed;constructor(){this.maxSizeFactor=3,this.speed=2}load(e){(0,s.isNull)(e)||(void 0!==e.maxSizeFactor&&(this.maxSizeFactor=e.maxSizeFactor),void 0!==e.speed&&(this.speed=e.speed))}}class n extends s.ValueWithRandom{constructor(){super(),this.value=3}}class f extends s.ValueWithRandom{constructor(){super(),this.value={min:4,max:9}}}class d{count;factor;fillColor;fillColorOffset;particles;rate;sizeOffset;strokeColor;strokeColorOffset;constructor(){this.count=1,this.factor=new n,this.rate=new f,this.sizeOffset=!0}load(e){!(0,s.isNull)(e)&&(void 0!==e.fillColor&&(this.fillColor=s.OptionsColor.create(this.fillColor,e.fillColor)),void 0!==e.strokeColor&&(this.strokeColor=s.OptionsColor.create(this.strokeColor,e.strokeColor)),void 0!==e.count&&(this.count=e.count),this.factor.load(e.factor),this.rate.load(e.rate),this.particles=(0,s.executeOnSingleOrMultiple)(e.particles,e=>(0,s.deepExtend)({},e)),void 0!==e.sizeOffset&&(this.sizeOffset=e.sizeOffset),e.fillColorOffset&&(this.fillColorOffset=this.fillColorOffset??{},void 0!==e.fillColorOffset.h&&(this.fillColorOffset.h=e.fillColorOffset.h),void 0!==e.fillColorOffset.s&&(this.fillColorOffset.s=e.fillColorOffset.s),void 0!==e.fillColorOffset.l&&(this.fillColorOffset.l=e.fillColorOffset.l)),e.strokeColorOffset&&(this.strokeColorOffset=this.strokeColorOffset??{},void 0!==e.strokeColorOffset.h&&(this.strokeColorOffset.h=e.strokeColorOffset.h),void 0!==e.strokeColorOffset.s&&(this.strokeColorOffset.s=e.strokeColorOffset.s),void 0!==e.strokeColorOffset.l&&(this.strokeColorOffset.l=e.strokeColorOffset.l)))}}class p{bounds;explode;mode;split;constructor(){this.bounds=new r,this.explode=new a,this.mode=l.none,this.split=new d}load(e){(0,s.isNull)(e)||(e.mode&&(this.mode=e.mode),e.bounds&&this.bounds.load(e.bounds),this.explode.load(e.explode),this.split.load(e.split))}}function u(e,t,o,i){if(e&&i){let t,o,l,r,a,n;return t=(0,s.getRangeValue)(e.h??0),o=(0,s.getRangeValue)(e.s??0),l=(0,s.getRangeValue)(e.l??0),r=(i.h+t)%360,a=Math.max(0,Math.min(100,i.s+o)),n=Math.max(0,Math.min(100,i.l+l)),s.AnimatableColor.create(void 0,{value:{hsl:{h:r<0?r+360:r,s:a,l:n}}})}return t?s.AnimatableColor.create(void 0,t):o?s.AnimatableColor.create(void 0,o):i?s.AnimatableColor.create(void 0,{value:{hsl:i}}):void 0}class c{_container;_pluginManager;constructor(e,t){this._container=t,this._pluginManager=e}init(e){let t=this._container,o=e.options.destroy;if(!o)return;e.exploding=void 0,e.splitCount=0;let i=o.bounds;e.destroyBounds??={};let{bottom:l,left:r,right:a,top:n}=i,{destroyBounds:f}=e,d=t.canvas.size;l&&(f.bottom=(0,s.getRangeValue)(l)*d.height/s.percentDenominator),r&&(f.left=(0,s.getRangeValue)(r)*d.width/s.percentDenominator),a&&(f.right=(0,s.getRangeValue)(a)*d.width/s.percentDenominator),n&&(f.top=(0,s.getRangeValue)(n)*d.height/s.percentDenominator)}isEnabled(e){return!e.destroyed||!!e.exploding}loadOptions(e,...t){for(let o of(e.destroy??=new p,t))e.destroy.load(o?.destroy)}particleDestroyed(e,t){if(t)return;let o=e.options.destroy;switch(o?.mode){case l.split:!function(e,t,o){let i=o.options.destroy;if(!i)return;let l=i.split;if(l.count>=0){if(void 0===o.splitCount||o.splitCount>l.count)return;o.splitCount++}let r=(0,s.getRangeValue)(l.rate.value),a=(0,s.itemFromSingleOrMultiple)(l.particles);for(let i=0;i<r;i++)!function(e,t,o,i){let l=o.options.destroy;if(!l)return;let r=l.split,a=(0,s.loadParticlesOptions)(e,t,o.options),n=(0,s.itemFromSingleOrMultiple)(r.fillColor),f=(0,s.itemFromSingleOrMultiple)(r.strokeColor),d=o.getFillColor(),p=o.getStrokeColor();a.move.load({center:{x:o.position.x,y:o.position.y,mode:s.PixelMode.precise}});let c=s.identity/(0,s.getRangeValue)(r.factor.value);(0,s.isNumber)(a.size.value)?a.size.value*=c:(a.size.value.min*=c,a.size.value.max*=c),a.load(i);let h=(0,s.itemFromSingleOrMultiple)(a.paint),g=h?.fill,O=h?.stroke,m=u(r.fillColorOffset,n,g?.color,d),C=u(r.strokeColorOffset,f,O?.color,p);m&&g&&(g.color=m),C&&O&&(O.color=C);let v=r.sizeOffset?(0,s.setRangeValue)(-o.size.value,o.size.value):0,y={x:o.position.x+(0,s.randomInRangeValue)(v),y:o.position.y+(0,s.randomInRangeValue)(v)};t.particles.addParticle(y,a,o.group,e=>!(e.size.value<.5)&&(e.velocity.length=(0,s.randomInRangeValue)((0,s.setRangeValue)(o.velocity.length,e.velocity.length)),e.splitCount=(o.splitCount??0)+1,e.unbreakable=!0,e.unbreakableUntil=performance.now()+500,!0))}(e,t,o,a)}(this._pluginManager,this._container,e);break;case l.explode:{if(e.exploding){e.destroyed=!1;break}let{explode:t}=o,i=e.size.value,l=i*t.maxSizeFactor,s=e.getOpacity();e.exploding={initialFillOpacity:s.fillOpacity,initialSize:i,initialStrokeOpacity:s.strokeOpacity,maxSize:l,progress:0,speed:Math.max(t.speed,.01)},e.fillOpacity=s.fillOpacity,e.strokeOpacity=s.strokeOpacity,e.destroyed=!1}}}update(e,t){if(e.exploding){let o=e.exploding,i=t.factor||1;o.progress=Math.min(1,o.progress+o.speed*i/60);let l=o.progress;e.size.value=o.initialSize+(o.maxSize-o.initialSize)*l,e.fillOpacity=o.initialFillOpacity*(1-l),e.strokeOpacity=o.initialStrokeOpacity*(1-l),l>=1&&(e.exploding=void 0,e.destroy(!0));return}void 0!==e.unbreakableUntil&&performance.now()>=e.unbreakableUntil&&(e.unbreakable=!1,e.unbreakableUntil=void 0);let o=e.getPosition(),i=e.destroyBounds;i&&(void 0!==i.bottom&&o.y>=i.bottom||void 0!==i.left&&o.x<=i.left||void 0!==i.right&&o.x>=i.right||void 0!==i.top&&o.y<=i.top)&&e.destroy()}}}}]);
@@ -2,6 +2,7 @@ import { getRangeValue, percentDenominator, } from "@tsparticles/engine";
2
2
  import { Destroy } from "./Options/Classes/Destroy.js";
3
3
  import { DestroyMode } from "./Enums/DestroyMode.js";
4
4
  import { split } from "./Utils.js";
5
+ const defaultDeltaFactor = 1, fpsFactor = 60, minExplodeSpeed = 0.01, maxExplodeProgress = 1;
5
6
  export class DestroyUpdater {
6
7
  _container;
7
8
  _pluginManager;
@@ -14,6 +15,7 @@ export class DestroyUpdater {
14
15
  if (!destroyOptions) {
15
16
  return;
16
17
  }
18
+ particle.exploding = undefined;
17
19
  particle.splitCount = 0;
18
20
  const destroyBoundsOptions = destroyOptions.bounds;
19
21
  particle.destroyBounds ??= {};
@@ -32,7 +34,8 @@ export class DestroyUpdater {
32
34
  }
33
35
  }
34
36
  isEnabled(particle) {
35
- return !particle.destroyed;
37
+ const destroyParticle = particle;
38
+ return !destroyParticle.destroyed || !!destroyParticle.exploding;
36
39
  }
37
40
  loadOptions(options, ...sources) {
38
41
  options.destroy ??= new Destroy();
@@ -45,11 +48,48 @@ export class DestroyUpdater {
45
48
  return;
46
49
  }
47
50
  const destroyOptions = particle.options.destroy;
48
- if (destroyOptions?.mode === DestroyMode.split) {
49
- split(this._pluginManager, this._container, particle);
51
+ switch (destroyOptions?.mode) {
52
+ case DestroyMode.split:
53
+ split(this._pluginManager, this._container, particle);
54
+ break;
55
+ case DestroyMode.explode: {
56
+ if (particle.exploding) {
57
+ particle.destroyed = false;
58
+ break;
59
+ }
60
+ const { explode } = destroyOptions, initialSize = particle.size.value, maxSize = initialSize * explode.maxSizeFactor, opacity = particle.getOpacity();
61
+ particle.exploding = {
62
+ initialFillOpacity: opacity.fillOpacity,
63
+ initialSize,
64
+ initialStrokeOpacity: opacity.strokeOpacity,
65
+ maxSize,
66
+ progress: 0,
67
+ speed: Math.max(explode.speed, minExplodeSpeed),
68
+ };
69
+ particle.fillOpacity = opacity.fillOpacity;
70
+ particle.strokeOpacity = opacity.strokeOpacity;
71
+ particle.destroyed = false;
72
+ break;
73
+ }
74
+ default:
75
+ break;
50
76
  }
51
77
  }
52
- update(particle) {
78
+ update(particle, delta) {
79
+ if (particle.exploding) {
80
+ const explosionState = particle.exploding, deltaFactor = delta.factor || defaultDeltaFactor;
81
+ explosionState.progress = Math.min(maxExplodeProgress, explosionState.progress + (explosionState.speed * deltaFactor) / fpsFactor);
82
+ const progress = explosionState.progress;
83
+ particle.size.value =
84
+ explosionState.initialSize + (explosionState.maxSize - explosionState.initialSize) * progress;
85
+ particle.fillOpacity = explosionState.initialFillOpacity * (maxExplodeProgress - progress);
86
+ particle.strokeOpacity = explosionState.initialStrokeOpacity * (maxExplodeProgress - progress);
87
+ if (progress >= maxExplodeProgress) {
88
+ particle.exploding = undefined;
89
+ particle.destroy(true);
90
+ }
91
+ return;
92
+ }
53
93
  if (particle.unbreakableUntil !== undefined && performance.now() >= particle.unbreakableUntil) {
54
94
  particle.unbreakable = false;
55
95
  particle.unbreakableUntil = undefined;
@@ -1,5 +1,6 @@
1
1
  export var DestroyMode;
2
2
  (function (DestroyMode) {
3
+ DestroyMode["explode"] = "explode";
3
4
  DestroyMode["none"] = "none";
4
5
  DestroyMode["split"] = "split";
5
6
  })(DestroyMode || (DestroyMode = {}));
@@ -1,13 +1,16 @@
1
1
  import { isNull } from "@tsparticles/engine";
2
2
  import { DestroyBounds } from "./DestroyBounds.js";
3
3
  import { DestroyMode } from "../../Enums/DestroyMode.js";
4
+ import { Explode } from "./Explode.js";
4
5
  import { Split } from "./Split.js";
5
6
  export class Destroy {
6
7
  bounds;
8
+ explode;
7
9
  mode;
8
10
  split;
9
11
  constructor() {
10
12
  this.bounds = new DestroyBounds();
13
+ this.explode = new Explode();
11
14
  this.mode = DestroyMode.none;
12
15
  this.split = new Split();
13
16
  }
@@ -21,6 +24,7 @@ export class Destroy {
21
24
  if (data.bounds) {
22
25
  this.bounds.load(data.bounds);
23
26
  }
27
+ this.explode.load(data.explode);
24
28
  this.split.load(data.split);
25
29
  }
26
30
  }
@@ -0,0 +1,20 @@
1
+ import { isNull } from "@tsparticles/engine";
2
+ export class Explode {
3
+ maxSizeFactor;
4
+ speed;
5
+ constructor() {
6
+ this.maxSizeFactor = 3;
7
+ this.speed = 2;
8
+ }
9
+ load(data) {
10
+ if (isNull(data)) {
11
+ return;
12
+ }
13
+ if (data.maxSizeFactor !== undefined) {
14
+ this.maxSizeFactor = data.maxSizeFactor;
15
+ }
16
+ if (data.speed !== undefined) {
17
+ this.speed = data.speed;
18
+ }
19
+ }
20
+ }
@@ -0,0 +1 @@
1
+ export {};
package/browser/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadDestroyUpdater(engine) {
2
- engine.checkVersion("4.0.0-beta.11");
2
+ engine.checkVersion("4.0.0-beta.12");
3
3
  await engine.pluginManager.register(e => {
4
4
  e.pluginManager.addParticleUpdater("destroy", async (container) => {
5
5
  const { DestroyUpdater } = await import("./DestroyUpdater.js");
@@ -2,6 +2,7 @@ import { getRangeValue, percentDenominator, } from "@tsparticles/engine";
2
2
  import { Destroy } from "./Options/Classes/Destroy.js";
3
3
  import { DestroyMode } from "./Enums/DestroyMode.js";
4
4
  import { split } from "./Utils.js";
5
+ const defaultDeltaFactor = 1, fpsFactor = 60, minExplodeSpeed = 0.01, maxExplodeProgress = 1;
5
6
  export class DestroyUpdater {
6
7
  _container;
7
8
  _pluginManager;
@@ -14,6 +15,7 @@ export class DestroyUpdater {
14
15
  if (!destroyOptions) {
15
16
  return;
16
17
  }
18
+ particle.exploding = undefined;
17
19
  particle.splitCount = 0;
18
20
  const destroyBoundsOptions = destroyOptions.bounds;
19
21
  particle.destroyBounds ??= {};
@@ -32,7 +34,8 @@ export class DestroyUpdater {
32
34
  }
33
35
  }
34
36
  isEnabled(particle) {
35
- return !particle.destroyed;
37
+ const destroyParticle = particle;
38
+ return !destroyParticle.destroyed || !!destroyParticle.exploding;
36
39
  }
37
40
  loadOptions(options, ...sources) {
38
41
  options.destroy ??= new Destroy();
@@ -45,11 +48,48 @@ export class DestroyUpdater {
45
48
  return;
46
49
  }
47
50
  const destroyOptions = particle.options.destroy;
48
- if (destroyOptions?.mode === DestroyMode.split) {
49
- split(this._pluginManager, this._container, particle);
51
+ switch (destroyOptions?.mode) {
52
+ case DestroyMode.split:
53
+ split(this._pluginManager, this._container, particle);
54
+ break;
55
+ case DestroyMode.explode: {
56
+ if (particle.exploding) {
57
+ particle.destroyed = false;
58
+ break;
59
+ }
60
+ const { explode } = destroyOptions, initialSize = particle.size.value, maxSize = initialSize * explode.maxSizeFactor, opacity = particle.getOpacity();
61
+ particle.exploding = {
62
+ initialFillOpacity: opacity.fillOpacity,
63
+ initialSize,
64
+ initialStrokeOpacity: opacity.strokeOpacity,
65
+ maxSize,
66
+ progress: 0,
67
+ speed: Math.max(explode.speed, minExplodeSpeed),
68
+ };
69
+ particle.fillOpacity = opacity.fillOpacity;
70
+ particle.strokeOpacity = opacity.strokeOpacity;
71
+ particle.destroyed = false;
72
+ break;
73
+ }
74
+ default:
75
+ break;
50
76
  }
51
77
  }
52
- update(particle) {
78
+ update(particle, delta) {
79
+ if (particle.exploding) {
80
+ const explosionState = particle.exploding, deltaFactor = delta.factor || defaultDeltaFactor;
81
+ explosionState.progress = Math.min(maxExplodeProgress, explosionState.progress + (explosionState.speed * deltaFactor) / fpsFactor);
82
+ const progress = explosionState.progress;
83
+ particle.size.value =
84
+ explosionState.initialSize + (explosionState.maxSize - explosionState.initialSize) * progress;
85
+ particle.fillOpacity = explosionState.initialFillOpacity * (maxExplodeProgress - progress);
86
+ particle.strokeOpacity = explosionState.initialStrokeOpacity * (maxExplodeProgress - progress);
87
+ if (progress >= maxExplodeProgress) {
88
+ particle.exploding = undefined;
89
+ particle.destroy(true);
90
+ }
91
+ return;
92
+ }
53
93
  if (particle.unbreakableUntil !== undefined && performance.now() >= particle.unbreakableUntil) {
54
94
  particle.unbreakable = false;
55
95
  particle.unbreakableUntil = undefined;
@@ -1,5 +1,6 @@
1
1
  export var DestroyMode;
2
2
  (function (DestroyMode) {
3
+ DestroyMode["explode"] = "explode";
3
4
  DestroyMode["none"] = "none";
4
5
  DestroyMode["split"] = "split";
5
6
  })(DestroyMode || (DestroyMode = {}));
@@ -1,13 +1,16 @@
1
1
  import { isNull } from "@tsparticles/engine";
2
2
  import { DestroyBounds } from "./DestroyBounds.js";
3
3
  import { DestroyMode } from "../../Enums/DestroyMode.js";
4
+ import { Explode } from "./Explode.js";
4
5
  import { Split } from "./Split.js";
5
6
  export class Destroy {
6
7
  bounds;
8
+ explode;
7
9
  mode;
8
10
  split;
9
11
  constructor() {
10
12
  this.bounds = new DestroyBounds();
13
+ this.explode = new Explode();
11
14
  this.mode = DestroyMode.none;
12
15
  this.split = new Split();
13
16
  }
@@ -21,6 +24,7 @@ export class Destroy {
21
24
  if (data.bounds) {
22
25
  this.bounds.load(data.bounds);
23
26
  }
27
+ this.explode.load(data.explode);
24
28
  this.split.load(data.split);
25
29
  }
26
30
  }
@@ -0,0 +1,20 @@
1
+ import { isNull } from "@tsparticles/engine";
2
+ export class Explode {
3
+ maxSizeFactor;
4
+ speed;
5
+ constructor() {
6
+ this.maxSizeFactor = 3;
7
+ this.speed = 2;
8
+ }
9
+ load(data) {
10
+ if (isNull(data)) {
11
+ return;
12
+ }
13
+ if (data.maxSizeFactor !== undefined) {
14
+ this.maxSizeFactor = data.maxSizeFactor;
15
+ }
16
+ if (data.speed !== undefined) {
17
+ this.speed = data.speed;
18
+ }
19
+ }
20
+ }
@@ -0,0 +1 @@
1
+ export {};
package/cjs/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadDestroyUpdater(engine) {
2
- engine.checkVersion("4.0.0-beta.11");
2
+ engine.checkVersion("4.0.0-beta.12");
3
3
  await engine.pluginManager.register(e => {
4
4
  e.pluginManager.addParticleUpdater("destroy", async (container) => {
5
5
  const { DestroyUpdater } = await import("./DestroyUpdater.js");
@@ -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
- * v4.0.0-beta.11
7
+ * v4.0.0-beta.12
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \****************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DestroyUpdater: () => (/* binding */ DestroyUpdater)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Destroy_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Destroy.js */ \"./dist/browser/Options/Classes/Destroy.js\");\n/* harmony import */ var _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Enums/DestroyMode.js */ \"./dist/browser/Enums/DestroyMode.js\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\n\n\nclass DestroyUpdater {\n _container;\n _pluginManager;\n constructor(pluginManager, container){\n this._container = container;\n this._pluginManager = pluginManager;\n }\n init(particle) {\n const container = this._container, particlesOptions = particle.options, destroyOptions = particlesOptions.destroy;\n if (!destroyOptions) {\n return;\n }\n particle.splitCount = 0;\n const destroyBoundsOptions = destroyOptions.bounds;\n particle.destroyBounds ??= {};\n const { bottom, left, right, top } = destroyBoundsOptions, { destroyBounds } = particle, canvasSize = container.canvas.size;\n if (bottom) {\n destroyBounds.bottom = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(bottom) * canvasSize.height / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (left) {\n destroyBounds.left = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(left) * canvasSize.width / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (right) {\n destroyBounds.right = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(right) * canvasSize.width / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (top) {\n destroyBounds.top = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(top) * canvasSize.height / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n }\n isEnabled(particle) {\n return !particle.destroyed;\n }\n loadOptions(options, ...sources) {\n options.destroy ??= new _Options_Classes_Destroy_js__WEBPACK_IMPORTED_MODULE_1__.Destroy();\n for (const source of sources){\n options.destroy.load(source?.destroy);\n }\n }\n particleDestroyed(particle, override) {\n if (override) {\n return;\n }\n const destroyOptions = particle.options.destroy;\n if (destroyOptions?.mode === _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__.DestroyMode.split) {\n (0,_Utils_js__WEBPACK_IMPORTED_MODULE_3__.split)(this._pluginManager, this._container, particle);\n }\n }\n update(particle) {\n if (particle.unbreakableUntil !== undefined && performance.now() >= particle.unbreakableUntil) {\n particle.unbreakable = false;\n particle.unbreakableUntil = undefined;\n }\n const position = particle.getPosition(), bounds = particle.destroyBounds;\n if (!bounds) {\n return;\n }\n if (bounds.bottom !== undefined && position.y >= bounds.bottom || bounds.left !== undefined && position.x <= bounds.left || bounds.right !== undefined && position.x >= bounds.right || bounds.top !== undefined && position.y <= bounds.top) {\n particle.destroy();\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/DestroyUpdater.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DestroyUpdater: () => (/* binding */ DestroyUpdater)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Destroy_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Destroy.js */ \"./dist/browser/Options/Classes/Destroy.js\");\n/* harmony import */ var _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Enums/DestroyMode.js */ \"./dist/browser/Enums/DestroyMode.js\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\n\n\nconst defaultDeltaFactor = 1, fpsFactor = 60, minExplodeSpeed = 0.01, maxExplodeProgress = 1;\nclass DestroyUpdater {\n _container;\n _pluginManager;\n constructor(pluginManager, container){\n this._container = container;\n this._pluginManager = pluginManager;\n }\n init(particle) {\n const container = this._container, particlesOptions = particle.options, destroyOptions = particlesOptions.destroy;\n if (!destroyOptions) {\n return;\n }\n particle.exploding = undefined;\n particle.splitCount = 0;\n const destroyBoundsOptions = destroyOptions.bounds;\n particle.destroyBounds ??= {};\n const { bottom, left, right, top } = destroyBoundsOptions, { destroyBounds } = particle, canvasSize = container.canvas.size;\n if (bottom) {\n destroyBounds.bottom = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(bottom) * canvasSize.height / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (left) {\n destroyBounds.left = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(left) * canvasSize.width / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (right) {\n destroyBounds.right = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(right) * canvasSize.width / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n if (top) {\n destroyBounds.top = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(top) * canvasSize.height / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator;\n }\n }\n isEnabled(particle) {\n const destroyParticle = particle;\n return !destroyParticle.destroyed || !!destroyParticle.exploding;\n }\n loadOptions(options, ...sources) {\n options.destroy ??= new _Options_Classes_Destroy_js__WEBPACK_IMPORTED_MODULE_1__.Destroy();\n for (const source of sources){\n options.destroy.load(source?.destroy);\n }\n }\n particleDestroyed(particle, override) {\n if (override) {\n return;\n }\n const destroyOptions = particle.options.destroy;\n switch(destroyOptions?.mode){\n case _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__.DestroyMode.split:\n (0,_Utils_js__WEBPACK_IMPORTED_MODULE_3__.split)(this._pluginManager, this._container, particle);\n break;\n case _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__.DestroyMode.explode:\n {\n if (particle.exploding) {\n particle.destroyed = false;\n break;\n }\n const { explode } = destroyOptions, initialSize = particle.size.value, maxSize = initialSize * explode.maxSizeFactor, opacity = particle.getOpacity();\n particle.exploding = {\n initialFillOpacity: opacity.fillOpacity,\n initialSize,\n initialStrokeOpacity: opacity.strokeOpacity,\n maxSize,\n progress: 0,\n speed: Math.max(explode.speed, minExplodeSpeed)\n };\n particle.fillOpacity = opacity.fillOpacity;\n particle.strokeOpacity = opacity.strokeOpacity;\n particle.destroyed = false;\n break;\n }\n default:\n break;\n }\n }\n update(particle, delta) {\n if (particle.exploding) {\n const explosionState = particle.exploding, deltaFactor = delta.factor || defaultDeltaFactor;\n explosionState.progress = Math.min(maxExplodeProgress, explosionState.progress + explosionState.speed * deltaFactor / fpsFactor);\n const progress = explosionState.progress;\n particle.size.value = explosionState.initialSize + (explosionState.maxSize - explosionState.initialSize) * progress;\n particle.fillOpacity = explosionState.initialFillOpacity * (maxExplodeProgress - progress);\n particle.strokeOpacity = explosionState.initialStrokeOpacity * (maxExplodeProgress - progress);\n if (progress >= maxExplodeProgress) {\n particle.exploding = undefined;\n particle.destroy(true);\n }\n return;\n }\n if (particle.unbreakableUntil !== undefined && performance.now() >= particle.unbreakableUntil) {\n particle.unbreakable = false;\n particle.unbreakableUntil = undefined;\n }\n const position = particle.getPosition(), bounds = particle.destroyBounds;\n if (!bounds) {\n return;\n }\n if (bounds.bottom !== undefined && position.y >= bounds.bottom || bounds.left !== undefined && position.x <= bounds.left || bounds.right !== undefined && position.x >= bounds.right || bounds.top !== undefined && position.y <= bounds.top) {\n particle.destroy();\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/DestroyUpdater.js?\n}");
27
27
 
28
28
  /***/ },
29
29
 
@@ -33,7 +33,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
33
33
  \*******************************************/
34
34
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
35
 
36
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DestroyMode: () => (/* binding */ DestroyMode)\n/* harmony export */ });\nvar DestroyMode;\n(function(DestroyMode) {\n DestroyMode[\"none\"] = \"none\";\n DestroyMode[\"split\"] = \"split\";\n})(DestroyMode || (DestroyMode = {}));\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/Enums/DestroyMode.js?\n}");
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DestroyMode: () => (/* binding */ DestroyMode)\n/* harmony export */ });\nvar DestroyMode;\n(function(DestroyMode) {\n DestroyMode[\"explode\"] = \"explode\";\n DestroyMode[\"none\"] = \"none\";\n DestroyMode[\"split\"] = \"split\";\n})(DestroyMode || (DestroyMode = {}));\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/Enums/DestroyMode.js?\n}");
37
37
 
38
38
  /***/ },
39
39
 
@@ -43,7 +43,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
43
43
  \*************************************************/
44
44
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
45
45
 
46
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Destroy: () => (/* binding */ Destroy)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _DestroyBounds_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./DestroyBounds.js */ \"./dist/browser/Options/Classes/DestroyBounds.js\");\n/* harmony import */ var _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Enums/DestroyMode.js */ \"./dist/browser/Enums/DestroyMode.js\");\n/* harmony import */ var _Split_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Split.js */ \"./dist/browser/Options/Classes/Split.js\");\n\n\n\n\nclass Destroy {\n bounds;\n mode;\n split;\n constructor(){\n this.bounds = new _DestroyBounds_js__WEBPACK_IMPORTED_MODULE_1__.DestroyBounds();\n this.mode = _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__.DestroyMode.none;\n this.split = new _Split_js__WEBPACK_IMPORTED_MODULE_3__.Split();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.mode) {\n this.mode = data.mode;\n }\n if (data.bounds) {\n this.bounds.load(data.bounds);\n }\n this.split.load(data.split);\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/Options/Classes/Destroy.js?\n}");
46
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Destroy: () => (/* binding */ Destroy)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _DestroyBounds_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./DestroyBounds.js */ \"./dist/browser/Options/Classes/DestroyBounds.js\");\n/* harmony import */ var _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Enums/DestroyMode.js */ \"./dist/browser/Enums/DestroyMode.js\");\n/* harmony import */ var _Explode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Explode.js */ \"./dist/browser/Options/Classes/Explode.js\");\n/* harmony import */ var _Split_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Split.js */ \"./dist/browser/Options/Classes/Split.js\");\n\n\n\n\n\nclass Destroy {\n bounds;\n explode;\n mode;\n split;\n constructor(){\n this.bounds = new _DestroyBounds_js__WEBPACK_IMPORTED_MODULE_1__.DestroyBounds();\n this.explode = new _Explode_js__WEBPACK_IMPORTED_MODULE_3__.Explode();\n this.mode = _Enums_DestroyMode_js__WEBPACK_IMPORTED_MODULE_2__.DestroyMode.none;\n this.split = new _Split_js__WEBPACK_IMPORTED_MODULE_4__.Split();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.mode) {\n this.mode = data.mode;\n }\n if (data.bounds) {\n this.bounds.load(data.bounds);\n }\n this.explode.load(data.explode);\n this.split.load(data.split);\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/Options/Classes/Destroy.js?\n}");
47
47
 
48
48
  /***/ },
49
49
 
@@ -57,6 +57,16 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
57
57
 
58
58
  /***/ },
59
59
 
60
+ /***/ "./dist/browser/Options/Classes/Explode.js"
61
+ /*!*************************************************!*\
62
+ !*** ./dist/browser/Options/Classes/Explode.js ***!
63
+ \*************************************************/
64
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
65
+
66
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Explode: () => (/* binding */ Explode)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass Explode {\n maxSizeFactor;\n speed;\n constructor(){\n this.maxSizeFactor = 3;\n this.speed = 2;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.maxSizeFactor !== undefined) {\n this.maxSizeFactor = data.maxSizeFactor;\n }\n if (data.speed !== undefined) {\n this.speed = data.speed;\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/Options/Classes/Explode.js?\n}");
67
+
68
+ /***/ },
69
+
60
70
  /***/ "./dist/browser/Options/Classes/Split.js"
61
71
  /*!***********************************************!*\
62
72
  !*** ./dist/browser/Options/Classes/Split.js ***!
@@ -2,6 +2,7 @@ import { getRangeValue, percentDenominator, } from "@tsparticles/engine";
2
2
  import { Destroy } from "./Options/Classes/Destroy.js";
3
3
  import { DestroyMode } from "./Enums/DestroyMode.js";
4
4
  import { split } from "./Utils.js";
5
+ const defaultDeltaFactor = 1, fpsFactor = 60, minExplodeSpeed = 0.01, maxExplodeProgress = 1;
5
6
  export class DestroyUpdater {
6
7
  _container;
7
8
  _pluginManager;
@@ -14,6 +15,7 @@ export class DestroyUpdater {
14
15
  if (!destroyOptions) {
15
16
  return;
16
17
  }
18
+ particle.exploding = undefined;
17
19
  particle.splitCount = 0;
18
20
  const destroyBoundsOptions = destroyOptions.bounds;
19
21
  particle.destroyBounds ??= {};
@@ -32,7 +34,8 @@ export class DestroyUpdater {
32
34
  }
33
35
  }
34
36
  isEnabled(particle) {
35
- return !particle.destroyed;
37
+ const destroyParticle = particle;
38
+ return !destroyParticle.destroyed || !!destroyParticle.exploding;
36
39
  }
37
40
  loadOptions(options, ...sources) {
38
41
  options.destroy ??= new Destroy();
@@ -45,11 +48,48 @@ export class DestroyUpdater {
45
48
  return;
46
49
  }
47
50
  const destroyOptions = particle.options.destroy;
48
- if (destroyOptions?.mode === DestroyMode.split) {
49
- split(this._pluginManager, this._container, particle);
51
+ switch (destroyOptions?.mode) {
52
+ case DestroyMode.split:
53
+ split(this._pluginManager, this._container, particle);
54
+ break;
55
+ case DestroyMode.explode: {
56
+ if (particle.exploding) {
57
+ particle.destroyed = false;
58
+ break;
59
+ }
60
+ const { explode } = destroyOptions, initialSize = particle.size.value, maxSize = initialSize * explode.maxSizeFactor, opacity = particle.getOpacity();
61
+ particle.exploding = {
62
+ initialFillOpacity: opacity.fillOpacity,
63
+ initialSize,
64
+ initialStrokeOpacity: opacity.strokeOpacity,
65
+ maxSize,
66
+ progress: 0,
67
+ speed: Math.max(explode.speed, minExplodeSpeed),
68
+ };
69
+ particle.fillOpacity = opacity.fillOpacity;
70
+ particle.strokeOpacity = opacity.strokeOpacity;
71
+ particle.destroyed = false;
72
+ break;
73
+ }
74
+ default:
75
+ break;
50
76
  }
51
77
  }
52
- update(particle) {
78
+ update(particle, delta) {
79
+ if (particle.exploding) {
80
+ const explosionState = particle.exploding, deltaFactor = delta.factor || defaultDeltaFactor;
81
+ explosionState.progress = Math.min(maxExplodeProgress, explosionState.progress + (explosionState.speed * deltaFactor) / fpsFactor);
82
+ const progress = explosionState.progress;
83
+ particle.size.value =
84
+ explosionState.initialSize + (explosionState.maxSize - explosionState.initialSize) * progress;
85
+ particle.fillOpacity = explosionState.initialFillOpacity * (maxExplodeProgress - progress);
86
+ particle.strokeOpacity = explosionState.initialStrokeOpacity * (maxExplodeProgress - progress);
87
+ if (progress >= maxExplodeProgress) {
88
+ particle.exploding = undefined;
89
+ particle.destroy(true);
90
+ }
91
+ return;
92
+ }
53
93
  if (particle.unbreakableUntil !== undefined && performance.now() >= particle.unbreakableUntil) {
54
94
  particle.unbreakable = false;
55
95
  particle.unbreakableUntil = undefined;
@@ -1,5 +1,6 @@
1
1
  export var DestroyMode;
2
2
  (function (DestroyMode) {
3
+ DestroyMode["explode"] = "explode";
3
4
  DestroyMode["none"] = "none";
4
5
  DestroyMode["split"] = "split";
5
6
  })(DestroyMode || (DestroyMode = {}));
@@ -1,13 +1,16 @@
1
1
  import { isNull } from "@tsparticles/engine";
2
2
  import { DestroyBounds } from "./DestroyBounds.js";
3
3
  import { DestroyMode } from "../../Enums/DestroyMode.js";
4
+ import { Explode } from "./Explode.js";
4
5
  import { Split } from "./Split.js";
5
6
  export class Destroy {
6
7
  bounds;
8
+ explode;
7
9
  mode;
8
10
  split;
9
11
  constructor() {
10
12
  this.bounds = new DestroyBounds();
13
+ this.explode = new Explode();
11
14
  this.mode = DestroyMode.none;
12
15
  this.split = new Split();
13
16
  }
@@ -21,6 +24,7 @@ export class Destroy {
21
24
  if (data.bounds) {
22
25
  this.bounds.load(data.bounds);
23
26
  }
27
+ this.explode.load(data.explode);
24
28
  this.split.load(data.split);
25
29
  }
26
30
  }
@@ -0,0 +1,20 @@
1
+ import { isNull } from "@tsparticles/engine";
2
+ export class Explode {
3
+ maxSizeFactor;
4
+ speed;
5
+ constructor() {
6
+ this.maxSizeFactor = 3;
7
+ this.speed = 2;
8
+ }
9
+ load(data) {
10
+ if (isNull(data)) {
11
+ return;
12
+ }
13
+ if (data.maxSizeFactor !== undefined) {
14
+ this.maxSizeFactor = data.maxSizeFactor;
15
+ }
16
+ if (data.speed !== undefined) {
17
+ this.speed = data.speed;
18
+ }
19
+ }
20
+ }
@@ -0,0 +1 @@
1
+ export {};
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadDestroyUpdater(engine) {
2
- engine.checkVersion("4.0.0-beta.11");
2
+ engine.checkVersion("4.0.0-beta.12");
3
3
  await engine.pluginManager.register(e => {
4
4
  e.pluginManager.addParticleUpdater("destroy", async (container) => {
5
5
  const { DestroyUpdater } = await import("./DestroyUpdater.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/updater-destroy",
3
- "version": "4.0.0-beta.11",
3
+ "version": "4.0.0-beta.12",
4
4
  "description": "tsParticles particles destroy updater",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "./package.json": "./package.json"
87
87
  },
88
88
  "peerDependencies": {
89
- "@tsparticles/engine": "4.0.0-beta.11"
89
+ "@tsparticles/engine": "4.0.0-beta.12"
90
90
  },
91
91
  "publishConfig": {
92
92
  "access": "public"
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/updater-destroy [8 Apr 2026 at 17:11]</title>
6
+ <title>@tsparticles/updater-destroy [15 Apr 2026 at 17:02]</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="
@@ -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
- * v4.0.0-beta.11
7
+ * v4.0.0-beta.12
8
8
  */
9
9
  /*
10
10
  * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
@@ -44,7 +44,7 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
44
44
  \*******************************/
45
45
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
46
46
 
47
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadDestroyUpdater: () => (/* binding */ loadDestroyUpdater)\n/* harmony export */ });\nasync function loadDestroyUpdater(engine) {\n engine.checkVersion(\"4.0.0-beta.11\");\n await engine.pluginManager.register((e)=>{\n e.pluginManager.addParticleUpdater(\"destroy\", async (container)=>{\n const { DestroyUpdater } = await __webpack_require__.e(/*! import() */ \"dist_browser_DestroyUpdater_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./DestroyUpdater.js */ \"./dist/browser/DestroyUpdater.js\"));\n return new DestroyUpdater(e.pluginManager, container);\n });\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/index.js?\n}");
47
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadDestroyUpdater: () => (/* binding */ loadDestroyUpdater)\n/* harmony export */ });\nasync function loadDestroyUpdater(engine) {\n engine.checkVersion(\"4.0.0-beta.12\");\n await engine.pluginManager.register((e)=>{\n e.pluginManager.addParticleUpdater(\"destroy\", async (container)=>{\n const { DestroyUpdater } = await __webpack_require__.e(/*! import() */ \"dist_browser_DestroyUpdater_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./DestroyUpdater.js */ \"./dist/browser/DestroyUpdater.js\"));\n return new DestroyUpdater(e.pluginManager, container);\n });\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/updater-destroy/./dist/browser/index.js?\n}");
48
48
 
49
49
  /***/ }
50
50
 
@@ -1,2 +1,2 @@
1
1
  !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine")):t(e.window);for(var o in r)("object"==typeof exports?exports:e)[o]=r[o]}}(this,e=>(()=>{"use strict";var t,r,o,n={303(t){t.exports=e}},i={};function a(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return n[e](r,r.exports,a),r.exports}a.m=n,a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce((t,r)=>(a.f[r](e,t),t),[])),a.u=e=>""+e+".min.js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s={},a.l=(e,t,r,o)=>{if(s[e])return void s[e].push(t);if(void 0!==r)for(var n,i,p=document.getElementsByTagName("script"),c=0;c<p.length;c++){var u=p[c];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")=="@tsparticles/updater-destroy:"+r){n=u;break}}n||(i=!0,(n=document.createElement("script")).charset="utf-8",a.nc&&n.setAttribute("nonce",a.nc),n.setAttribute("data-webpack","@tsparticles/updater-destroy:"+r),n.src=e),s[e]=[t];var l=(t,r)=>{n.onerror=n.onload=null,clearTimeout(d);var o=s[e];if(delete s[e],n.parentNode&&n.parentNode.removeChild(n),o&&o.forEach(e=>e(r)),t)return t(r)},d=setTimeout(l.bind(null,void 0,{type:"timeout",target:n}),12e4);n.onerror=l.bind(null,n.onerror),n.onload=l.bind(null,n.onload),i&&document.head.appendChild(n)},a.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.g.importScripts&&(p=a.g.location+"");var s,p,c=a.g.document;if(!p&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(p=c.currentScript.src),!p)){var u=c.getElementsByTagName("script");if(u.length)for(var l=u.length-1;l>-1&&(!p||!/^http(s?):/.test(p));)p=u[l--].src}if(!p)throw Error("Automatic publicPath is not supported in this browser");a.p=p=p.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),t={114:0},a.f.j=(e,r)=>{var o=a.o(t,e)?t[e]:void 0;if(0!==o)if(o)r.push(o[2]);else{var n=new Promise((r,n)=>o=t[e]=[r,n]);r.push(o[2]=n);var i=a.p+a.u(e),s=Error();a.l(i,r=>{if(a.o(t,e)&&(0!==(o=t[e])&&(t[e]=void 0),o)){var n=r&&("load"===r.type?"missing":r.type),i=r&&r.target&&r.target.src;s.message="Loading chunk "+e+` failed.
2
- (`+n+": "+i+")",s.name="ChunkLoadError",s.type=n,s.request=i,o[1](s)}},"chunk-"+e,e)}},r=(e,r)=>{var o,n,[i,s,p]=r,c=0;if(i.some(e=>0!==t[e])){for(o in s)a.o(s,o)&&(a.m[o]=s[o]);p&&p(a)}for(e&&e(r);c<i.length;c++)n=i[c],a.o(t,n)&&t[n]&&t[n][0](),t[n]=0},(o=this.webpackChunk_tsparticles_updater_destroy=this.webpackChunk_tsparticles_updater_destroy||[]).forEach(r.bind(null,0)),o.push=r.bind(null,o.push.bind(o));var d={};async function f(e){e.checkVersion("4.0.0-beta.11"),await e.pluginManager.register(e=>{e.pluginManager.addParticleUpdater("destroy",async t=>{let{DestroyUpdater:r}=await a.e(960).then(a.bind(a,960));return new r(e.pluginManager,t)})})}return a.r(d),a.d(d,{loadDestroyUpdater:()=>f}),d})());
2
+ (`+n+": "+i+")",s.name="ChunkLoadError",s.type=n,s.request=i,o[1](s)}},"chunk-"+e,e)}},r=(e,r)=>{var o,n,[i,s,p]=r,c=0;if(i.some(e=>0!==t[e])){for(o in s)a.o(s,o)&&(a.m[o]=s[o]);p&&p(a)}for(e&&e(r);c<i.length;c++)n=i[c],a.o(t,n)&&t[n]&&t[n][0](),t[n]=0},(o=this.webpackChunk_tsparticles_updater_destroy=this.webpackChunk_tsparticles_updater_destroy||[]).forEach(r.bind(null,0)),o.push=r.bind(null,o.push.bind(o));var d={};async function f(e){e.checkVersion("4.0.0-beta.12"),await e.pluginManager.register(e=>{e.pluginManager.addParticleUpdater("destroy",async t=>{let{DestroyUpdater:r}=await a.e(310).then(a.bind(a,310));return new r(e.pluginManager,t)})})}return a.r(d),a.d(d,{loadDestroyUpdater:()=>f}),d})());
@@ -1,4 +1,4 @@
1
- import { type Container, type IParticleUpdater, type Particle, type PluginManager, type RecursivePartial } from "@tsparticles/engine";
1
+ import { type Container, type IDelta, type IParticleUpdater, type Particle, type PluginManager, type RecursivePartial } from "@tsparticles/engine";
2
2
  import type { DestroyParticle, DestroyParticlesOptions, IDestroyParticlesOptions } from "./Types.js";
3
3
  export declare class DestroyUpdater implements IParticleUpdater {
4
4
  private readonly _container;
@@ -8,5 +8,5 @@ export declare class DestroyUpdater implements IParticleUpdater {
8
8
  isEnabled(particle: Particle): boolean;
9
9
  loadOptions(options: DestroyParticlesOptions, ...sources: (RecursivePartial<IDestroyParticlesOptions> | undefined)[]): void;
10
10
  particleDestroyed(particle: DestroyParticle, override?: boolean): void;
11
- update(particle: DestroyParticle): void;
11
+ update(particle: DestroyParticle, delta: IDelta): void;
12
12
  }
@@ -1,4 +1,5 @@
1
1
  export declare enum DestroyMode {
2
+ explode = "explode",
2
3
  none = "none",
3
4
  split = "split"
4
5
  }
@@ -1,10 +1,12 @@
1
1
  import { type IOptionLoader, type RecursivePartial } from "@tsparticles/engine";
2
2
  import { DestroyBounds } from "./DestroyBounds.js";
3
3
  import { DestroyMode } from "../../Enums/DestroyMode.js";
4
+ import { Explode } from "./Explode.js";
4
5
  import type { IDestroy } from "../Interfaces/IDestroy.js";
5
6
  import { Split } from "./Split.js";
6
7
  export declare class Destroy implements IDestroy, IOptionLoader<IDestroy> {
7
8
  bounds: DestroyBounds;
9
+ explode: Explode;
8
10
  mode: DestroyMode | keyof typeof DestroyMode;
9
11
  split: Split;
10
12
  constructor();
@@ -0,0 +1,8 @@
1
+ import { type IOptionLoader, type RecursivePartial } from "@tsparticles/engine";
2
+ import type { IExplode } from "../Interfaces/IExplode.js";
3
+ export declare class Explode implements IExplode, IOptionLoader<IExplode> {
4
+ maxSizeFactor: number;
5
+ speed: number;
6
+ constructor();
7
+ load(data?: RecursivePartial<IExplode>): void;
8
+ }
@@ -1,8 +1,10 @@
1
1
  import type { DestroyMode } from "../../Enums/DestroyMode.js";
2
2
  import type { IDestroyBounds } from "./IDestroyBounds.js";
3
+ import type { IExplode } from "./IExplode.js";
3
4
  import type { ISplit } from "./ISplit.js";
4
5
  export interface IDestroy {
5
6
  bounds: IDestroyBounds;
7
+ explode: IExplode;
6
8
  mode: DestroyMode | keyof typeof DestroyMode;
7
9
  split: ISplit;
8
10
  }
@@ -0,0 +1,4 @@
1
+ export interface IExplode {
2
+ maxSizeFactor: number;
3
+ speed: number;
4
+ }
package/types/Types.d.ts CHANGED
@@ -9,6 +9,14 @@ export type DestroyParticlesOptions = ParticlesOptions & {
9
9
  };
10
10
  export type DestroyParticle = Particle & {
11
11
  destroyBounds?: Partial<IBounds>;
12
+ exploding?: {
13
+ initialFillOpacity: number;
14
+ initialSize: number;
15
+ initialStrokeOpacity: number;
16
+ maxSize: number;
17
+ progress: number;
18
+ speed: number;
19
+ };
12
20
  options: DestroyParticlesOptions;
13
21
  splitCount?: number;
14
22
  unbreakableUntil?: number;
package/960.min.js DELETED
@@ -1 +0,0 @@
1
- "use strict";(this.webpackChunk_tsparticles_updater_destroy=this.webpackChunk_tsparticles_updater_destroy||[]).push([[960],{960(t,e,o){o.d(e,{DestroyUpdater:()=>h});var l,i,s=o(303);class r{bottom;left;right;top;load(t){(0,s.isNull)(t)||(void 0!==t.bottom&&(this.bottom=(0,s.setRangeValue)(t.bottom)),void 0!==t.left&&(this.left=(0,s.setRangeValue)(t.left)),void 0!==t.right&&(this.right=(0,s.setRangeValue)(t.right)),void 0!==t.top&&(this.top=(0,s.setRangeValue)(t.top)))}}(l=i||(i={})).none="none",l.split="split";class n extends s.ValueWithRandom{constructor(){super(),this.value=3}}class a extends s.ValueWithRandom{constructor(){super(),this.value={min:4,max:9}}}class f{count;factor;fillColor;fillColorOffset;particles;rate;sizeOffset;strokeColor;strokeColorOffset;constructor(){this.count=1,this.factor=new n,this.rate=new a,this.sizeOffset=!0}load(t){!(0,s.isNull)(t)&&(void 0!==t.fillColor&&(this.fillColor=s.OptionsColor.create(this.fillColor,t.fillColor)),void 0!==t.strokeColor&&(this.strokeColor=s.OptionsColor.create(this.strokeColor,t.strokeColor)),void 0!==t.count&&(this.count=t.count),this.factor.load(t.factor),this.rate.load(t.rate),this.particles=(0,s.executeOnSingleOrMultiple)(t.particles,t=>(0,s.deepExtend)({},t)),void 0!==t.sizeOffset&&(this.sizeOffset=t.sizeOffset),t.fillColorOffset&&(this.fillColorOffset=this.fillColorOffset??{},void 0!==t.fillColorOffset.h&&(this.fillColorOffset.h=t.fillColorOffset.h),void 0!==t.fillColorOffset.s&&(this.fillColorOffset.s=t.fillColorOffset.s),void 0!==t.fillColorOffset.l&&(this.fillColorOffset.l=t.fillColorOffset.l)),t.strokeColorOffset&&(this.strokeColorOffset=this.strokeColorOffset??{},void 0!==t.strokeColorOffset.h&&(this.strokeColorOffset.h=t.strokeColorOffset.h),void 0!==t.strokeColorOffset.s&&(this.strokeColorOffset.s=t.strokeColorOffset.s),void 0!==t.strokeColorOffset.l&&(this.strokeColorOffset.l=t.strokeColorOffset.l)))}}class u{bounds;mode;split;constructor(){this.bounds=new r,this.mode=i.none,this.split=new f}load(t){(0,s.isNull)(t)||(t.mode&&(this.mode=t.mode),t.bounds&&this.bounds.load(t.bounds),this.split.load(t.split))}}function d(t,e,o,l){if(t&&l){let e,o,i,r,n,a;return e=(0,s.getRangeValue)(t.h??0),o=(0,s.getRangeValue)(t.s??0),i=(0,s.getRangeValue)(t.l??0),r=(l.h+e)%360,n=Math.max(0,Math.min(100,l.s+o)),a=Math.max(0,Math.min(100,l.l+i)),s.AnimatableColor.create(void 0,{value:{hsl:{h:r<0?r+360:r,s:n,l:a}}})}return e?s.AnimatableColor.create(void 0,e):o?s.AnimatableColor.create(void 0,o):l?s.AnimatableColor.create(void 0,{value:{hsl:l}}):void 0}class h{_container;_pluginManager;constructor(t,e){this._container=e,this._pluginManager=t}init(t){let e=this._container,o=t.options.destroy;if(!o)return;t.splitCount=0;let l=o.bounds;t.destroyBounds??={};let{bottom:i,left:r,right:n,top:a}=l,{destroyBounds:f}=t,u=e.canvas.size;i&&(f.bottom=(0,s.getRangeValue)(i)*u.height/s.percentDenominator),r&&(f.left=(0,s.getRangeValue)(r)*u.width/s.percentDenominator),n&&(f.right=(0,s.getRangeValue)(n)*u.width/s.percentDenominator),a&&(f.top=(0,s.getRangeValue)(a)*u.height/s.percentDenominator)}isEnabled(t){return!t.destroyed}loadOptions(t,...e){for(let o of(t.destroy??=new u,e))t.destroy.load(o?.destroy)}particleDestroyed(t,e){if(e)return;let o=t.options.destroy;o?.mode===i.split&&function(t,e,o){let l=o.options.destroy;if(!l)return;let i=l.split;if(i.count>=0){if(void 0===o.splitCount||o.splitCount>i.count)return;o.splitCount++}let r=(0,s.getRangeValue)(i.rate.value),n=(0,s.itemFromSingleOrMultiple)(i.particles);for(let l=0;l<r;l++)!function(t,e,o,l){let i=o.options.destroy;if(!i)return;let r=i.split,n=(0,s.loadParticlesOptions)(t,e,o.options),a=(0,s.itemFromSingleOrMultiple)(r.fillColor),f=(0,s.itemFromSingleOrMultiple)(r.strokeColor),u=o.getFillColor(),h=o.getStrokeColor();n.move.load({center:{x:o.position.x,y:o.position.y,mode:s.PixelMode.precise}});let c=s.identity/(0,s.getRangeValue)(r.factor.value);(0,s.isNumber)(n.size.value)?n.size.value*=c:(n.size.value.min*=c,n.size.value.max*=c),n.load(l);let p=(0,s.itemFromSingleOrMultiple)(n.paint),C=p?.fill,g=p?.stroke,m=d(r.fillColorOffset,a,C?.color,u),v=d(r.strokeColorOffset,f,g?.color,h);m&&C&&(C.color=m),v&&g&&(g.color=v);let O=r.sizeOffset?(0,s.setRangeValue)(-o.size.value,o.size.value):0,b={x:o.position.x+(0,s.randomInRangeValue)(O),y:o.position.y+(0,s.randomInRangeValue)(O)};e.particles.addParticle(b,n,o.group,t=>!(t.size.value<.5)&&(t.velocity.length=(0,s.randomInRangeValue)((0,s.setRangeValue)(o.velocity.length,t.velocity.length)),t.splitCount=(o.splitCount??0)+1,t.unbreakable=!0,t.unbreakableUntil=performance.now()+500,!0))}(t,e,o,n)}(this._pluginManager,this._container,t)}update(t){void 0!==t.unbreakableUntil&&performance.now()>=t.unbreakableUntil&&(t.unbreakable=!1,t.unbreakableUntil=void 0);let e=t.getPosition(),o=t.destroyBounds;o&&(void 0!==o.bottom&&e.y>=o.bottom||void 0!==o.left&&e.x<=o.left||void 0!==o.right&&e.x>=o.right||void 0!==o.top&&e.y<=o.top)&&t.destroy()}}}}]);