Skip to content

Commit

Permalink
feat: changed particles.js compatibility with a new plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
matteobruni committed Dec 19, 2021
1 parent 88b9dfe commit 4b7c90b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 84 deletions.
33 changes: 33 additions & 0 deletions bundles/pjs/src/IParticlesJS.ts
@@ -0,0 +1,33 @@
import type { Container } from "tsparticles-engine";
import { IParticlesJSOptions } from "./IParticlesJSOptions";

/**
* [[include:pjsMigration.md]]
* @category Particles.js
*/
export interface IParticlesJS {
/**
* Loads the provided options to create a [[Container]] object.
* @deprecated this method is obsolete, please use the new tsParticles.load
* @param tagId the particles container element id
* @param options the options object to initialize the [[Container]]
*/
(tagId: string, options: IParticlesJSOptions): Promise<Container | undefined>;

/**
* Loads the provided json with a GET request.
* The content will be used to create a [[Container]] object.
* @deprecated this method is obsolete, please use the new tsParticles.loadJSON
* @param tagId the particles container element id
* @param pathConfigJson the json path to use in the GET request
* @param callback called after the [[Container]] is loaded and it will be passed as a parameter
*/
load(tagId: string, pathConfigJson: string, callback: (container?: Container) => void): void;

/**
* Adds an additional click handler to all the loaded [[Container]] objects.
* @deprecated this method is obsolete, please use the new tsParticles.setOnClickHandler
* @param callback the function called after the click event is fired
*/
setOnClickHandler(callback: EventListenerOrEventListenerObject): void;
}
21 changes: 9 additions & 12 deletions bundles/pjs/src/IParticlesJSOptions.ts
@@ -1,7 +1,4 @@
import type {
IOptions,
InteractivityDetect
} from "tsparticles-engine";
import type { IOptions, InteractivityDetect } from "tsparticles-engine";
import type { IStroke } from "tsparticles-engine/Options/Interfaces/Particles/IStroke";
import type { IShapeValues } from "tsparticles-engine/Options/Interfaces/Particles/Shape/IShapeValues";
import type { ILinks } from "tsparticles-engine/Options/Interfaces/Particles/Links/ILinks";
Expand Down Expand Up @@ -34,27 +31,27 @@ export type IParticlesJSOptions = IOptions & {
remove: {
particles_nb?: number;
};
}
},
};
};
particles: IParticles & {
line_linked?: ILinks;
move: {
out_mode?: OutMode | keyof typeof OutMode | OutModeAlt;
attract: {
rotateX?: number;
rotateY?: number;
}
};
};
number: {
density: {
value_area?: number;
}
};
};
opacity: {
random?: boolean;
anim?: IOpacityAnimation & {
opacity_min?: number;
}
};
};
shape: {
stroke?: IStroke;
Expand All @@ -65,7 +62,7 @@ export type IParticlesJSOptions = IOptions & {
random?: boolean;
anim?: ISizeAnimation & {
size_min?: number;
}
};
};
}
}
};
};
44 changes: 30 additions & 14 deletions bundles/pjs/src/fixOptions.ts
@@ -1,8 +1,4 @@
import type {
ISourceOptions,
SingleOrMultiple,
RecursivePartial
} from "tsparticles-engine";
import type { ISourceOptions, SingleOrMultiple, RecursivePartial } from "tsparticles-engine";
import type { IStroke } from "tsparticles-engine/Options/Interfaces/Particles/IStroke";
import type { IShapeValues } from "tsparticles-engine/Options/Interfaces/Particles/Shape/IShapeValues";
import type { IOpacityAnimation } from "tsparticles-engine/Options/Interfaces/Particles/Opacity/IOpacityAnimation";
Expand Down Expand Up @@ -43,7 +39,7 @@ const fixOptions = (options: RecursivePartial<IParticlesJSOptions>): ISourceOpti

