├── .github
├── stale.yml
└── workflows
│ └── node.js.yml
├── .gitignore
├── .idea
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── react-tsparticles.iml
└── workspace.xml
├── .npmignore
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── package.json
├── src
├── Particles.tsx
└── index.ts
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 40
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | - help wanted
10 | # Label to use when marking an issue as stale
11 | staleLabel: stale
12 | # Comment to post when marking an issue as stale. Set to `false` to disable
13 | markComment: >
14 | This issue has been automatically marked as stale because it has not had
15 | recent activity. It will be closed if no further activity occurs. Thank you
16 | for your contributions.
17 | # Comment to post when closing a stale issue. Set to `false` to disable
18 | closeComment: false
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [10.x, 12.x, 14.x]
20 |
21 | steps:
22 | - uses: actions/checkout@v2
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v1
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - run: yarn install
28 | - run: yarn compile:production --if-present
29 | # - run: yarn test
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | # Typings folder
40 | typings
41 |
42 | .DS_Store
43 |
44 | lib/particles.js.map
45 |
46 | # Visual Studio Code
47 | .vscode
48 | /.idea
49 |
50 | /cjs
51 | /umd
52 | report.html
53 |
54 | package-lock.json
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/react-tsparticles.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | img
2 | src
3 | tsconfig.json
4 | typings.json
5 | webpack.config.js
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Matteo Bruni
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This Repository has been moved!
2 |
3 | This repository is now part of **https://github.com/matteobruni/tsparticles**, this repository will be archived because it's included in the main package **tsParticles**
4 |
5 | ---
6 |
7 | ## tsParticles - React Component 
8 |
9 | tsParticles React component, using [tsParticles](https://github.com/matteobruni/tsparticles).
10 |
11 | Checkout the [demo page](https://particles.matteobruni.it).
12 |
13 | ---
14 |
15 | ## Installation
16 |
17 | `npm install react-tsparticles`
18 |
19 | or
20 |
21 | `yarn add react-tsparticles`
22 |
23 | ## How to use
24 |
25 | ### Code
26 |
27 | Example:
28 |
29 | ```javascript
30 | import Particles from 'react-tsparticles';
31 |
32 | class App extends Component{
33 |
34 | render(){
35 | return (
36 |
37 | );
38 | };
39 |
40 | }
41 |
42 | ```
43 |
44 | ### Props
45 |
46 | | Prop | Type | Definition |
47 | | --- | --- | --- |
48 | | width | string | The width of the canvas. |
49 | | height | string | The height of the canvas. |
50 | | params | object | The parameters of the particles instance. |
51 | | style | object | The style of the canvas element. |
52 | | className | string | The class name of the canvas wrapper. |
53 | | canvasClassName | string | the class name of the canvas. |
54 | | container | object | The instance of the [particles container](https://github.com/matteobruni/tsparticles/wiki/Particles-Container-class) |
55 |
56 | Find your parameters configuration [here](https://particles.matteobruni.it).
57 |
58 | ### Errors
59 |
60 | If you have typescript errors `tsParticles` uses TypeScript `3.9.3` so try installing at least 3.8 for `import type` syntax.
61 |
62 | ## Need More Help?
63 |
64 | [](https://join.slack.com/t/tsparticles/shared_invite/enQtOTcxNTQxNjQ4NzkxLWE2MTZhZWExMWRmOWI5MTMxNjczOGE1Yjk0MjViYjdkYTUzODM3OTc5MGQ5MjFlODc4MzE0N2Q1OWQxZDc1YzI)
65 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for react-tsparticles v1.15.0
2 | // Project: https://github.com/matteobruni/react-tsparticles
3 | // Definitions by: Matteo Bruni
4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5 |
6 | ///
7 | import { ComponentClass } from "react";
8 | import { Container } from "tsparticles/dist/Core/Container";
9 | import type { IOptions } from "tsparticles/dist/Options/Interfaces/IOptions";
10 | import type { RecursivePartial } from "tsparticles/dist/Types/RecursivePartial";
11 | import { IPolygonMaskOptions } from "tsparticles/dist/Plugins/PolygonMask/PolygonMaskPlugin";
12 | import { IAbsorberOptions } from "tsparticles/dist/Plugins/Absorbers/AbsorbersPlugin";
13 | import { IEmitterOptions } from "tsparticles/dist/Plugins/Emitters/EmittersPlugin";
14 |
15 | export type IParticlesParams = RecursivePartial;
16 |
17 | export * from "tsparticles/dist/Enums";
18 |
19 | export interface ParticlesProps {
20 | width?: string;
21 | height?: string;
22 | params?: IParticlesParams;
23 | style?: any;
24 | className?: string;
25 | canvasClassName?: string;
26 | particlesRef?: React.RefObject;
27 | }
28 |
29 | type Particles = ComponentClass;
30 |
31 | declare const Particles: Particles;
32 |
33 | export default Particles;
34 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const ReactParticles = require("./cjs/particles");
2 |
3 | for (let key in ReactParticles) {
4 | ReactParticles.default[key] = ReactParticles[key];
5 | }
6 |
7 | module.exports = ReactParticles.default;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-tsparticles",
3 | "version": "1.15.1",
4 | "description": "Reactified tsParticles",
5 | "main": "index.js",
6 | "unpkg": "umd/particles.js",
7 | "jsdelivr": "umd/particles.js",
8 | "types": "index.d.ts",
9 | "scripts": {
10 | "compile": "webpack",
11 | "compile:production": "cross-env NODE_ENV=production webpack"
12 | },
13 | "repository": {
14 | "url": "https://github.com/matteobruni/react-tsparticles",
15 | "type": "git"
16 | },
17 | "author": "Matteo Bruni (https://www.matteobruni.it)",
18 | "license": "MIT",
19 | "devDependencies": {
20 | "@babel/core": "^7.0.0",
21 | "@babel/preset-env": "^7.0.0",
22 | "@types/lodash": "^4.14.123",
23 | "@types/node": "^14.0.5",
24 | "@types/react": "^16.0.8",
25 | "babel-loader": "^8.0.0",
26 | "cross-env": "^7.0.2",
27 | "react-dom": "^16.0.0",
28 | "ts-loader": "^7.0.5",
29 | "ts-node": "^8.10.1",
30 | "typescript": "^3.8.3",
31 | "webpack": "^4.16.5",
32 | "webpack-bundle-analyzer": "^3.3.2",
33 | "webpack-cli": "^3.1.0",
34 | "webpack-node-externals": "^1.5.4"
35 | },
36 | "dependencies": {
37 | "lodash": "^4.17.15",
38 | "tsparticles": "^1.15.1"
39 | },
40 | "peerDependencies": {
41 | "react": "^16.0.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Particles.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Component } from "react";
3 | import type { IOptions } from "tsparticles/dist/Options/Interfaces/IOptions";
4 | import { Container } from "tsparticles/dist/Core/Container";
5 | import type { RecursivePartial } from "tsparticles/dist/Types/RecursivePartial";
6 | import { tsParticles } from "tsparticles";
7 | import { isEqual } from "lodash";
8 | import { IPolygonMaskOptions } from "tsparticles/dist/Plugins/PolygonMask/PolygonMaskPlugin";
9 | import { IAbsorberOptions } from "tsparticles/dist/Plugins/Absorbers/AbsorbersPlugin";
10 | import { IEmitterOptions } from "tsparticles/dist/Plugins/Emitters/EmittersPlugin";
11 |
12 | export interface ParticlesProps {
13 | id: string;
14 | width: string;
15 | height: string;
16 | params: RecursivePartial;
17 | style: any;
18 | className?: string;
19 | canvasClassName?: string;
20 | container?: React.RefObject;
21 | }
22 |
23 | export interface ParticlesState {
24 | canvas?: HTMLCanvasElement;
25 | library?: Container;
26 | }
27 |
28 | export default class Particles extends Component {
30 | public static defaultProps: ParticlesProps = {
31 | width: "100%",
32 | height: "100%",
33 | params: {},
34 | style: {},
35 | id: "tsparticles"
36 | };
37 |
38 | constructor(props: ParticlesProps) {
39 | super(props);
40 | this.state = {
41 | canvas: undefined,
42 | library: undefined
43 | };
44 | this.loadCanvas = this.loadCanvas.bind(this);
45 | }
46 |
47 | private buildParticlesLibrary(
48 | tagId: string,
49 | params?: RecursivePartial
50 | ) {
51 | try {
52 | if (window === undefined) return null;
53 | } catch {
54 | return null;
55 | } // SSR
56 |
57 | tsParticles.init();
58 |
59 | const container = new Container(tagId, params);
60 |
61 | if (this.props.container) {
62 | (this.props.container as React.MutableRefObject).current = container;
63 | }
64 |
65 | return container;
66 | }
67 |
68 | private refresh(props: Readonly): void {
69 | const { canvas } = this.state;
70 | if (canvas) {
71 | this.destroy();
72 | this.setState(
73 | {
74 | library: this.buildParticlesLibrary(props.id, props.params)
75 | },
76 | () => {
77 | this.loadCanvas(canvas);
78 | }
79 | );
80 | }
81 | }
82 |
83 | destroy() {
84 | if (this.state.library) {
85 | this.state.library.destroy();
86 | }
87 | }
88 |
89 | loadCanvas(canvas: HTMLCanvasElement) {
90 | if (canvas) {
91 | this.setState(
92 | {
93 | canvas
94 | },
95 | () => {
96 | const { library } = this.state;
97 |
98 | if (!library) {
99 | return;
100 | }
101 |
102 | library.canvas.loadCanvas(canvas);
103 | library.start();
104 | }
105 | );
106 | }
107 | }
108 |
109 | shouldComponentUpdate(nextProps: Readonly) {
110 | return !isEqual(nextProps, this.props);
111 | }
112 |
113 | componentDidUpdate() {
114 | this.refresh(this.props);
115 | }
116 |
117 | forceUpdate() {
118 | this.refresh(this.props);
119 | super.forceUpdate();
120 | }
121 |
122 | componentDidMount() {
123 | this.setState({
124 | library: this.buildParticlesLibrary(this.props.id, this.props.params)
125 | });
126 | }
127 |
128 | componentWillUnmount() {
129 | this.destroy();
130 | this.setState({
131 | library: undefined
132 | });
133 | }
134 |
135 | render() {
136 | let { width, height, className, canvasClassName, id } = this.props;
137 | return (
138 |
139 |
148 |
149 | );
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import Particles from "./Particles";
2 |
3 | export * from "tsparticles/dist/Enums";
4 |
5 | export default Particles;
6 | export { Particles };
7 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "noImplicitAny": true,
5 | "module": "commonjs",
6 | "target": "es6",
7 | "jsx": "react",
8 | "removeComments": true,
9 | "esModuleInterop": true
10 | },
11 | "files": [
12 | "./src/index.ts"
13 | ]
14 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
3 |
4 | const production = process.env.NODE_ENV === "production";
5 |
6 | const plugins = (production ?
7 | [
8 | new webpack.optimize.OccurrenceOrderPlugin(),
9 | new webpack.DefinePlugin({
10 | 'process.env': {
11 | 'NODE_ENV': JSON.stringify('production')
12 | }
13 | })
14 | ] :
15 | []).concat([
16 | new BundleAnalyzerPlugin({
17 | openAnalyzer: false,
18 | analyzerMode: "static",
19 | reportFilename: "../report.html"
20 | })
21 | ]);
22 |
23 | const typescriptLoader = {
24 | test: /\.tsx?$/,
25 | exclude: /node_modules/,
26 | use: [
27 | {
28 | loader: 'babel-loader',
29 | options: {
30 | presets: [ '@babel/preset-env' ]
31 | }
32 | }, {
33 | loader: 'ts-loader'
34 | }
35 | ]
36 | };
37 |
38 | const jsonLoader = {
39 | test: /\.json$/,
40 | use: 'json-loader'
41 | };
42 |
43 | const rules = [
44 | typescriptLoader,
45 | jsonLoader
46 | ];
47 |
48 | const getExternals = (target = 'cjs') => {
49 | const baseExternals = [
50 | {
51 | react: {
52 | commonjs: "react",
53 | commonjs2: "react",
54 | amd: "react",
55 | root: "React"
56 | }
57 | }
58 | ];
59 |
60 | baseExternals.push(/ts[pP]articles/);
61 |
62 | if (target === 'cjs') {
63 | baseExternals.push(/lodash/);
64 | }
65 | return baseExternals;
66 | };
67 |
68 | const getLibraryTarget = (target = 'cjs') => {
69 | let libraryTarget = '';
70 | switch (target) {
71 | case 'umd':
72 | libraryTarget = 'umd';
73 | break;
74 | case 'cjs':
75 | libraryTarget = 'commonjs';
76 | break;
77 | default:
78 | libraryTarget = target;
79 | }
80 | return libraryTarget;
81 | }
82 |
83 | const getOutput = (target = 'cjs') => {
84 | const baseOutput = {
85 | path: __dirname + `/${target}`,
86 | filename: "particles.js",
87 | libraryTarget: getLibraryTarget(target)
88 | };
89 |
90 | if (target === 'umd') {
91 | baseOutput.library = 'Particles';
92 | baseOutput.globalObject = 'this';
93 | }
94 |
95 | return baseOutput;
96 | }
97 |
98 | const getConfig = (target = 'cjs') => {
99 |
100 |
101 | return {
102 | mode: production ? 'production' : 'development',
103 | context: __dirname,
104 | devtool: production ? false : "source-map-loader",
105 | resolve: {
106 | extensions: [ ".ts", ".tsx", ".js" ]
107 | },
108 | entry: "./src/index.ts",
109 | output: getOutput(target),
110 | target: 'web',
111 | module: {
112 | rules
113 | },
114 | externals: getExternals(target),
115 | plugins
116 | }
117 | };
118 |
119 | module.exports = [ getConfig('cjs'), getConfig('umd') ];
--------------------------------------------------------------------------------