Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(links): Add Threejs Journey link to recommended documentation #2592

Merged
merged 2 commits into from Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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