@tsparticles/interaction-particles-collisions 3.9.1 → 4.0.0-alpha.1
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/373.min.js +2 -0
- package/373.min.js.LICENSE.txt +1 -0
- package/518.min.js +2 -0
- package/518.min.js.LICENSE.txt +1 -0
- package/browser/Absorb.js +7 -4
- package/browser/Bounce.js +3 -2
- package/browser/Collider.js +11 -2
- package/browser/CollisionMode.js +6 -0
- package/browser/Destroy.js +4 -3
- package/browser/Options/Classes/Collisions.js +31 -0
- package/browser/Options/Classes/CollisionsAbsorb.js +14 -0
- package/browser/Options/Classes/CollisionsOverlap.js +18 -0
- package/browser/Options/Interfaces/ICollisions.js +1 -0
- package/browser/Options/Interfaces/ICollisionsAbsorb.js +1 -0
- package/browser/Options/Interfaces/ICollisionsOverlap.js +1 -0
- package/browser/OverlapPlugin.js +14 -0
- package/browser/OverlapPluginInstance.js +25 -0
- package/browser/ResolveCollision.js +4 -1
- package/browser/Types.js +1 -0
- package/browser/index.js +10 -6
- package/cjs/Absorb.js +10 -10
- package/cjs/Bounce.js +6 -8
- package/cjs/Collider.js +15 -10
- package/cjs/CollisionMode.js +6 -0
- package/cjs/Destroy.js +7 -9
- package/cjs/Options/Classes/Collisions.js +31 -0
- package/cjs/Options/Classes/CollisionsAbsorb.js +14 -0
- package/cjs/Options/Classes/CollisionsOverlap.js +18 -0
- package/cjs/Options/Interfaces/ICollisions.js +1 -0
- package/cjs/Options/Interfaces/ICollisionsAbsorb.js +1 -0
- package/cjs/Options/Interfaces/ICollisionsOverlap.js +1 -0
- package/cjs/OverlapPlugin.js +14 -0
- package/cjs/OverlapPluginInstance.js +25 -0
- package/cjs/ResolveCollision.js +14 -14
- package/cjs/Types.js +1 -0
- package/cjs/index.js +10 -9
- package/dist_browser_Collider_js.js +110 -0
- package/dist_browser_OverlapPlugin_js.js +40 -0
- package/esm/Absorb.js +7 -4
- package/esm/Bounce.js +3 -2
- package/esm/Collider.js +11 -2
- package/esm/CollisionMode.js +6 -0
- package/esm/Destroy.js +4 -3
- package/esm/Options/Classes/Collisions.js +31 -0
- package/esm/Options/Classes/CollisionsAbsorb.js +14 -0
- package/esm/Options/Classes/CollisionsOverlap.js +18 -0
- package/esm/Options/Interfaces/ICollisions.js +1 -0
- package/esm/Options/Interfaces/ICollisionsAbsorb.js +1 -0
- package/esm/Options/Interfaces/ICollisionsOverlap.js +1 -0
- package/esm/OverlapPlugin.js +14 -0
- package/esm/OverlapPluginInstance.js +25 -0
- package/esm/ResolveCollision.js +4 -1
- package/esm/Types.js +1 -0
- package/esm/index.js +10 -6
- package/package.json +4 -3
- package/report.html +5 -4
- package/tsparticles.interaction.particles.collisions.js +209 -70
- package/tsparticles.interaction.particles.collisions.min.js +1 -1
- package/tsparticles.interaction.particles.collisions.min.js.LICENSE.txt +1 -1
- package/types/Bounce.d.ts +2 -2
- package/types/Collider.d.ts +6 -4
- package/types/CollisionMode.d.ts +5 -0
- package/types/Options/Classes/Collisions.d.ts +15 -0
- package/types/Options/Classes/CollisionsAbsorb.d.ts +7 -0
- package/types/Options/Classes/CollisionsOverlap.d.ts +8 -0
- package/types/Options/Interfaces/ICollisions.d.ts +12 -0
- package/types/Options/Interfaces/ICollisionsAbsorb.d.ts +3 -0
- package/types/Options/Interfaces/ICollisionsOverlap.d.ts +4 -0
- package/types/OverlapPlugin.d.ts +7 -0
- package/types/OverlapPluginInstance.d.ts +8 -0
- package/types/ResolveCollision.d.ts +3 -2
- package/types/Types.d.ts +12 -0
- package/types/index.d.ts +1 -1
- package/umd/Absorb.js +7 -4
- package/umd/Bounce.js +3 -2
- package/umd/Collider.js +11 -2
- package/umd/CollisionMode.js +19 -0
- package/umd/Destroy.js +4 -3
- package/umd/Options/Classes/Collisions.js +45 -0
- package/umd/Options/Classes/CollisionsAbsorb.js +28 -0
- package/umd/Options/Classes/CollisionsOverlap.js +32 -0
- package/umd/Options/Interfaces/ICollisions.js +12 -0
- package/umd/Options/Interfaces/ICollisionsAbsorb.js +12 -0
- package/umd/Options/Interfaces/ICollisionsOverlap.js +12 -0
- package/umd/OverlapPlugin.js +28 -0
- package/umd/OverlapPluginInstance.js +39 -0
- package/umd/ResolveCollision.js +8 -5
- package/umd/Types.js +12 -0
- package/umd/index.js +45 -7
package/373.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 373.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_interaction_particles_collisions=this.webpackChunk_tsparticles_interaction_particles_collisions||[]).push([[373],{373(o,e,s){s.d(e,{Collider:()=>p});var i,t=s(303);!function(o){o.absorb="absorb",o.bounce="bounce",o.destroy="destroy"}(i||(i={}));class n{constructor(){this.speed=2}load(o){(0,t.isNull)(o)||void 0!==o.speed&&(this.speed=o.speed)}}class l{constructor(){this.enable=!0,this.retries=0}load(o){(0,t.isNull)(o)||(void 0!==o.enable&&(this.enable=o.enable),void 0!==o.retries&&(this.retries=o.retries))}}class a{constructor(){this.absorb=new n,this.bounce=new t.ParticlesBounce,this.enable=!1,this.maxSpeed=50,this.mode=i.bounce,this.overlap=new l}load(o){(0,t.isNull)(o)||(this.absorb.load(o.absorb),this.bounce.load(o.bounce),void 0!==o.enable&&(this.enable=o.enable),void 0!==o.maxSpeed&&(this.maxSpeed=(0,t.setRangeValue)(o.maxSpeed)),void 0!==o.mode&&(this.mode=o.mode),this.overlap.load(o.overlap))}}function c(o,e,s,i,n,l){if(!o.options.collisions||!s.options.collisions)return;const a=(0,t.clamp)(o.options.collisions.absorb.speed*n.factor/10,0,i);o.size.value+=.5*a,s.size.value-=a,i<=l&&(s.size.value=0,s.destroy())}const r=o=>{o.options.collisions&&(o.collisionMaxSpeed??=(0,t.getRangeValue)(o.options.collisions.maxSpeed),o.velocity.length>o.collisionMaxSpeed&&(o.velocity.length=o.collisionMaxSpeed))};function d(o,e){(0,t.circleBounce)((0,t.circleBounceDataFromParticle)(o),(0,t.circleBounceDataFromParticle)(e)),r(o),r(e)}function u(o,e,s,t){if(o.options.collisions&&e.options.collisions)switch(o.options.collisions.mode){case i.absorb:!function(o,e,s,i){const t=o.getRadius(),n=e.getRadius();!t&&n?o.destroy():t&&!n?e.destroy():t&&n&&(t>=n?c(o,0,e,n,s,i):c(e,0,o,t,s,i))}(o,e,s,t);break;case i.bounce:d(o,e);break;case i.destroy:!function(o,e){o.unbreakable||e.unbreakable||d(o,e);const s=o.getRadius(),i=e.getRadius();!s&&i?o.destroy():s&&!i?e.destroy():s&&i&&(o.getRadius()>=e.getRadius()?e:o).destroy()}(o,e)}}class p extends t.ParticlesInteractorBase{constructor(o){super(o)}clear(){}init(){}interact(o,e){if(o.destroyed||o.spawning)return;const s=this.container,i=o.getPosition(),n=o.getRadius(),l=s.particles.quadTree.queryCircle(i,2*n);for(const a of l){if(o===a||!o.options.collisions||!a.options.collisions||!a.options.collisions.enable||o.options.collisions.mode!==a.options.collisions.mode||a.destroyed||a.spawning)continue;const l=a.getPosition(),c=a.getRadius();if(Math.abs(Math.round(i.z)-Math.round(l.z))>n+c)continue;(0,t.getDistance)(i,l)>n+c||u(o,a,e,s.retina.pixelRatio)}}isEnabled(o){return!!o.options.collisions?.enable}loadParticlesOptions(o,...e){o.collisions??=new a;for(const s of e)o.collisions.load(s?.collisions)}reset(){}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Collisions Particles Interaction v4.0.0-alpha.1 by Matteo Bruni */
|
package/518.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 518.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_interaction_particles_collisions=this.webpackChunk_tsparticles_interaction_particles_collisions||[]).push([[518],{518(e,i,t){t.d(i,{OverlapPlugin:()=>n});var r=t(303);class s{constructor(e){this._checkOverlap=(e,i,t)=>{const s=e.options.collisions,n=e.getRadius();if(!s?.enable)return!1;const c=s.overlap;if(c.enable)return!1;const o=c.retries;if(o>=0&&t>o)throw new Error("Particle is overlapping and can't be placed");return!!this._container.particles.find((e=>(0,r.getDistance)(i,e.position)<n+e.getRadius()))},this._container=e}checkParticlePosition(e,i,t){return this._checkOverlap(e,i,t)}}class n{constructor(){this.id="overlap"}getPlugin(e){return Promise.resolve(new s(e))}loadOptions(){}needsPlugin(){return!0}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Collisions Particles Interaction v4.0.0-alpha.1 by Matteo Bruni */
|
package/browser/Absorb.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { clamp } from "@tsparticles/engine";
|
|
2
2
|
const half = 0.5, absorbFactor = 10, minAbsorbFactor = 0;
|
|
3
|
-
function updateAbsorb(p1,
|
|
3
|
+
function updateAbsorb(p1, _r1, p2, r2, delta, pixelRatio) {
|
|
4
|
+
if (!p1.options.collisions || !p2.options.collisions) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
4
7
|
const factor = clamp((p1.options.collisions.absorb.speed * delta.factor) / absorbFactor, minAbsorbFactor, r2);
|
|
5
8
|
p1.size.value += factor * half;
|
|
6
9
|
p2.size.value -= factor;
|
|
@@ -11,13 +14,13 @@ function updateAbsorb(p1, r1, p2, r2, delta, pixelRatio) {
|
|
|
11
14
|
}
|
|
12
15
|
export function absorb(p1, p2, delta, pixelRatio) {
|
|
13
16
|
const r1 = p1.getRadius(), r2 = p2.getRadius();
|
|
14
|
-
if (r1
|
|
17
|
+
if (!r1 && r2) {
|
|
15
18
|
p1.destroy();
|
|
16
19
|
}
|
|
17
|
-
else if (r1
|
|
20
|
+
else if (r1 && !r2) {
|
|
18
21
|
p2.destroy();
|
|
19
22
|
}
|
|
20
|
-
else if (r1
|
|
23
|
+
else if (r1 && r2) {
|
|
21
24
|
if (r1 >= r2) {
|
|
22
25
|
updateAbsorb(p1, r1, p2, r2, delta, pixelRatio);
|
|
23
26
|
}
|
package/browser/Bounce.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { circleBounce, circleBounceDataFromParticle, getRangeValue } from "@tsparticles/engine";
|
|
2
2
|
const fixBounceSpeed = (p) => {
|
|
3
|
-
if (p.
|
|
4
|
-
|
|
3
|
+
if (!p.options.collisions) {
|
|
4
|
+
return;
|
|
5
5
|
}
|
|
6
|
+
p.collisionMaxSpeed ??= getRangeValue(p.options.collisions.maxSpeed);
|
|
6
7
|
if (p.velocity.length > p.collisionMaxSpeed) {
|
|
7
8
|
p.velocity.length = p.collisionMaxSpeed;
|
|
8
9
|
}
|
package/browser/Collider.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ParticlesInteractorBase, getDistance } from "@tsparticles/engine";
|
|
1
|
+
import { ParticlesInteractorBase, getDistance, } from "@tsparticles/engine";
|
|
2
|
+
import { Collisions } from "./Options/Classes/Collisions.js";
|
|
2
3
|
import { resolveCollision } from "./ResolveCollision.js";
|
|
3
4
|
const double = 2;
|
|
4
5
|
export class Collider extends ParticlesInteractorBase {
|
|
@@ -16,6 +17,8 @@ export class Collider extends ParticlesInteractorBase {
|
|
|
16
17
|
const container = this.container, pos1 = p1.getPosition(), radius1 = p1.getRadius(), query = container.particles.quadTree.queryCircle(pos1, radius1 * double);
|
|
17
18
|
for (const p2 of query) {
|
|
18
19
|
if (p1 === p2 ||
|
|
20
|
+
!p1.options.collisions ||
|
|
21
|
+
!p2.options.collisions ||
|
|
19
22
|
!p2.options.collisions.enable ||
|
|
20
23
|
p1.options.collisions.mode !== p2.options.collisions.mode ||
|
|
21
24
|
p2.destroyed ||
|
|
@@ -34,7 +37,13 @@ export class Collider extends ParticlesInteractorBase {
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
isEnabled(particle) {
|
|
37
|
-
return particle.options.collisions
|
|
40
|
+
return !!particle.options.collisions?.enable;
|
|
41
|
+
}
|
|
42
|
+
loadParticlesOptions(options, ...sources) {
|
|
43
|
+
options.collisions ??= new Collisions();
|
|
44
|
+
for (const source of sources) {
|
|
45
|
+
options.collisions.load(source?.collisions);
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
48
|
reset() {
|
|
40
49
|
}
|
package/browser/Destroy.js
CHANGED
|
@@ -3,13 +3,14 @@ export function destroy(p1, p2) {
|
|
|
3
3
|
if (!p1.unbreakable && !p2.unbreakable) {
|
|
4
4
|
bounce(p1, p2);
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
const p1Radius = p1.getRadius(), p2Radius = p2.getRadius();
|
|
7
|
+
if (!p1Radius && p2Radius) {
|
|
7
8
|
p1.destroy();
|
|
8
9
|
}
|
|
9
|
-
else if (
|
|
10
|
+
else if (p1Radius && !p2Radius) {
|
|
10
11
|
p2.destroy();
|
|
11
12
|
}
|
|
12
|
-
else if (
|
|
13
|
+
else if (p1Radius && p2Radius) {
|
|
13
14
|
const deleteP = p1.getRadius() >= p2.getRadius() ? p2 : p1;
|
|
14
15
|
deleteP.destroy();
|
|
15
16
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ParticlesBounce, isNull, setRangeValue, } from "@tsparticles/engine";
|
|
2
|
+
import { CollisionMode } from "../../CollisionMode.js";
|
|
3
|
+
import { CollisionsAbsorb } from "./CollisionsAbsorb.js";
|
|
4
|
+
import { CollisionsOverlap } from "./CollisionsOverlap.js";
|
|
5
|
+
export class Collisions {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.absorb = new CollisionsAbsorb();
|
|
8
|
+
this.bounce = new ParticlesBounce();
|
|
9
|
+
this.enable = false;
|
|
10
|
+
this.maxSpeed = 50;
|
|
11
|
+
this.mode = CollisionMode.bounce;
|
|
12
|
+
this.overlap = new CollisionsOverlap();
|
|
13
|
+
}
|
|
14
|
+
load(data) {
|
|
15
|
+
if (isNull(data)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.absorb.load(data.absorb);
|
|
19
|
+
this.bounce.load(data.bounce);
|
|
20
|
+
if (data.enable !== undefined) {
|
|
21
|
+
this.enable = data.enable;
|
|
22
|
+
}
|
|
23
|
+
if (data.maxSpeed !== undefined) {
|
|
24
|
+
this.maxSpeed = setRangeValue(data.maxSpeed);
|
|
25
|
+
}
|
|
26
|
+
if (data.mode !== undefined) {
|
|
27
|
+
this.mode = data.mode;
|
|
28
|
+
}
|
|
29
|
+
this.overlap.load(data.overlap);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
export class CollisionsOverlap {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.enable = true;
|
|
5
|
+
this.retries = 0;
|
|
6
|
+
}
|
|
7
|
+
load(data) {
|
|
8
|
+
if (isNull(data)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (data.enable !== undefined) {
|
|
12
|
+
this.enable = data.enable;
|
|
13
|
+
}
|
|
14
|
+
if (data.retries !== undefined) {
|
|
15
|
+
this.retries = data.retries;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OverlapPluginInstance } from "./OverlapPluginInstance.js";
|
|
2
|
+
export class OverlapPlugin {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.id = "overlap";
|
|
5
|
+
}
|
|
6
|
+
getPlugin(container) {
|
|
7
|
+
return Promise.resolve(new OverlapPluginInstance(container));
|
|
8
|
+
}
|
|
9
|
+
loadOptions() {
|
|
10
|
+
}
|
|
11
|
+
needsPlugin() {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getDistance } from "@tsparticles/engine";
|
|
2
|
+
const minRetries = 0;
|
|
3
|
+
export class OverlapPluginInstance {
|
|
4
|
+
constructor(container) {
|
|
5
|
+
this._checkOverlap = (particle, pos, tryCount) => {
|
|
6
|
+
const collisionsOptions = particle.options.collisions, radius = particle.getRadius();
|
|
7
|
+
if (!collisionsOptions?.enable) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const overlapOptions = collisionsOptions.overlap;
|
|
11
|
+
if (overlapOptions.enable) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const retries = overlapOptions.retries;
|
|
15
|
+
if (retries >= minRetries && tryCount > retries) {
|
|
16
|
+
throw new Error(`Particle is overlapping and can't be placed`);
|
|
17
|
+
}
|
|
18
|
+
return !!this._container.particles.find(p => getDistance(pos, p.position) < radius + p.getRadius());
|
|
19
|
+
};
|
|
20
|
+
this._container = container;
|
|
21
|
+
}
|
|
22
|
+
checkParticlePosition(particle, position, tryCount) {
|
|
23
|
+
return this._checkOverlap(particle, position, tryCount);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { CollisionMode } from "
|
|
1
|
+
import { CollisionMode } from "./CollisionMode.js";
|
|
2
2
|
import { absorb } from "./Absorb.js";
|
|
3
3
|
import { bounce } from "./Bounce.js";
|
|
4
4
|
import { destroy } from "./Destroy.js";
|
|
5
5
|
export function resolveCollision(p1, p2, delta, pixelRatio) {
|
|
6
|
+
if (!p1.options.collisions || !p2.options.collisions) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
6
9
|
switch (p1.options.collisions.mode) {
|
|
7
10
|
case CollisionMode.absorb: {
|
|
8
11
|
absorb(p1, p2, delta, pixelRatio);
|
package/browser/Types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/browser/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
engine.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export function loadParticlesCollisionsInteraction(engine) {
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.1");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { OverlapPlugin } = await import("./OverlapPlugin.js");
|
|
5
|
+
e.addPlugin(new OverlapPlugin());
|
|
6
|
+
e.addInteractor("particlesCollisions", async (container) => {
|
|
7
|
+
const { Collider } = await import("./Collider.js");
|
|
8
|
+
return new Collider(container);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
7
11
|
}
|
package/cjs/Absorb.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.absorb = absorb;
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
1
|
+
import { clamp } from "@tsparticles/engine";
|
|
5
2
|
const half = 0.5, absorbFactor = 10, minAbsorbFactor = 0;
|
|
6
|
-
function updateAbsorb(p1,
|
|
7
|
-
|
|
3
|
+
function updateAbsorb(p1, _r1, p2, r2, delta, pixelRatio) {
|
|
4
|
+
if (!p1.options.collisions || !p2.options.collisions) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const factor = clamp((p1.options.collisions.absorb.speed * delta.factor) / absorbFactor, minAbsorbFactor, r2);
|
|
8
8
|
p1.size.value += factor * half;
|
|
9
9
|
p2.size.value -= factor;
|
|
10
10
|
if (r2 <= pixelRatio) {
|
|
@@ -12,15 +12,15 @@ function updateAbsorb(p1, r1, p2, r2, delta, pixelRatio) {
|
|
|
12
12
|
p2.destroy();
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
function absorb(p1, p2, delta, pixelRatio) {
|
|
15
|
+
export function absorb(p1, p2, delta, pixelRatio) {
|
|
16
16
|
const r1 = p1.getRadius(), r2 = p2.getRadius();
|
|
17
|
-
if (r1
|
|
17
|
+
if (!r1 && r2) {
|
|
18
18
|
p1.destroy();
|
|
19
19
|
}
|
|
20
|
-
else if (r1
|
|
20
|
+
else if (r1 && !r2) {
|
|
21
21
|
p2.destroy();
|
|
22
22
|
}
|
|
23
|
-
else if (r1
|
|
23
|
+
else if (r1 && r2) {
|
|
24
24
|
if (r1 >= r2) {
|
|
25
25
|
updateAbsorb(p1, r1, p2, r2, delta, pixelRatio);
|
|
26
26
|
}
|
package/cjs/Bounce.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.bounce = bounce;
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
1
|
+
import { circleBounce, circleBounceDataFromParticle, getRangeValue } from "@tsparticles/engine";
|
|
5
2
|
const fixBounceSpeed = (p) => {
|
|
6
|
-
if (p.
|
|
7
|
-
|
|
3
|
+
if (!p.options.collisions) {
|
|
4
|
+
return;
|
|
8
5
|
}
|
|
6
|
+
p.collisionMaxSpeed ??= getRangeValue(p.options.collisions.maxSpeed);
|
|
9
7
|
if (p.velocity.length > p.collisionMaxSpeed) {
|
|
10
8
|
p.velocity.length = p.collisionMaxSpeed;
|
|
11
9
|
}
|
|
12
10
|
};
|
|
13
|
-
function bounce(p1, p2) {
|
|
14
|
-
|
|
11
|
+
export function bounce(p1, p2) {
|
|
12
|
+
circleBounce(circleBounceDataFromParticle(p1), circleBounceDataFromParticle(p2));
|
|
15
13
|
fixBounceSpeed(p1);
|
|
16
14
|
fixBounceSpeed(p2);
|
|
17
15
|
}
|
package/cjs/Collider.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
5
|
-
const ResolveCollision_js_1 = require("./ResolveCollision.js");
|
|
1
|
+
import { ParticlesInteractorBase, getDistance, } from "@tsparticles/engine";
|
|
2
|
+
import { Collisions } from "./Options/Classes/Collisions.js";
|
|
3
|
+
import { resolveCollision } from "./ResolveCollision.js";
|
|
6
4
|
const double = 2;
|
|
7
|
-
class Collider extends
|
|
5
|
+
export class Collider extends ParticlesInteractorBase {
|
|
8
6
|
constructor(container) {
|
|
9
7
|
super(container);
|
|
10
8
|
}
|
|
@@ -19,6 +17,8 @@ class Collider extends engine_1.ParticlesInteractorBase {
|
|
|
19
17
|
const container = this.container, pos1 = p1.getPosition(), radius1 = p1.getRadius(), query = container.particles.quadTree.queryCircle(pos1, radius1 * double);
|
|
20
18
|
for (const p2 of query) {
|
|
21
19
|
if (p1 === p2 ||
|
|
20
|
+
!p1.options.collisions ||
|
|
21
|
+
!p2.options.collisions ||
|
|
22
22
|
!p2.options.collisions.enable ||
|
|
23
23
|
p1.options.collisions.mode !== p2.options.collisions.mode ||
|
|
24
24
|
p2.destroyed ||
|
|
@@ -29,17 +29,22 @@ class Collider extends engine_1.ParticlesInteractorBase {
|
|
|
29
29
|
if (Math.abs(Math.round(pos1.z) - Math.round(pos2.z)) > radius1 + radius2) {
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
|
-
const dist =
|
|
32
|
+
const dist = getDistance(pos1, pos2), distP = radius1 + radius2;
|
|
33
33
|
if (dist > distP) {
|
|
34
34
|
continue;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
resolveCollision(p1, p2, delta, container.retina.pixelRatio);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
isEnabled(particle) {
|
|
40
|
-
return particle.options.collisions
|
|
40
|
+
return !!particle.options.collisions?.enable;
|
|
41
|
+
}
|
|
42
|
+
loadParticlesOptions(options, ...sources) {
|
|
43
|
+
options.collisions ??= new Collisions();
|
|
44
|
+
for (const source of sources) {
|
|
45
|
+
options.collisions.load(source?.collisions);
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
reset() {
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
|
-
exports.Collider = Collider;
|
package/cjs/Destroy.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.destroy = destroy;
|
|
4
|
-
const Bounce_js_1 = require("./Bounce.js");
|
|
5
|
-
function destroy(p1, p2) {
|
|
1
|
+
import { bounce } from "./Bounce.js";
|
|
2
|
+
export function destroy(p1, p2) {
|
|
6
3
|
if (!p1.unbreakable && !p2.unbreakable) {
|
|
7
|
-
|
|
4
|
+
bounce(p1, p2);
|
|
8
5
|
}
|
|
9
|
-
|
|
6
|
+
const p1Radius = p1.getRadius(), p2Radius = p2.getRadius();
|
|
7
|
+
if (!p1Radius && p2Radius) {
|
|
10
8
|
p1.destroy();
|
|
11
9
|
}
|
|
12
|
-
else if (
|
|
10
|
+
else if (p1Radius && !p2Radius) {
|
|
13
11
|
p2.destroy();
|
|
14
12
|
}
|
|
15
|
-
else if (
|
|
13
|
+
else if (p1Radius && p2Radius) {
|
|
16
14
|
const deleteP = p1.getRadius() >= p2.getRadius() ? p2 : p1;
|
|
17
15
|
deleteP.destroy();
|
|
18
16
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ParticlesBounce, isNull, setRangeValue, } from "@tsparticles/engine";
|
|
2
|
+
import { CollisionMode } from "../../CollisionMode.js";
|
|
3
|
+
import { CollisionsAbsorb } from "./CollisionsAbsorb.js";
|
|
4
|
+
import { CollisionsOverlap } from "./CollisionsOverlap.js";
|
|
5
|
+
export class Collisions {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.absorb = new CollisionsAbsorb();
|
|
8
|
+
this.bounce = new ParticlesBounce();
|
|
9
|
+
this.enable = false;
|
|
10
|
+
this.maxSpeed = 50;
|
|
11
|
+
this.mode = CollisionMode.bounce;
|
|
12
|
+
this.overlap = new CollisionsOverlap();
|
|
13
|
+
}
|
|
14
|
+
load(data) {
|
|
15
|
+
if (isNull(data)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.absorb.load(data.absorb);
|
|
19
|
+
this.bounce.load(data.bounce);
|
|
20
|
+
if (data.enable !== undefined) {
|
|
21
|
+
this.enable = data.enable;
|
|
22
|
+
}
|
|
23
|
+
if (data.maxSpeed !== undefined) {
|
|
24
|
+
this.maxSpeed = setRangeValue(data.maxSpeed);
|
|
25
|
+
}
|
|
26
|
+
if (data.mode !== undefined) {
|
|
27
|
+
this.mode = data.mode;
|
|
28
|
+
}
|
|
29
|
+
this.overlap.load(data.overlap);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
export class CollisionsOverlap {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.enable = true;
|
|
5
|
+
this.retries = 0;
|
|
6
|
+
}
|
|
7
|
+
load(data) {
|
|
8
|
+
if (isNull(data)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (data.enable !== undefined) {
|
|
12
|
+
this.enable = data.enable;
|
|
13
|
+
}
|
|
14
|
+
if (data.retries !== undefined) {
|
|
15
|
+
this.retries = data.retries;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OverlapPluginInstance } from "./OverlapPluginInstance.js";
|
|
2
|
+
export class OverlapPlugin {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.id = "overlap";
|
|
5
|
+
}
|
|
6
|
+
getPlugin(container) {
|
|
7
|
+
return Promise.resolve(new OverlapPluginInstance(container));
|
|
8
|
+
}
|
|
9
|
+
loadOptions() {
|
|
10
|
+
}
|
|
11
|
+
needsPlugin() {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getDistance } from "@tsparticles/engine";
|
|
2
|
+
const minRetries = 0;
|
|
3
|
+
export class OverlapPluginInstance {
|
|
4
|
+
constructor(container) {
|
|
5
|
+
this._checkOverlap = (particle, pos, tryCount) => {
|
|
6
|
+
const collisionsOptions = particle.options.collisions, radius = particle.getRadius();
|
|
7
|
+
if (!collisionsOptions?.enable) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const overlapOptions = collisionsOptions.overlap;
|
|
11
|
+
if (overlapOptions.enable) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const retries = overlapOptions.retries;
|
|
15
|
+
if (retries >= minRetries && tryCount > retries) {
|
|
16
|
+
throw new Error(`Particle is overlapping and can't be placed`);
|
|
17
|
+
}
|
|
18
|
+
return !!this._container.particles.find(p => getDistance(pos, p.position) < radius + p.getRadius());
|
|
19
|
+
};
|
|
20
|
+
this._container = container;
|
|
21
|
+
}
|
|
22
|
+
checkParticlePosition(particle, position, tryCount) {
|
|
23
|
+
return this._checkOverlap(particle, position, tryCount);
|
|
24
|
+
}
|
|
25
|
+
}
|
package/cjs/ResolveCollision.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { CollisionMode } from "./CollisionMode.js";
|
|
2
|
+
import { absorb } from "./Absorb.js";
|
|
3
|
+
import { bounce } from "./Bounce.js";
|
|
4
|
+
import { destroy } from "./Destroy.js";
|
|
5
|
+
export function resolveCollision(p1, p2, delta, pixelRatio) {
|
|
6
|
+
if (!p1.options.collisions || !p2.options.collisions) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
9
|
switch (p1.options.collisions.mode) {
|
|
10
|
-
case
|
|
11
|
-
|
|
10
|
+
case CollisionMode.absorb: {
|
|
11
|
+
absorb(p1, p2, delta, pixelRatio);
|
|
12
12
|
break;
|
|
13
13
|
}
|
|
14
|
-
case
|
|
15
|
-
|
|
14
|
+
case CollisionMode.bounce: {
|
|
15
|
+
bounce(p1, p2);
|
|
16
16
|
break;
|
|
17
17
|
}
|
|
18
|
-
case
|
|
19
|
-
|
|
18
|
+
case CollisionMode.destroy: {
|
|
19
|
+
destroy(p1, p2);
|
|
20
20
|
break;
|
|
21
21
|
}
|
|
22
22
|
}
|
package/cjs/Types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/cjs/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
export function loadParticlesCollisionsInteraction(engine) {
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.1");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { OverlapPlugin } = await import("./OverlapPlugin.js");
|
|
5
|
+
e.addPlugin(new OverlapPlugin());
|
|
6
|
+
e.addInteractor("particlesCollisions", async (container) => {
|
|
7
|
+
const { Collider } = await import("./Collider.js");
|
|
8
|
+
return new Collider(container);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
10
11
|
}
|