Skip to content

Commit

Permalink
docs(links): Add Threejs Journey link to recommended documentation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahlecss committed Oct 28, 2022
1 parent 17ff08f commit 87644eb
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 66 deletions.
1 change: 1 addition & 0 deletions docs/getting-started/introduction.mdx
Expand Up @@ -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_)
Expand Down
180 changes: 114 additions & 66 deletions packages/fiber/readme.md
Expand Up @@ -10,25 +10,23 @@

react-three-fiber is a <a href="https://reactjs.org/docs/codebase-overview.html#renderers">React renderer</a> 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: `<mesh />` 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: `<mesh />` 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?

Expand All @@ -45,80 +43,127 @@ There is no additional overhead. Components participate in the renderloop outsid
</tbody>
</table>

#### 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 (
<mesh
{...props}
ref={mesh}
scale={active ? 1.5 : 1}
onClick={(event) => setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
<boxGeometry args={[1, 2, 3]} />
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}

createRoot(document.getElementById('root')).render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)
```

#### Compose the scene
<details>
<summary>Show TypeScript example</summary>

```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<THREE.Mesh>(null!)
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
useFrame((state, delta) => (ref.current.rotation.x += 0.01))
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}

createRoot(document.getElementById('root') as HTMLElement).render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
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'
</details>

<details>
<summary>Show React Native example</summary>

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(<Scene />, 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
```

<details>
<summary>Show TypeScript example</summary>
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<MeshProps> = (props) => {
// This reference will give us direct access to the mesh
const mesh = useRef<THREE.Mesh>(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 (
<mesh
{...props}
Expand All @@ -127,32 +172,32 @@ const Box: React.FC<MeshProps> = (props) => {
onClick={(event) => setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
<boxGeometry args={[1, 2, 3]} />
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}

ReactDOM.render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
document.getElementById('root'),
)
export default function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
)
}
```

</details>

---

# 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)
<a href="https://docs.pmnd.rs/react-three-fiber"><img src="/docs/preview.jpg"></a>

# Fundamentals

Expand All @@ -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_)
Expand All @@ -180,9 +226,11 @@ Some reading material:
- [`@react-three/flex`](https://github.com/pmndrs/react-three-flex) &ndash; flexbox for react-three-fiber
- [`@react-three/xr`](https://github.com/pmndrs/react-xr) &ndash; VR/AR controllers and events
- [`@react-three/cannon`](https://github.com/pmndrs/use-cannon) &ndash; physics based hooks
- [`@react-three/a11y`](https://github.com/pmndrs/react-three-a11y) &ndash; real a11y for your scene
- [`zustand`](https://github.com/pmndrs/zustand) &ndash; state management
- [`react-spring`](https://github.com/pmndrs/react-spring) &ndash; a spring-physics-based animation library
- [`react-use-gesture`](https://github.com/pmndrs/react-use-gesture) &ndash; mouse/touch gestures
- [`leva`](https://github.com/pmndrs/leva) &ndash; create GUI controls in seconds

# How to contribute

Expand Down
1 change: 1 addition & 0 deletions readme.md
Expand Up @@ -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_)
Expand Down

0 comments on commit 87644eb

Please sign in to comment.