if (moveOptions.out_mode !== undefined) {
if (!moveOptions.outModes) {
moveOptions.outModes = { default: moveOptions.out_mode }
moveOptions.outModes = { default: moveOptions.out_mode };
} else {
if (typeof moveOptions.outModes === "object") {
moveOptions.outModes.default = moveOptions.out_mode;
Expand All @@ -66,33 +62,47 @@ const fixOptions = (options: RecursivePartial<IParticlesJSOptions>): ISourceOpti
}

if (opacityOptions.anim) {
opacityOptions.animation = deepExtend(opacityOptions.animation, opacityOptions.anim) as IOpacityAnimation;
opacityOptions.animation = deepExtend(
opacityOptions.animation,
opacityOptions.anim
) as IOpacityAnimation;

if (opacityOptions.anim.enable && opacityOptions.anim.opacity_min !== undefined) {
opacityOptions.value = setRangeValue(opacityOptions.value ?? opacityOptions.anim.opacity_min, opacityOptions.anim.opacity_min);
opacityOptions.value = setRangeValue(
opacityOptions.value ?? opacityOptions.anim.opacity_min,
opacityOptions.anim.opacity_min
);
}
}
}

if (particlesOptions?.shape?.stroke) {
particlesOptions.stroke = deepExtend(particlesOptions.stroke, particlesOptions.shape.stroke) as SingleOrMultiple<IStroke>;
particlesOptions.stroke = deepExtend(
particlesOptions.stroke,
particlesOptions.shape.stroke
) as SingleOrMultiple<IStroke>;
}

if (particlesOptions?.shape?.polygon) {
if (!particlesOptions.shape.options) {
particlesOptions.shape.options = {};
}

particlesOptions.shape.options.polygon = deepExtend(particlesOptions.shape.options.polygon, particlesOptions.shape.polygon) as SingleOrMultiple<IShapeValues>;
particlesOptions.shape.options.polygon = deepExtend(
particlesOptions.shape.options.polygon,
particlesOptions.shape.polygon
) as SingleOrMultiple<IShapeValues>;
}

if (particlesOptions?.shape?.image) {
if (!particlesOptions.shape.options) {
particlesOptions.shape.options = {};
}


particlesOptions.shape.options.image = deepExtend(particlesOptions.shape.options.image, particlesOptions.shape.image) as SingleOrMultiple<IShapeValues>;
particlesOptions.shape.options.image = deepExtend(
particlesOptions.shape.options.image,
particlesOptions.shape.image
) as SingleOrMultiple<IShapeValues>;
}

const sizeOptions = particlesOptions.size;
Expand All @@ -106,7 +116,10 @@ const fixOptions = (options: RecursivePartial<IParticlesJSOptions>): ISourceOpti
sizeOptions.animation = deepExtend(sizeOptions.animation, sizeOptions.anim) as ISizeAnimation;

if (sizeOptions.anim.enable && sizeOptions.anim.size_min !== undefined) {
sizeOptions.value = setRangeValue(sizeOptions.value ?? sizeOptions.anim.size_min, sizeOptions.anim.size_min);
sizeOptions.value = setRangeValue(
sizeOptions.value ?? sizeOptions.anim.size_min,
sizeOptions.anim.size_min
);
}
}
}
Expand Down Expand Up @@ -135,7 +148,10 @@ const fixOptions = (options: RecursivePartial<IParticlesJSOptions>): ISourceOpti

