Skip to content

Commit

Permalink
feat: added error prefix to standardize error messages
Browse files Browse the repository at this point in the history
chore(image): improved image shape
  • Loading branch information
matteobruni committed Feb 28, 2023
1 parent 6bde6de commit f735252
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 107 deletions.
4 changes: 2 additions & 2 deletions engine/src/Core/Loader.ts
@@ -1,10 +1,10 @@
import { errorPrefix, generatedAttribute } from "./Utils/Constants";
import { Container } from "./Container";
import type { Engine } from "../engine";
import type { IOptions } from "../Options/Interfaces/IOptions";
import type { LoaderParams } from "./Interfaces/LoaderParams";
import type { RecursivePartial } from "../Types/RecursivePartial";
import type { SingleOrMultiple } from "../Types/SingleOrMultiple";
import { generatedAttribute } from "./Utils/Constants";
import { getRandom } from "../Utils/NumberUtils";
import { itemFromSingleOrMultiple } from "../Utils/Utils";

Expand All @@ -24,7 +24,7 @@ async function getDataFromUrl(
return response.json();
}

console.error(`tsParticles - Error ${response.status} while retrieving config file`);
console.error(`${errorPrefix} ${response.status} while retrieving config file`);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion engine/src/Core/Particle.ts
Expand Up @@ -43,6 +43,7 @@ import { StartValueType } from "../Enums/Types/StartValueType";
import { Vector } from "./Utils/Vector";
import { Vector3d } from "./Utils/Vector3d";
import { alterHsl } from "../Utils/CanvasUtils";
import { errorPrefix } from "./Utils/Constants";
import { loadParticlesOptions } from "../Utils/OptionsUtils";

