Skip to content

Commit

Permalink
fix: fixed overlapping issues
Browse files Browse the repository at this point in the history
  • Loading branch information
matteobruni committed Jul 3, 2020
1 parent 9fe288f commit 442777c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 109 deletions.
71 changes: 37 additions & 34 deletions core/main/src/Core/Particle.ts
Expand Up @@ -95,26 +95,23 @@ export class Particle implements IParticle {

particlesOptions.load(options.particles);

if (overrideOptions?.shape !== undefined) {
const shapeType = overrideOptions.shape.type ?? particlesOptions.shape.type;
if (overrideOptions?.shape?.type) {
const shapeType = overrideOptions.shape.type;

this.shape = shapeType instanceof Array ? Utils.itemFromArray(shapeType) : shapeType;

const shapeOptions = new Shape();

shapeOptions.load(overrideOptions.shape);

if (this.shape !== undefined) {
if (this.shape) {
const shapeData = shapeOptions.options[this.shape];

if (shapeData !== undefined) {
if (shapeData) {
this.shapeData = Utils.deepExtend(
{},
shapeData instanceof Array ? Utils.itemFromArray(shapeData) : shapeData
);

this.fill = this.shapeData?.fill ?? this.fill;
this.close = this.shapeData?.close ?? this.close;
}
}
} else {
Expand All @@ -129,9 +126,6 @@ export class Particle implements IParticle {
{},
shapeData instanceof Array ? Utils.itemFromArray(shapeData) : shapeData
);

this.fill = this.shapeData?.fill ?? this.fill;
this.close = this.shapeData?.close ?? this.close;
}
}

Expand All @@ -143,6 +137,9 @@ export class Particle implements IParticle {
particlesOptions.load(this.shapeData?.particles);
}

this.fill = this.shapeData?.fill ?? this.fill;
this.close = this.shapeData?.close ?? this.close;

this.particlesOptions = particlesOptions;

const noiseDelay = this.particlesOptions.move.noise.delay;
Expand Down Expand Up @@ -250,8 +247,8 @@ export class Particle implements IParticle {
};

/* check position - avoid overlap */
if (this.particlesOptions.collisions.enable) {
this.checkOverlap(position);
if (this.particlesOptions.collisions.enable && !this.checkOverlap(position)) {
throw new Error();
}

/* opacity */
Expand Down Expand Up @@ -333,16 +330,14 @@ export class Particle implements IParticle {
this.container.canvas.drawParticle(this, delta);
}

public isOverlapping(): { collisionFound: boolean; iterations: number } {
public isOverlapping(): boolean {
const container = this.container;

let collisionFound = false;
let iterations = 0;

const pos1 = this.getPosition();

for (const p2 of container.particles.array.filter((t) => t != this)) {
iterations++;
const pos2 = p2.getPosition();
const dist = Utils.getDistance(pos1, pos2);

Expand All @@ -352,25 +347,7 @@ export class Particle implements IParticle {
}
}

return {
collisionFound: collisionFound,
iterations: iterations,
};
}

public checkOverlap(position?: ICoordinates): void {
const container = this.container;
const overlapResult = this.isOverlapping();

if (overlapResult.iterations >= container.particles.count) {
// too many particles, removing from the current
container.particles.remove(this);
} else if (overlapResult.collisionFound) {
this.position.x = position ? position.x : Math.random() * container.canvas.size.width;
this.position.y = position ? position.y : Math.random() * container.canvas.size.height;

this.checkOverlap();
}
return collisionFound;
}

public startInfection(stage: number): void {
Expand Down Expand Up @@ -468,6 +445,32 @@ export class Particle implements IParticle {
this.destroyed = true;
}

private checkOverlap(position?: ICoordinates, iterations = 0): boolean {
const container = this.container;

if (!container.particles.count) {
return true;
}

if (iterations >= container.particles.count) {
// too many particles
return false;
}

const overlapping = this.isOverlapping();

console.log(overlapping);

if (overlapping) {
this.position.x = position ? position.x : Math.random() * container.canvas.size.width;
this.position.y = position ? position.y : Math.random() * container.canvas.size.height;

return this.checkOverlap(undefined, iterations + 1);
}

return true;
}

private nextInfectionStage(): void {
const options = this.container.options;
const stagesCount = options.infection.stages.length;
Expand Down
14 changes: 10 additions & 4 deletions core/main/src/Core/Particles.ts
Expand Up @@ -203,12 +203,18 @@ export class Particles {
this.pushing = false;
}

public addParticle(position?: ICoordinates, overrideOptions?: RecursivePartial<IParticles>): Particle {
const particle = new Particle(this.container, position, overrideOptions);
public addParticle(position?: ICoordinates, overrideOptions?: RecursivePartial<IParticles>): Particle | undefined {
try {
const particle = new Particle(this.container, position, overrideOptions);

this.array.push(particle);
this.array.push(particle);

return particle;
return particle;
} catch {
console.log("error adding particle");

return;
}
}

public removeQuantity(quantity: number): void {
Expand Down
42 changes: 16 additions & 26 deletions core/main/src/Utils/ColorUtils.ts
Expand Up @@ -66,29 +66,24 @@ export class ColorUtils {
const g1 = color.g / 255;
const b1 = color.b / 255;

const maxColor = Math.max(r1, g1, b1);
const minColor = Math.min(r1, g1, b1);
const max = Math.max(r1, g1, b1);
const min = Math.min(r1, g1, b1);

//Calculate L:
const res = {
h: 0,
l: (maxColor + minColor) / 2,
l: (max + min) / 2,
s: 0,
};

if (maxColor != minColor) {
if (max != min) {
//Calculate S:
res.s =
res.l < 0.5
? (maxColor - minColor) / (maxColor + minColor)
: (maxColor - minColor) / (2.0 - maxColor - minColor);
res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
//Calculate H:
res.h =
r1 === maxColor
? (g1 - b1) / (maxColor - minColor)
: (res.h =
g1 === maxColor
? 2.0 + (b1 - r1) / (maxColor - minColor)
: 4.0 + (r1 - g1) / (maxColor - minColor));
r1 === max
? (g1 - b1) / (max - min)
: (res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min));
}

res.l *= 100;
Expand Down Expand Up @@ -165,18 +160,13 @@ export class ColorUtils {
* @param min a minimum seed value for all 3 values
*/
public static getRandomRgbColor(min?: number): IRgb {
const fixedMin = min || 0;
const minColor = fixedMin + fixedMin * Math.pow(16, 2) + fixedMin * Math.pow(16, 4);
const factor = minColor ^ 0xffffff;
const randomColor = Math.floor((Math.random() * factor) | minColor).toString(16);

return (
this.stringToRgb(`#${randomColor}`) ?? {
b: 0,
g: 0,
r: 0,
}
);
const fixedMin = min ?? 0;

return {
b: Utils.randomInRange(fixedMin, 256),
g: Utils.randomInRange(fixedMin, 256),
r: Utils.randomInRange(fixedMin, 256),
};
}

/**
Expand Down
83 changes: 38 additions & 45 deletions core/main/src/Utils/Utils.ts
Expand Up @@ -213,12 +213,12 @@ export class Utils {
}

public static itemFromArray<T>(array: T[], index?: number): T {
return array[index !== undefined ? index : this.arrayRandomIndex(array)];
return array[index ?? this.arrayRandomIndex(array)];
}

public static randomInRange(r1: number, r2: number): number {
const max = Math.max(r1, r2);
const min = Math.min(r1, r2);
const max = Math.max(r1, r2),
min = Math.min(r1, r2);

return Math.random() * (max - min) + min;
}
Expand Down Expand Up @@ -246,63 +246,60 @@ export class Utils {
resolve: (value?: IImage | PromiseLike<IImage> | undefined) => void,
reject: (reason?: string) => void
) => {
if (!source) {
reject("Error tsParticles - No image.src");
return;
}

const image: IImage = {
source: source,
type: source.substr(source.length - 3),
};

if (source) {
const img = new Image();
const img = new Image();

img.addEventListener("load", () => {
image.element = img;
img.addEventListener("load", () => {
image.element = img;

resolve(image);
});
resolve(image);
});

img.addEventListener("error", () => {
reject(`Error tsParticles - loading image: ${source}`);
});
img.addEventListener("error", () => {
reject(`Error tsParticles - loading image: ${source}`);
});

img.src = source;
} else {
reject("Error tsParticles - No image.src");
}
img.src = source;
}
);
}

public static async downloadSvgImage(source: string): Promise<IImage> {
if (source) {
const image: IImage = {
source: source,
type: source.substr(source.length - 3),
};

if (image.type !== "svg") {
return this.loadImage(source);
}
if (!source) {
throw new Error("Error tsParticles - No image.src");
}

const response = await fetch(image.source);
const image: IImage = {
source: source,
type: source.substr(source.length - 3),
};

if (response.ok) {
image.svgData = await response.text();
if (image.type !== "svg") {
return this.loadImage(source);
}

return image;
} else {
throw new Error("Error tsParticles - Image not found");
}
} else {
throw new Error("Error tsParticles - No image.src");
const response = await fetch(image.source);

if (!response.ok) {
throw new Error("Error tsParticles - Image not found");
}

image.svgData = await response.text();

return image;
}

public static deepExtend(destination: any, ...sources: any[]): any {
for (const source of sources) {
if (source === undefined || source === null) {
continue;
}

for (const source of sources.filter((s) => s !== undefined && s !== null)) {
if (typeof source !== "object") {
destination = source;

Expand Down Expand Up @@ -339,7 +336,7 @@ export class Utils {

public static isDivModeEnabled(mode: DivMode, divs: SingleOrMultiple<DivEvent>): boolean {
return divs instanceof Array
? divs.filter((t) => t.enable && Utils.isInArray(mode, t.mode)).length > 0
? !!divs.find((t) => t.enable && Utils.isInArray(mode, t.mode))
: Utils.isInArray(mode, divs.mode);
}

Expand Down Expand Up @@ -380,11 +377,7 @@ export class Utils {
}

public static divMode<T extends IModeDiv>(divs?: SingleOrMultiple<T>, divId?: string): T | undefined {
if (!divId) {
return;
}

if (!divs) {
if (!divId || !divs) {
return;
}

Expand Down

0 comments on commit 442777c

Please sign in to comment.