if (modesOptions) {
if (modesOptions.grab?.line_linked) {
modesOptions.grab.links = deepExtend(modesOptions.grab.links, modesOptions.grab.line_linked) as IGrabLinks;
modesOptions.grab.links = deepExtend(
modesOptions.grab.links,
modesOptions.grab.line_linked
) as IGrabLinks;
}

if (modesOptions.push?.particles_nb !== undefined) {
Expand Down
77 changes: 19 additions & 58 deletions bundles/pjs/src/index.ts
Expand Up @@ -2,60 +2,25 @@
* [[include:pjsMigration.md]]
* @packageDocumentation
*/
import type {
Container,
Main,
Particle,
RecursivePartial
} from "tsparticles-engine";
import type { Container, Main, Particle, RecursivePartial } from "tsparticles-engine";
import type { IParticlesJSOptions } from "./IParticlesJSOptions";
import { fixOptions } from "./fixOptions";

/**
* [[include:pjsMigration.md]]
* @category Particles.js
*/
export interface IParticlesJS {
/**
* Loads the provided options to create a [[Container]] object.
* @deprecated this method is obsolete, please use the new tsParticles.load
* @param tagId the particles container element id
* @param options the options object to initialize the [[Container]]
*/
(tagId: string, options: IParticlesJSOptions): Promise<Container | undefined>;

/**
* Loads the provided json with a GET request.
* The content will be used to create a [[Container]] object.
* @deprecated this method is obsolete, please use the new tsParticles.loadJSON
* @param tagId the particles container element id
* @param pathConfigJson the json path to use in the GET request
* @param callback called after the [[Container]] is loaded and it will be passed as a parameter
*/
load(tagId: string, pathConfigJson: string, callback: (container?: Container) => void): void;

/**
* Adds an additional click handler to all the loaded [[Container]] objects.
* @deprecated this method is obsolete, please use the new tsParticles.setOnClickHandler
* @param callback the function called after the click event is fired
*/
setOnClickHandler(callback: EventListenerOrEventListenerObject): void;
}

function fetchError(statusCode: number): void {
console.error(`Error tsParticles - fetch status: ${statusCode}`);
console.error("Error tsParticles - File config not found");
}
import type { IParticlesJS } from "./IParticlesJS";
import { ParticlesJSPlugin } from "./particlesJSPlugin";

const initPjs = (main: Main): { particlesJS: IParticlesJS; pJSDom: Container[] } => {
main.addPlugin(new ParticlesJSPlugin());

/**
* Loads the provided options to create a [[Container]] object.
* @deprecated this method is obsolete, please use the new tsParticles.load
* @param tagId the particles container element id
* @param options the options object to initialize the [[Container]]
*/
const particlesJS = (tagId: string, options: RecursivePartial<IParticlesJSOptions>): Promise<Container | undefined> => {
return main.load(tagId, fixOptions(options));
const particlesJS = (
tagId: string,
options: RecursivePartial<IParticlesJSOptions>
): Promise<Container | undefined> => {
return main.load(tagId, options);
};

/**
Expand All @@ -67,19 +32,15 @@ const initPjs = (main: Main): { particlesJS: IParticlesJS; pJSDom: Container[] }
* @param callback called after the [[Container]] is loaded and it will be passed as a parameter
*/
particlesJS.load = (tagId: string, pathConfigJson: string, callback: (container?: Container) => void): void => {
(async () => {
const response = await fetch(pathConfigJson);

if (!response.ok) {
fetchError(response.status);

return;
}

const data = await response.json();

callback(await particlesJS(tagId, data));
})();
main.loadJSON(tagId, pathConfigJson)
.then((container) => {
if (container) {
callback(container);
}
})
.catch(() => {
callback(undefined);
});
};

/**
Expand Down
23 changes: 23 additions & 0 deletions bundles/pjs/src/particlesJSPlugin.ts
@@ -0,0 +1,23 @@
import type { IPlugin, IContainerPlugin } from "tsparticles-engine";
import type { Options } from "tsparticles-engine/Options/Classes/Options";
import { fixOptions } from "./fixOptions";

export class ParticlesJSPlugin implements IPlugin {
readonly id: string;

constructor() {
this.id = "particles-js-plugin";
}

needsPlugin(): boolean {
return true;
}

getPlugin(): IContainerPlugin {
return {};
}

loadOptions(options: Options): void {
fixOptions(options);
}
}

0 comments on commit 4b7c90b

Please sign in to comment.