{"id":16323590,"url":"https://github.com/im-rises/nbody-simulator-react-p5","last_synced_at":"2025-07-31T15:34:14.140Z","repository":{"id":165045175,"uuid":"640391545","full_name":"Im-Rises/nbody-simulator-react-p5","owner":"Im-Rises","description":"N-Body simulation package made in React using bruteforce method","archived":false,"fork":false,"pushed_at":"2023-09-28T02:11:23.000Z","size":515,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-04T10:56:02.529Z","etag":null,"topics":["canvas","gravity","javascript","n-body","nbody","nbody-simulation","package","react","simulation","typescript"],"latest_commit_sha":null,"homepage":"https://im-rises.github.io/nbody-simulator-react-p5-website/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Im-Rises.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-05-13T23:40:49.000Z","updated_at":"2023-09-28T03:41:30.000Z","dependencies_parsed_at":"2023-10-01T04:00:29.891Z","dependency_job_id":null,"html_url":"https://github.com/Im-Rises/nbody-simulator-react-p5","commit_stats":{"total_commits":37,"total_committers":2,"mean_commits":18.5,"dds":"0.027027027027026973","last_synced_commit":"d99c0bfa050ed99a992271d02e5b1826b1b46495"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Im-Rises/nbody-simulator-react-p5","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Im-Rises%2Fnbody-simulator-react-p5","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Im-Rises%2Fnbody-simulator-react-p5/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Im-Rises%2Fnbody-simulator-react-p5/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Im-Rises%2Fnbody-simulator-react-p5/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Im-Rises","download_url":"https://codeload.github.com/Im-Rises/nbody-simulator-react-p5/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Im-Rises%2Fnbody-simulator-react-p5/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268065741,"owners_count":24190182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canvas","gravity","javascript","n-body","nbody","nbody-simulation","package","react","simulation","typescript"],"created_at":"2024-10-10T22:55:11.895Z","updated_at":"2025-07-31T15:34:14.078Z","avatar_url":"https://github.com/Im-Rises.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nbody-simulator-react-p5\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/React-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB\" alt=\"reactLogo\" style=\"height:50px;\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/JavaScript-323330?style=for-the-badge\u0026logo=javascript\u0026logoColor=F7DF1E\" alt=\"javascriptLogo\" style=\"height:50px;\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white\" alt=\"typescriptLogo\" style=\"height:50px;\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Sass-CC6699?style=for-the-badge\u0026logo=sass\u0026logoColor=white\" alt=\"scssLogo\" style=\"height:50px;\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/CSS-239120?\u0026style=for-the-badge\u0026logo=css3\u0026logoColor=white\" alt=\"cssLogo\" style=\"height:50px;\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/p5%20js-ED225D?style=for-the-badge\u0026logo=p5dotjs\u0026logoColor=white\" alt=\"cssLogo\" style=\"height:50px;\"\u003e\n\u003c/p\u003e\n\n## Description\n\nThis is an n-body simulator package made with React Typescript and p5.js.\n\nBodies are attracted to each other by the gravitational force and by a center attractor which is defiend by clicking on\nthe canvas.\n\n## 🚀🚀[You can try it online from your browser](https://im-rises.github.io/nbody-simulator-react-p5-website/) 🚀🚀\n\nIt works on desktop and mobile as well with different controls (check the `controls` section).\n\n## 🚀🚀 [The package is available on npm](https://www.npmjs.com/package/nbody-simulator-react-p5) 🚀🚀\n\n\u003e **Note**  \n\u003e I also made a C++ version for WebGL2 using OpenGL ES 3.0. You can check it\n\u003e out [here](https://github.com/Im-Rises/nbody-simulator-webgl).\n\n\u003e **Note**  \n\u003e I also made a version using Barnes-Hut algorithm. You can check it\n\u003e out [here](https://github.com/Im-Rises/nbody-simulator-barnes-hut-react-p5).\n\n## Screenshots\n\n| Screenshot 1                                                                                                              | Screenshot 2                                                                                                              | \n|---------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|\n| ![Screenshot1](https://github.com/Im-Rises/nbody-simulator-react-p5/assets/59691442/59dbae4f-bfe8-4923-ad06-cc6abf07db13) | ![Screenshot2](https://github.com/Im-Rises/nbody-simulator-react-p5/assets/59691442/ec62857c-fb48-4049-8a8c-32a0ccc5fa91) |\n\n## Demo video\n\nhttps://github.com/Im-Rises/nbody-simulator-react-p5/assets/59691442/20bc593e-7bd0-4d60-9470-a8caed1a45bd\n\n## Package installation\n\nTo install it type the following command in your terminal:\n\n```bash\nnpm install nbody-simulator-react-p5\n```\n\nThen you can import it in your project with:\n\n```bash\nimport NbodySimulator from 'nbody-simulator-react-p5'\n```\n\n## Usage\n\nTo use it you can simply add the component in your project like this:\n\n```tsx\nimport React, {useEffect, useState} from 'react';\nimport NbodySimulator from 'nbody-simulator-react-p5';\nimport './App.css';\n\nconst App: React.FC = () =\u003e {\n    const [isLoaded, setIsLoaded] = useState(false);\n    const divRef = React.useRef \u003cHTMLDivElement\u003e(null);\n\n    useEffect(() =\u003e {\n        if (divRef.current) {\n            setIsLoaded(true);\n        }\n    }, [divRef]);\n\n    return (\n        \u003cdiv className='App'\u003e\n            \u003cdiv ref={divRef}\u003e\n                {isLoaded ? (\n                    \u003cdiv className={'nbody-sim-canvas'}\u003e\n                        \u003cNbodySimulator\n                            parentRef={divRef}\n                        /\u003e\n                    \u003c/div\u003e\n                ) : (\n                    \u003cp className={'wait-sim-canvas'}\u003eLoading...\u003c/p\u003e\n                )}\n            \u003c/div\u003e\n        \u003c/div\u003e\n    );\n};\n\nexport default App;\n```\n\nor you can change all the settings like this:\n\n```tsx\nimport React, {useEffect, useState} from 'react';\nimport NbodySimulator from 'nbody-simulator-react-p5';\nimport './App.css';\n\nconst App: React.FC = () =\u003e {\n    const [isLoaded, setIsLoaded] = useState(false);\n    const divRef = React.useRef \u003cHTMLDivElement\u003e(null);\n\n    useEffect(() =\u003e {\n        if (divRef.current) {\n            setIsLoaded(true);\n        }\n    }, [divRef]);\n\n    return (\n        \u003cdiv className='App'\u003e\n            \u003cdiv ref={divRef}\u003e\n                {isLoaded ? (\n                    \u003cdiv className={'nbody-sim-canvas'}\u003e\n                        \u003cNbodySimulator\n                            parentRef={divRef}\n                            nbodyCountMobile={100}\n                            nbodyCountComputer={50}\n                            frameRate={60}\n                            fixedUpdate={60}\n                            minSpawnRadius={3}\n                            maxSpawnRadius={4}\n                            minSpawnVelocity={5}\n                            maxSpawnVelocity={10}\n                            gravitationalConstant={1}\n                            particlesMass={400}\n                            softening={4}\n                            friction={0.99}\n                            centerAttractorMass={10000}\n                            pixelsPerMeter={100}\n                            initColor={[0, 255, 255, 200]}\n                            finalColor={[255, 0, 255, 200]}\n                            maxForceMagColor={30}\n                            backColor={[0, 0, 0, 255]}\n                        /\u003e\n                    \u003c/div\u003e\n                ) : (\n                    \u003cp className={'wait-sim-canvas'}\u003eLoading...\u003c/p\u003e\n                )}\n            \u003c/div\u003e\n        \u003c/div\u003e\n    );\n};\n\nexport default App;\n```\n\nThe component takes 1 to 16 props:\n\n- `parentRef` - a reference to the parent div of the canvas. It is used to get the size of the canvas.\n- `particleCountMobile` - the number of particles on mobile devices.\n- `particleCountComputer` - the number of particles on desktop devices.\n- `fixedUpdate` - the number of fixed updates per second.\n- `frameRate` - the number of frames per second.\n- `minSpawnRadius` - the minimum radius of the particles when they are spawned.\n- `maxSpawnRadius` - the maximum radius of the particles when they are spawned.\n- `minSpawnVelocity` - the minimum velocity of the particles when they are spawned.\n- `maxSpawnVelocity` - the maximum velocity of the particles when they are spawned.\n- `gravitationalConstant` - the gravitational constant of the simulation.\n- `particlesMass` - the mass of the particles.\n- `attractorMass` - the mass of the attractor.\n- `friction` - the friction of the particles.\n- `softening` - the softening parameter of the gravitational force calculation.\n- `pixelsPerMeter` - the number of pixels to represent 1 meter.\n- `initColor` - the initial color of the particles (in RGB).\n- `finalColor` - the final color of the particles (in RGB).\n- `maxVelocityMagColor` - the maximum velocity of the particles at which the color will be the final color.\n- `backColor` - the background color of the canvas (in RGB).\n\nThis will create a canvas with 3000 particles on desktop and 1000 on mobile in fullscreen which will be resized\nwhen the window is resized.\n\n\u003e **Note**\n\u003e The default values of the props are the same as the ones in the example above.\n\nYou can find the complete example of the project in the GitHub\nrepository [here](https://im-rises.github.io/nbody-simulator-react-p5-website).\n\n\u003e **Note**  \n\u003e Be sure to do like in the example, the parent div of the canvas must be set before the p5 canvas is created.\n\n## Calculations\n\nThe calculations are made with the [Newtonian mechanics](https://en.wikipedia.org/wiki/Newtonian_mechanics) equations.\n\n$$ F = G \\frac{m_1 m_2}{r^2} $$\n\nTo prevent to have a division by zero when the particles are too close to each other, we add a softening parameter\n$\\epsilon$.\n\nOne of the real force calculation with softening could be like this:\n\n$$ F = G \\frac{m_1 m_2}{(r^2 + \\epsilon^2)^\\frac{3}{2}} $$\n\nWhere G is the gravitational constant, m1 and m2 are the masses of the particles, r is the distance between the\nparticles and d is the softening parameter.\n\n## Known issues\n\n\u003e **Warning**  \n\u003e The React-p5 dependency may have issues with the index.js file.\n\n```js\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(\n    \u003cReact.StrictMode\u003e\n        \u003cApp/\u003e\n    \u003c/React.StrictMode\u003e\n);\n\n```\n\nPlease delete the React.StrictMode tag in the index.js file and replace it with the code below.\n\n```js\nconst root = ReactDOM.createRoot(document.getElementById('root'));\nroot.render(\n    \u003c\u003e\n        \u003cApp/\u003e\n    \u003c/\u003e\n);\n```\n\n## GitHub Actions\n\n[//]: # ([![pages-build-deployment]\u0026#40;https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/pages/pages-build-deployment/badge.svg\u0026#41;]\u0026#40;https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/pages/pages-build-deployment\u0026#41;)\n[![Node.js CI](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/node.js.yml)\n[![ESLint](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/eslint.yml/badge.svg?branch=main)](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/eslint.yml)\n[![CodeQL](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/codeql.yml)\n[![Node.js Package](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/Im-Rises/nbody-simulator-react-p5/actions/workflows/npm-publish.yml)\n\nThe project is set up to run the following actions:\n\n[//]: # (- pages-build-deployment : Builds the website and deploys it to GitHub Pages.)\n\n- node.js.yml : Runs the tests for the Node.js project.\n- eslint.yml : Runs the ESLint linter on the project.\n- codeql.yml : Runs the CodeQL linter on the project.\n- npm-publish.yml : Publishes the package to npm.\n\n## Libraries\n\nReact:  \n\u003chttps://reactjs.org/docs/getting-started.html\u003e\n\nXo:  \n\u003chttps://github.com/xojs/xo\u003e  \n\u003chttps://github.com/xojs/eslint-config-xo-react\u003e  \n\u003chttps://github.com/xojs/eslint-config-xo-typescript\u003e\n\nESLint:  \n\u003chttps://eslint.org/docs/latest/user-guide/getting-started\u003e\n\nGitHub gh-pages:  \n\u003chttps://github.com/gitname/react-gh-pages\u003e\n\nP5.js:  \n\u003chttps://p5js.org/\u003e  \n\u003chttps://www.npmjs.com/package/react-p5\u003e\n\nreact-device-detect:  \n\u003chttps://www.npmjs.com/package/react-device-detect\u003e\n\n## Documentation\n\nThe Coding Challenge (math and physics):  \n\u003chttps://www.youtube.com/watch?v=OAcXnzRNiCY\u003e  \n\u003chttps://www.youtube.com/watch?v=GjbKsOkN1Oc\u003e\n\nP5.js:  \n\u003chttps://p5js.org/\u003e\n\nP5.js React:  \n\u003chttps://www.npmjs.com/package/react-p5\u003e\n\nWikipedia Barnes-Hut simulation:  \n\u003chttps://en.wikipedia.org/wiki/Barnes–Hut_simulation\u003e\n\n## Links\n\nCheck the source code\non [![github](https://user-images.githubusercontent.com/59691442/223556058-6244e346-8117-43cd-97c6-bf68611bf286.svg)](https://github.com/im-rises/nbody-simulator-react-p5)\n\nCheck the demo\non [![github](https://user-images.githubusercontent.com/59691442/223556058-6244e346-8117-43cd-97c6-bf68611bf286.svg)](https://github.com/im-rises/nbody-simulator-react-p5-website)\n\nCheck the package\non [![npm](https://user-images.githubusercontent.com/59691442/223556055-4e9ef014-79d4-4136-ac07-b837b49066c8.svg)](https://www.npmjs.com/package/nbody-simulator-react-p5)\n\n## Contributors\n\nQuentin MOREL :\n\n- @Im-Rises\n- \u003chttps://github.com/Im-Rises\u003e\n\n[![GitHub contributors](https://contrib.rocks/image?repo=Im-Rises/nbody-simulator-react-p5)](https://github.com/Im-Rises/nbody-simulator-react-p5/graphs/contributors)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fim-rises%2Fnbody-simulator-react-p5","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fim-rises%2Fnbody-simulator-react-p5","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fim-rises%2Fnbody-simulator-react-p5/lists"}