├── .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 | 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 | 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 ![Node.js CI](https://github.com/matteobruni/react-tsparticles/workflows/Node.js%20CI/badge.svg) 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 | [![Slack](https://cdn.matteobruni.it/images/slack.png)](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') ]; --------------------------------------------------------------------------------