/**
Expand Down Expand Up @@ -676,7 +677,7 @@ export class Particle implements IParticle {
const retries = overlapOptions.retries;

if (retries >= 0 && tryCount > retries) {
throw new Error("Particle is overlapping and can't be placed");
throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
}

let overlaps = false;
Expand Down
3 changes: 2 additions & 1 deletion engine/src/Core/Particles.ts
Expand Up @@ -14,6 +14,7 @@ import { QuadTree } from "./Utils/QuadTree";
import { Rectangle } from "./Utils/Rectangle";
import type { RecursivePartial } from "../Types/RecursivePartial";
import { calcPositionFromSize } from "../Utils/NumberUtils";
import { errorPrefix } from "./Utils/Constants";

/**
* Particles manager object
Expand Down Expand Up @@ -434,7 +435,7 @@ export class Particles {

return particle;
} catch (e) {
console.warn(`error adding particle: ${e}`);
console.warn(`${errorPrefix} adding particle: ${e}`);

return;
}
Expand Down
2 changes: 2 additions & 0 deletions engine/src/Core/Utils/Constants.ts
Expand Up @@ -15,3 +15,5 @@ export const mouseOutEvent = "pointerout";
export const touchCancelEvent = "touchcancel";
export const resizeEvent = "resize";
export const visibilityChangeEvent = "visibilitychange";

export const errorPrefix = "tsParticles - Error";
3 changes: 2 additions & 1 deletion engine/src/Core/Utils/FrameManager.ts
@@ -1,5 +1,6 @@
import type { Container } from "../Container";
import type { IDelta } from "../Interfaces/IDelta";
import { errorPrefix } from "./Constants";

function initDelta(value: number, fpsLimit = 60, smooth = false): IDelta {
return {
Expand Down Expand Up @@ -57,7 +58,7 @@ export class FrameManager {
container.draw(false);
}
} catch (e) {
console.error("tsParticles error in animation loop", e);
console.error(`${errorPrefix} in animation loop`, e);
}
}
}
3 changes: 2 additions & 1 deletion engine/src/Core/Utils/Vector3d.ts
@@ -1,4 +1,5 @@
import type { ICoordinates, ICoordinates3d } from "../Interfaces/ICoordinates";
import { errorPrefix } from "./Constants";

/**
* @category Utils
Expand Down Expand Up @@ -39,7 +40,7 @@ export class Vector3d implements ICoordinates3d {
this.y = y;
this.z = z ?? 0;
} else {
throw new Error("tsParticles - Vector3d not initialized correctly");
throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
}
}

Expand Down
5 changes: 4 additions & 1 deletion engine/src/engine.ts
Expand Up @@ -26,6 +26,7 @@ import type { Particle } from "./Core/Particle";
import { Plugins } from "./Core/Utils/Plugins";
import type { RecursivePartial } from "./Types/RecursivePartial";
import type { SingleOrMultiple } from "./Types/SingleOrMultiple";
import { errorPrefix } from "./Core/Utils/Constants";

declare const __VERSION__: string;

Expand Down Expand Up @@ -353,7 +354,9 @@ export class Engine {
const dom = this.dom();

if (!dom.length) {
throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");
throw new Error(
`${errorPrefix} can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()`
);
}

for (const domItem of dom) {
Expand Down
4 changes: 2 additions & 2 deletions engine/tests/Particle.ts
@@ -1,5 +1,5 @@
import { describe, it } from "mocha";
import type { ICoordinates } from "../src";
import { errorPrefix, ICoordinates } from "../src";
import { TestCanvas } from "./Fixture/TestCanvas";
import { TestContainer } from "./Fixture/TestContainer";
import { TestParticle } from "./Fixture/TestParticle";
Expand Down Expand Up @@ -99,7 +99,7 @@ describe("Particle", () => {
expectedShapeData = multipleShapeTypeOptions.particles.shape.options["polygon"];
break;
default:
throw new Error(`Unexpected shape type "${testParticle.particle?.shape}"`);
throw new Error(`${errorPrefix} Unexpected shape type "${testParticle.particle?.shape}"`);
}

expect(testParticle.particle?.close).to.eql(expectedShapeData.close);
Expand Down
4 changes: 2 additions & 2 deletions plugins/canvasMask/src/utils.ts
Expand Up @@ -6,9 +6,9 @@ import type {
IRgba,
RecursivePartial,
} from "tsparticles-engine";
import { errorPrefix, getRandom } from "tsparticles-engine";
import type { ICanvasMaskOverride } from "./Options/Interfaces/ICanvasMaskOverride";
import type { TextMask } from "./Options/Classes/TextMask";
import { getRandom } from "tsparticles-engine";

export type CanvasPixelData = {
height: number;
Expand Down Expand Up @@ -146,7 +146,7 @@ export function getImageData(src: string, offset: number): Promise<CanvasPixelDa
const context = canvas.getContext("2d");

if (!context) {
return reject(new Error("Could not get canvas context"));
return reject(new Error(`${errorPrefix} Could not get canvas context`));
}

context.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
Expand Down
8 changes: 4 additions & 4 deletions plugins/polygonMask/src/PolygonMaskInstance.ts
@@ -1,15 +1,15 @@
import type { Engine, IContainerPlugin, ICoordinates, IDelta, IDimension } from "tsparticles-engine";
import { calcClosestPtOnSegment, drawPolygonMask, drawPolygonMaskPath, parsePaths, segmentBounce } from "./utils";
import { deepExtend, getDistance, getDistances, getRandom, itemFromArray } from "tsparticles-engine";
import { deepExtend, errorPrefix, getDistance, getDistances, getRandom, itemFromArray } from "tsparticles-engine";
import type { ISvgPath } from "./Interfaces/ISvgPath";
import { OutModeDirection } from "tsparticles-engine";
import type { Particle } from "tsparticles-engine";
import type { PolygonMaskContainer } from "./types";
import { PolygonMaskInlineArrangement } from "./Enums/PolygonMaskInlineArrangement";
import { PolygonMaskType } from "./Enums/PolygonMaskType";

const noPolygonDataLoaded = "No polygon data loaded.",
noPolygonFound = "No polygon found, you need to specify SVG url in config.";
const noPolygonDataLoaded = `${errorPrefix} No polygon data loaded.`,
noPolygonFound = `${errorPrefix} No polygon found, you need to specify SVG url in config.`;

/**
* Polygon Mask manager
Expand Down Expand Up @@ -267,7 +267,7 @@ export class PolygonMaskInstance implements IContainerPlugin {
const req = await fetch(url);

if (!req.ok) {
throw new Error("tsParticles Error - Error occurred during polygon mask download");
throw new Error(`${errorPrefix} occurred during polygon mask download`);
}

return this.parseSvgPath(await req.text(), force);
Expand Down
97 changes: 29 additions & 68 deletions shapes/image/src/ImageDrawer.ts
@@ -1,41 +1,34 @@
import type { Container, IShapeDrawer } from "tsparticles-engine";
import type { ContainerImage, IImage, IParticleImage, ImageParticle } from "./Utils";
import { downloadSvgImage, loadImage, replaceImageColor } from "./Utils";
import type { IImage, IParticleImage, ImageParticle } from "./Utils";
import type { IImageShape } from "./IImageShape";
import type { ImageEngine } from "./types";
import { errorPrefix } from "tsparticles-engine";
import { replaceImageColor } from "./Utils";

/**
* @category Shape Drawers
*/
export class ImageDrawer implements IShapeDrawer {
/**
* The image set collection
* @private
*/
private _images: ContainerImage[];
private readonly _engine: ImageEngine;

/**
* Image drawer constructor, initializing the image set collection
*/
constructor() {
this._images = [];
constructor(engine: ImageEngine) {
this._engine = engine;
}

/**
* Adds an image to the given container
* @param container the container where the image is going to be added
* @param image the image to add to the container collection
*/
addImage(container: Container, image: IImage): void {
const containerImages = this.getImages(container);

containerImages?.images.push(image);
}
addImage(image: IImage): void {
if (!this._engine.images) {
this._engine.images = [];
}

/**
* Resets the image general collection
*/
destroy(): void {
this._images = [];
this._engine.images.push(image);
}

/**
Expand Down Expand Up @@ -66,26 +59,6 @@ export class ImageDrawer implements IShapeDrawer {
context.globalAlpha = 1;
}

/**
* Gets the image collection of the given container
* @param container the container requesting the image collection
* @returns the container image collection
*/
getImages(container: Container): ContainerImage {
const containerImages = this._images.find((t) => t.id === container.id);

if (!containerImages) {
this._images.push({
id: container.id,
images: [],
});

return this.getImages(container);
} else {
return containerImages;
}
}

/**
* Returning the side count for the image, defaults to 12 for using the inner circle as rendering
* When using non-transparent images this can be an issue with shadows
Expand All @@ -99,13 +72,15 @@ export class ImageDrawer implements IShapeDrawer {
return;
}

const container = particle.container,
images = this.getImages(container).images,
imageData = particle.shapeData as IImageShape,
image = images.find((t) => t.source === imageData.src);
if (!this._engine.images) {
this._engine.images = [];
}

const imageData = particle.shapeData as IImageShape,
image = this._engine.images.find((t: IImage) => t.source === imageData.src);

if (!image) {
this.loadImageShape(container, imageData).then(() => {
this.loadImageShape(imageData).then(() => {
this.loadShape(particle);
});
}
Expand All @@ -121,11 +96,15 @@ export class ImageDrawer implements IShapeDrawer {
return;
}

const images = this.getImages(container).images,
if (!this._engine.images) {
this._engine.images = [];
}

const images = this._engine.images,
imageData = particle.shapeData as IImageShape,
color = particle.getFillColor(),
replaceColor = imageData.replaceColor ?? imageData.replace_color,
image = images.find((t) => t.source === imageData.src);
image = images.find((t: IImage) => t.source === imageData.src);

if (!image) {
return;
Expand Down Expand Up @@ -176,32 +155,14 @@ export class ImageDrawer implements IShapeDrawer {

/**
* Loads the image shape
* @param container the container used for searching images
* @param imageShape the image shape to load
* @private
*/
private async loadImageShape(container: Container, imageShape: IImageShape): Promise<void> {
const source = imageShape.src;

if (!source) {
throw new Error("Error tsParticles - No image.src");
private async loadImageShape(imageShape: IImageShape): Promise<void> {
if (!this._engine.loadImage) {
throw new Error(`${errorPrefix} image shape not initialized`);
}

try {
const image: IImage = {
source: source,
type: source.substring(source.length - 3),
error: false,
loading: true,
};

this.addImage(container, image);

const imageFunc = imageShape.replaceColor ?? imageShape.replace_color ? downloadSvgImage : loadImage;

await imageFunc(image);
} catch {
throw new Error(`tsParticles error - ${imageShape.src} not found`);
}
await this._engine.loadImage(imageShape.src, imageShape.replaceColor ?? imageShape.replace_color ?? false);
}
}
21 changes: 3 additions & 18 deletions shapes/image/src/Utils.ts
@@ -1,6 +1,6 @@
import type { IHsl, Particle } from "tsparticles-engine";
import { errorPrefix, getStyleFromHsl } from "tsparticles-engine";
import type { IImageShape } from "./IImageShape";
import { getStyleFromHsl } from "tsparticles-engine";

/**
* @category Interfaces
Expand Down Expand Up @@ -32,21 +32,6 @@ export interface IParticleImage {
source: string;
}

/*
* The container image collection
*/
export interface ContainerImage {
/**
* The container id, used key
*/
id: string;

/**
* The image collection of the given container
*/
images: IImage[];
}

/**
* The Particle extension type
*/
Expand Down Expand Up @@ -109,7 +94,7 @@ export async function loadImage(image: IImage): Promise<void> {
image.error = true;
image.loading = false;

console.error(`Error tsParticles - loading image: ${image.source}`);
console.error(`${errorPrefix} loading image: ${image.source}`);

resolve();
});
Expand All @@ -134,7 +119,7 @@ export async function downloadSvgImage(image: IImage): Promise<void> {
const response = await fetch(image.source);

if (!response.ok) {
console.error("Error tsParticles - Image not found");
console.error(`${errorPrefix} Image not found`);

image.error = true;
}
Expand Down

0 comments on commit f735252

Please sign in to comment.