From 45413dc262b67e6b5aa1b1545922d28029dac57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Sejourn=C3=A9?= <60986348+Ahlecss@users.noreply.github.com> Date: Thu, 27 Oct 2022 16:11:49 +0200 Subject: [PATCH 1/2] docs(links): Add Threejs Journey link to recommended documentation --- docs/getting-started/introduction.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/getting-started/introduction.mdx b/docs/getting-started/introduction.mdx index ad95310bad..9a94d687dc 100644 --- a/docs/getting-started/introduction.mdx +++ b/docs/getting-started/introduction.mdx @@ -189,6 +189,7 @@ You need to be versed in both React and `three.js` before rushing into this. If - [three.js-docs](https://threejs.org/docs) - [three.js-examples](https://threejs.org/examples) - [three.js-fundamentals](https://threejs.org/manual/#en/fundamentals) +- [three.js-journey](https://threejs-journey.com) - [Discover three.js](https://discoverthreejs.com) - [Do's and don'ts](https://discoverthreejs.com/tips-and-tricks) for performance and best practices - [react-three-fiber alligator.io tutorial](https://alligator.io/react/react-with-threejs) by [@dghez\_](https://twitter.com/dghez_) From b0ec7eda71bb050914187a074165494682d6a012 Mon Sep 17 00:00:00 2001 From: Cody Bennett <23324155+CodyJasonBennett@users.noreply.github.com> Date: Fri, 28 Oct 2022 07:06:27 -0500 Subject: [PATCH 2/2] chore: add link to readme --- packages/fiber/readme.md | 180 +++++++++++++++++++++++++-------------- readme.md | 1 + 2 files changed, 115 insertions(+), 66 deletions(-) diff --git a/packages/fiber/readme.md b/packages/fiber/readme.md index 35db6e9b07..e2ac9e061e 100644 --- a/packages/fiber/readme.md +++ b/packages/fiber/readme.md @@ -10,25 +10,23 @@ react-three-fiber is a React renderer for threejs. +Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can participate in React's ecosystem. + ```bash npm install three @react-three/fiber ``` -### Why? - -Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can tap into React's ecosystem. - #### Does it have limitations? -None. Everything that works in threejs will work here without exception. +None. Everything that works in Threejs will work here without exception. -#### Can it keep up with frequent updates to threejs? +#### Is it slower than plain Threejs? -Yes, because it merely expresses threejs in JSX: `` becomes `new THREE.Mesh()`, and that happens dynamically. There is no hard dependency on a particular threejs version, it does not wrap or duplicate a single threejs class. +No. There is no overhead. Components render outside of React. It outperforms Threejs in scale due to Reacts scheduling abilities. -#### Is it slower than plain threejs? +#### Can it keep up with frequent feature updates to Threejs? -There is no additional overhead. Components participate in the renderloop outside of React. +Yes. It merely expresses Threejs in JSX: `` becomes `new THREE.Mesh()`, and that happens dynamically. If a new Threejs version adds, removes or changes features, it will be available to you instantly without depending on updates to this library. ### What does it look like? @@ -45,80 +43,127 @@ There is no additional overhead. Components participate in the renderloop outsid -#### Imports first - ```jsx +import { createRoot } from 'react-dom/client' import React, { useRef, useState } from 'react' -import ReactDOM from 'react-dom' import { Canvas, useFrame } from '@react-three/fiber' -``` -#### Define a component - -```jsx function Box(props) { - // This reference will give us direct access to the mesh - const mesh = useRef() - // Set up state for the hovered and active state - const [hovered, setHover] = useState(false) - const [active, setActive] = useState(false) - // Rotate mesh every frame, this is outside of React without overhead - useFrame(() => (mesh.current.rotation.x += 0.01)) - + // This reference gives us direct access to the THREE.Mesh object + const ref = useRef() + // Hold state for hovered and clicked events + const [hovered, hover] = useState(false) + const [clicked, click] = useState(false) + // Subscribe this component to the render-loop, rotate the mesh every frame + useFrame((state, delta) => (ref.current.rotation.x += 0.01)) + // Return the view, these are regular Threejs elements expressed in JSX return ( setActive(!active)} - onPointerOver={(event) => setHover(true)} - onPointerOut={(event) => setHover(false)}> - + ref={ref} + scale={clicked ? 1.5 : 1} + onClick={(event) => click(!clicked)} + onPointerOver={(event) => hover(true)} + onPointerOut={(event) => hover(false)}> + ) } + +createRoot(document.getElementById('root')).render( + + + + + + , +) ``` -#### Compose the scene +
+ Show TypeScript example + +```bash +npm install @types/three +``` -Either use `Canvas`, which you can think of as a portal to threejs inside your regular dom graph. Everything within it is a [native threejs element](https://threejs.org/docs). If you want to mix Webgl and Html (react-dom) this is what you should use. +```tsx +import * as THREE from 'three' +import { createRoot } from 'react-dom/client' +import React, { useRef, useState } from 'react' +import { Canvas, useFrame, ThreeElements } from '@react-three/fiber' -```jsx -ReactDOM.render( +function Box(props: ThreeElements['mesh']) { + const ref = useRef(null!) + const [hovered, hover] = useState(false) + const [clicked, click] = useState(false) + useFrame((state, delta) => (ref.current.rotation.x += 0.01)) + return ( + click(!clicked)} + onPointerOver={(event) => hover(true)} + onPointerOut={(event) => hover(false)}> + + + + ) +} + +createRoot(document.getElementById('root') as HTMLElement).render( , - document.getElementById('root'), ) ``` -Or use react-three-fibers own `render` function, which is a little more low-level but could save you the extra cost of carrying react-dom. It renders into a dom `canvas` element. Use this for Webgl-only apps. +Live demo: https://codesandbox.io/s/icy-tree-brnsm?file=/src/App.tsx -```jsx -import { render } from '@react-three/fiber' +
+ +
+ Show React Native example + +This example relies on react 18 and uses `expo-cli`, but you can create a bare project with their template or with the `react-native` CLI. -render(, document.querySelector('canvas')) +```bash +# Install expo-cli, this will create our app +npm install expo-cli -g +# Create app and cd into it +expo init my-app +cd my-app +# Install dependencies +npm install three @react-three/fiber@beta react@rc +# Start +expo start ``` -
- Show TypeScript example +Some configuration may be required to tell the Metro bundler about your assets if you use `useLoader` or Drei abstractions like `useGLTF` and `useTexture`: -```tsx -import { Canvas, MeshProps, useFrame } from '@react-three/fiber' +```js +// metro.config.js +module.exports = { + resolver: { + sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'], + assetExts: ['glb', 'png', 'jpg'], + }, +} +``` -const Box: React.FC = (props) => { - // This reference will give us direct access to the mesh - const mesh = useRef(null!) - // Set up state for the hovered and active state +```tsx +import React, { useRef, useState } from 'react' +import { Canvas, useFrame } from '@react-three/fiber/native' +function Box(props) { + const mesh = useRef(null) const [hovered, setHover] = useState(false) const [active, setActive] = useState(false) - // Rotate mesh every frame, this is outside of React without overhead - useFrame(() => (mesh.current.rotation.x += 0.01)) - + useFrame((state, delta) => (mesh.current.rotation.x += 0.01)) return ( = (props) => { onClick={(event) => setActive(!active)} onPointerOver={(event) => setHover(true)} onPointerOut={(event) => setHover(false)}> - + ) } - -ReactDOM.render( - - - - - - , - document.getElementById('root'), -) +export default function App() { + return ( + + + + + + + ) +} ```
--- -# Documentation +# Documentation, tutorials, examples + +Visit [docs.pmnd.rs](https://docs.pmnd.rs/react-three-fiber) -- [api.md](/markdown/api.md) -- [pitfalls.md](/markdown/pitfalls.md) -- [testing.md](/packages/test-renderer) + # Fundamentals @@ -161,13 +206,14 @@ You need to be versed in both React and Threejs before rushing into this. If you 1. Make sure you have a [basic grasp of Threejs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene). Keep that site open. 2. When you know what a scene is, a camera, mesh, geometry, material, fork the [demo above](https://github.com/pmndrs/react-three-fiber#what-does-it-look-like). 3. [Look up](https://threejs.org/docs/index.html#api/en/objects/Mesh) the JSX elements that you see (mesh, ambientLight, etc), _all_ threejs exports are native to three-fiber. -4. Try changing some values, scroll though our [Api](/markdown/api.md) to see what the various settings and hooks do. +4. Try changing some values, scroll through our [API](https://docs.pmnd.rs/react-three-fiber/API) to see what the various settings and hooks do. Some reading material: - [Threejs-docs](https://threejs.org/docs) - [Threejs-examples](https://threejs.org/examples) - [Threejs-fundamentals](https://threejs.org/manual/#en/fundamentals) +- [three.js-journey](https://threejs-journey.com) - [Discover Threejs](https://discoverthreejs.com) - [Do's and don'ts](https://discoverthreejs.com/tips-and-tricks) for performance and best practices - [react-three-fiber alligator.io tutorial](https://alligator.io/react/react-with-threejs) by [@dghez\_](https://twitter.com/dghez_) @@ -180,9 +226,11 @@ Some reading material: - [`@react-three/flex`](https://github.com/pmndrs/react-three-flex) – flexbox for react-three-fiber - [`@react-three/xr`](https://github.com/pmndrs/react-xr) – VR/AR controllers and events - [`@react-three/cannon`](https://github.com/pmndrs/use-cannon) – physics based hooks +- [`@react-three/a11y`](https://github.com/pmndrs/react-three-a11y) – real a11y for your scene - [`zustand`](https://github.com/pmndrs/zustand) – state management - [`react-spring`](https://github.com/pmndrs/react-spring) – a spring-physics-based animation library - [`react-use-gesture`](https://github.com/pmndrs/react-use-gesture) – mouse/touch gestures +- [`leva`](https://github.com/pmndrs/leva) – create GUI controls in seconds # How to contribute diff --git a/readme.md b/readme.md index 30cb08cd83..e2ac9e061e 100644 --- a/readme.md +++ b/readme.md @@ -213,6 +213,7 @@ Some reading material: - [Threejs-docs](https://threejs.org/docs) - [Threejs-examples](https://threejs.org/examples) - [Threejs-fundamentals](https://threejs.org/manual/#en/fundamentals) +- [three.js-journey](https://threejs-journey.com) - [Discover Threejs](https://discoverthreejs.com) - [Do's and don'ts](https://discoverthreejs.com/tips-and-tricks) for performance and best practices - [react-three-fiber alligator.io tutorial](https://alligator.io/react/react-with-threejs) by [@dghez\_](https://twitter.com/dghez_)