{"id":15313577,"url":"https://github.com/farazzshaikh/react-three-paper","last_synced_at":"2025-09-03T20:47:38.071Z","repository":{"id":57346353,"uuid":"390035655","full_name":"FarazzShaikh/react-three-paper","owner":"FarazzShaikh","description":"A paper-thin (~800 bytes) and position-aware wrapper for ThreeJS in React.","archived":false,"fork":false,"pushed_at":"2021-08-04T05:13:54.000Z","size":4301,"stargazers_count":87,"open_issues_count":3,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-12T11:52:53.657Z","etag":null,"topics":["component","component-library","npm","react","threejs","wrapper"],"latest_commit_sha":null,"homepage":"https://farazzshaikh.github.io/react-three-paper/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FarazzShaikh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-27T15:31:42.000Z","updated_at":"2025-04-01T23:00:32.000Z","dependencies_parsed_at":"2022-09-18T11:02:44.370Z","dependency_job_id":null,"html_url":"https://github.com/FarazzShaikh/react-three-paper","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2Freact-three-paper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2Freact-three-paper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2Freact-three-paper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2Freact-three-paper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FarazzShaikh","download_url":"https://codeload.github.com/FarazzShaikh/react-three-paper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248990533,"owners_count":21194769,"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","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":["component","component-library","npm","react","threejs","wrapper"],"created_at":"2024-10-01T08:42:21.207Z","updated_at":"2025-04-15T01:38:20.558Z","avatar_url":"https://github.com/FarazzShaikh.png","language":"TypeScript","funding_links":["https://paypal.me/farazzshaikh"],"categories":[],"sub_categories":[],"readme":"\u003cbr /\u003e\n\u003cp align=\"center\"\u003e\n    \n  \u003ch1 align=\"center\"\u003ereact-three-paper\u003c/h1\u003e\n  \n  \u003cp align=\"center\"\u003e\n    A paper-thin (~800 bytes\u003csup\u003e*\u003c/sup\u003e) and position-aware wrapper for ThreeJS in React.\n    \u003cbr /\u003e\n    \u003ca href=\"https://farazzshaikh.github.io/react-three-paper/\"\u003eView Demo\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/FarazzShaikh/react-three-paper/issues/new\"\u003eReport Bug\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/react-three-paper\"\u003e\u003cimg align=\"center\" src=\"https://img.shields.io/npm/v/react-three-paper?color=cc3534\u0026style=for-the-badge\" /\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003cp align=\"center\"\u003e\n    My work is for and funded by the community. If you used this or found this helpful consider supporting me.\n  \u003c/p\u003e\n\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://farazzshaikh.github.io/experiments/examples/support.html?via=ETH\"\u003e\u003cimg align=\"center\" src=\"https://img.shields.io/badge/Ethereum-A6A9AA?style=for-the-badge\u0026logo=ethereum\u0026logoColor=white\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://farazzshaikh.github.io/experiments/examples/support.html?via=BTC\"\u003e\u003cimg align=\"center\" src=\"https://img.shields.io/badge/Bitcoin-000000?style=for-the-badge\u0026logo=bitcoin\u0026logoColor=white\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://farazzshaikh.github.io/experiments/examples/support.html?via=DOGE\"\u003e\u003cimg align=\"center\" src=\"https://img.shields.io/badge/dogecoin-C2A633?style=for-the-badge\u0026logo=dogecoin\u0026logoColor=white\" /\u003e\u003c/a\u003e\n     \u003ca href=\"https://paypal.me/farazzshaikh\"\u003e\u003cimg align=\"center\" src=\"https://img.shields.io/badge/PayPal-00457C?style=for-the-badge\u0026logo=paypal\u0026logoColor=white\" /\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\n\u003cbr /\u003e\n\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"Assets/banner.png\" \u003e\u003c/img\u003e\n    65k particles in React using Three.js via \u003ccode\u003ereact-three-paper\u003c/code\u003e.\n  \u003c/p\u003e\n\n\u003cbr /\u003e\n\n\u003csup\u003e*\u003c/sup\u003e Not including the Source Map and types.\n\n## But why?\n\nI use this component a lot when creating React-based apps. A prominent example is [my blog](https://github.com/FarazzShaikh/blog) and I am kinda sick of rewriting it again and again.\n\nBut other than that, here are some actual uses over using something like `react-three-fiber`:\n\n- Very easily port Vanilla-JS scripts to React.\n- No special declarative syntax to learn.\n- Separate your UI logic from your core ThreeJS app.\n- It is **TINY**.\n\nIn theory, all you have to do to convert Vanilla-JS examples to React ones via this library is wrap them in a `main()` function, tell ThreeJS to render on the given canvas, and return the render loop as a function. [Read more.](#your-script)\n\n## Position aware...what?\n\nYes, the canvas knows when it is out of the viewport and will pause your render loop. It will resume it when it is back in the viewport. This is **TREMENDOUSLY** helpful with performance. \n\nFor example, when creating long pages where you have multiple ThreeJS canvas components coming in and going out of the viewport.\n\nYou can also tap these events and define custom behavior.\n\n## Installation\n\n```bash\nnpm install react-three-paper\n# or\nyarn add react-three-paper\n```\n\n**`react-three-paper` requires `react \u003e=16.8.0`**\n\n```bash\nnpm install react\n# or\nyarn add react\n```\n\n## Usage\n\nImport the `Paper` component and use it like this:\n\n```jsx\nimport { Paper } from \"paper\";\nimport { main } from \"./main.js\"; // 👈 Your ThreeJS script\n\nexport default function App() {\n    return (\n        \u003cPaper \n            script={main} // 👈 Pass it in here\n        /\u003e\n    )\n}\n```\n\n### Your script\n\nThe `script` prop accepts a function, here is how that function should look.\n\n```js\nexport async function main(canvas) {\n    //...Do ThreeJS stuff\n    const renderer = new THREE.WebGLRenderer({\n        canvas: canvas, // 👈 Use canvas as the ThreeJS canvas\n    });\n\n    // 👇 Use canavs dimentions insted of window\n    const aspectRatio = canvas.clientWidth / canvas.clientHeight;\n    renderer.setSize(canvas.clientWidth, canvas.clientHeight);\n\n    function render() {...} //...Render loop without requestAnimationFrame()\n    function cleanup() {...} //...Any cleanup youd like (optional)\n\n    return { render, cleanup }\n}\n```\n\nEssentially, a function that receives a `canvas` element (that is used as the ThreeJS canvas) and returns a promise which resolves to a couple of functions.\n\n- `render`: Your render loop without `requestAnimationFrame` as this is handled by `react-three-paper`.\n- `cleanup`: An optional cleanup function without `cancleAnimationFrame`.\n\n**Pass this function directly into the `script` prop.**\n\n### Example\n\nAn example app can be found within the `example` directory. It is also hosted [here](https://farazzshaikh.github.io/react-three-paper/example). See:\n\n- `example/src/App.js`: For `Paper` component usage. \n- `example/src/three/main.js`: For an example of how to format your main function.\n\n### Advanced Usage\n\nHere are some other props that `react-three-paper` provides.\n\n```jsx\nimport { Paper } from \"../../build/index\";\nimport { main } from \"./three/main.js\";\n\nexport default function App() {\n    return (\n        \u003cPaper \n            script={main}\n            style={{...}} // 👈 CSS styles for the underlying \u003ccanvas\u003e\n\n            // 👇 Events\n            onExit={(entry, ID) =\u003e {...}} // 👈 Fired when canvas exits the viewport\n            onEntry={(entry, ID) =\u003e {...}} // 👈 Fired when canvas enters the viewport\n            onError={(error, ID) =\u003e {...}} // 👈 Fired when there is a error\n        /\u003e\n    )\n}\n```\n\n| Prop | Required | Type | Discription | Default |\n|-|-|-|-|-|\n| script | Yes | [`tPaperScript`](#tpaperscript) | Your ThreeJS script | No default behaviour |\n| style | No | [`React.CSSProperties`](https://reactjs.org/docs/faq-styling.html) | CSS  styles for the underlying `\u003ccanvas\u003e` | Makes the canvas dimensions 100% of its container. |\n| onExit | No | [`tPaperPositionEvent`](#tpaperpositionevent) | Fired when canvas exits the viewport | Stops the render loop when canvas exits viewport. |\n| onEntry | No | [`tPaperPositionEvent`](#tpaperpositionevent) | Fired when canvas enters the viewport | Start the render loop when canvas enters viewport. |\n| onError | No | [`tPaperErrorEvent`](#tpapererrorevent) | Fired when there is a error | Logs the error and stops the render loop. |\n\n**Note: Default behaviour cannot be overwritten, only extended.**\n\n### Types\n\n#### `tPaperRenderLoop`\n\nA function that receives current time. By default, it is run every frame.\n\n```js\n(time?: number) =\u003e void\n```\n\n#### `tPaperCleanup`\n\nAn optional cleanup function.\n\n```js\n() =\u003e void\n```\n\n#### `tPaperScriptReturn`\n\nThe return value of the function is passed to the `script` prop.\n\n```ts\ntype tPaperScriptReturn = {\n  render: tPaperRenderLoop;\n  cleanup: tPaperCleanup;\n};\n```\n\n#### `tPaperScript`\n\nA function that recieves a HTML canvas and returns a promise that resolves to [tPaperScriptReturn](#tpaperscriptreturn) (your render loop).\n\n```js\n(canvas?: HTMLCanvasElement) =\u003e Promise\u003ctPaperScriptReturn\u003e\n```\n\n#### `tPaperPositionEvent`\n\nA function that receives the Intersection observer event's entry object. Use this to have custom behavior when the canvas goes out of and comes into the viewport. This function is called when the canvas enters or leaves the viewport.\n\n```js\n(entry: IntersectionObserverEntry) =\u003e void;\n```\n\n#### `tPaperErrorEvent`\n\nThis function is called when an error occurs. It receives the error.\n\n```js\n(error: Error) =\u003e void;\n```\n\nThis module provides TypeScript type definitions.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarazzshaikh%2Freact-three-paper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffarazzshaikh%2Freact-three-paper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarazzshaikh%2Freact-three-paper/lists"}