-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
4,233 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
title: Additional Exports | ||
nav: 9 | ||
--- | ||
|
||
| export | usage | | ||
| ------------------ | -------------------------------------------------------------- | | ||
| addEffect | Adds a global render callback which is called each frame | | ||
| addAfterEffect | Adds a global after-render callback which is called each frame | | ||
| addTail | Adds a global callback which is called when rendering stops | | ||
| buildGraph | Collects nodes and materials from a THREE.Object3D | | ||
| flushGlobalEffects | Flushes global render-effects for when manually driving a loop | | ||
| invalidate | Forces view global invalidation | | ||
| advance | Advances the frameloop (given that it's set to 'never') | | ||
| extend | Extends the native-object catalogue | | ||
| createPortal | Creates a portal (it's a React feature for re-parenting) | | ||
| createRoot | Creates a root that can render three JSX into a canvas | | ||
| events | Dom pointer-event system | | ||
| applyProps | `applyProps(element, props)` sets element properties, | | ||
| act | usage with react-testing | | ||
| useInstanceHandle | Exposes react-internal local state from `instance.__r3f` | | ||
| | | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
--- | ||
title: Canvas | ||
description: 'The Canvas object is your portal into three.js.' | ||
nav: 4 | ||
--- | ||
|
||
The `Canvas` object is where you start to define your React Three Fiber Scene. | ||
|
||
```jsx | ||
import React from 'react' | ||
import { Canvas } from '@react-three/fiber' | ||
|
||
const App = () => ( | ||
<Canvas> | ||
<pointLight position={[10, 10, 10]} /> | ||
<mesh> | ||
<sphereGeometry /> | ||
<meshStandardMaterial color="hotpink" /> | ||
</mesh> | ||
</Canvas> | ||
) | ||
``` | ||
|
||
## Properties | ||
|
||
| Prop | Description | Default | | ||
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | ||
| children | three.js JSX elements or regular components | | | ||
| fallback | optional DOM JSX elements or regular components in case GL is not supported | | | ||
| gl | Props that go into the default renderer, or your own renderer. Also accepts a synchronous callback like `gl={canvas => new Renderer({ canvas })}` | `{}` | | ||
| camera | Props that go into the default camera, or your own `THREE.Camera` | `{ fov: 75, near: 0.1, far: 1000, position: [0, 0, 5] }` | | ||
| scene | Props that go into the default scene, or your own `THREE.Scene` | `{}` | | ||
| shadows | Props that go into `gl.shadowMap`, can be set true for `PCFsoft` or one of the following: 'basic', 'percentage', 'soft', 'variance' | `false` | | ||
| raycaster | Props that go into the default raycaster | `{}` | | ||
| frameloop | Render mode: always, demand, never | `always` | | ||
| resize | Resize config, see react-use-measure's options | `{ scroll: true, debounce: { scroll: 50, resize: 0 } }` | | ||
| orthographic | Creates an orthographic camera | `false` | | ||
| dpr | Pixel-ratio, use `window.devicePixelRatio`, or automatic: [min, max] | `[1, 2]` | | ||
| legacy | Enables THREE.ColorManagement in three r139 or later | `false` | | ||
| linear | Switch off automatic sRGB color space and gamma correction | `false` | | ||
| events | Configuration for the event manager, as a function of state | `import { events } from "@react-three/fiber"` | | ||
| eventSource | The source where events are being subscribed to, HTMLElement | `React.MutableRefObject<HTMLElement>`, `gl.domElement.parentNode` | | ||
| eventPrefix | The event prefix that is cast into canvas pointer x/y events | `offset` | | ||
| flat | Use `THREE.NoToneMapping` instead of `THREE.ACESFilmicToneMapping` | `false` | | ||
| onCreated | Callback after the canvas has rendered (but not yet committed) | `(state) => {}` | | ||
| onPointerMissed | Response for pointer clicks that have missed any target | `(event) => {}` | | ||
|
||
## Defaults | ||
|
||
Canvas uses [createRoot](#createroot) which will create a translucent `THREE.WebGLRenderer` with the following constructor args: | ||
|
||
- antialias=true | ||
- alpha=true | ||
- powerPreference="high-performance" | ||
|
||
and with the following properties: | ||
|
||
- outputColorSpace = THREE.SRGBColorSpace | ||
- toneMapping = THREE.ACESFilmicToneMapping | ||
|
||
It will also create the following scene internals: | ||
|
||
- A `THREE.Perspective` camera | ||
- A `THREE.Orthographic` cam if `orthographic` is true | ||
- A `THREE.PCFSoftShadowMap` if `shadows` is true | ||
- A `THREE.Scene` (into which all the JSX is rendered) and a `THREE.Raycaster` | ||
|
||
In recent versions of threejs, `THREE.ColorManagement.enabled` will be set to `true` to enable automatic conversion of colors according to the renderer's configured color space. R3F will handle texture color space conversion. For more on this topic, see [https://threejs.org/docs/#manual/en/introduction/Color-management](https://threejs.org/docs/#manual/en/introduction/Color-management). | ||
|
||
## Errors and fallbacks | ||
|
||
On some systems WebGL may not be supported, you can provide a fallback component that will be rendered instead of the canvas: | ||
|
||
```jsx | ||
<Canvas fallback={<div>Sorry no WebGL supported!</div>}> | ||
<mesh /> | ||
</Canvas> | ||
``` | ||
|
||
You should also safeguard the canvas against WebGL context crashes, for instance if users have the GPU disabled or GPU drivers are faulty. | ||
|
||
```jsx | ||
import { useErrorBoundary } from 'use-error-boundary' | ||
|
||
function App() { | ||
const { ErrorBoundary, didCatch, error } = useErrorBoundary() | ||
return didCatch ? ( | ||
<div>{error.message}</div> | ||
) : ( | ||
<ErrorBoundary> | ||
<Canvas> | ||
<mesh /> | ||
</Canvas> | ||
</ErrorBoundary> | ||
) | ||
} | ||
``` | ||
|
||
<Hint> | ||
|
||
Ideally, and if possible, your fallback is a seamless, visual replacement for what the canvas would have otherwise rendered. | ||
|
||
</Hint> | ||
|
||
## Custom Canvas | ||
|
||
R3F can render to a root, similar to how `react-dom` and all the other React renderers work. This allows you to shave off `react-dom` (~40kb), `react-use-measure` (~3kb) and, if you don't need them, `pointer-events` (~7kb) (you need to explicitly import `events` and add them to the config otherwise). | ||
|
||
Roots have the same options and properties as `Canvas`, but you are responsible for resizing it. It requires an existing DOM `<canvas>` object into which it renders. | ||
|
||
### CreateRoot | ||
|
||
Creates a root targeting a canvas, rendering JSX. | ||
|
||
```jsx | ||
import * as THREE from 'three' | ||
import { extend, createRoot, events } from '@react-three/fiber' | ||
|
||
// Register the THREE namespace as native JSX elements. | ||
// See below for notes on tree-shaking | ||
extend(THREE) | ||
|
||
// Create a react root | ||
const root = createRoot(document.querySelector('canvas')) | ||
|
||
// Configure the root, inject events optionally, set camera, etc | ||
root.configure({ events, camera: { position: [0, 0, 50] } }) | ||
|
||
// createRoot by design is not responsive, you have to take care of resize yourself | ||
window.addEventListener('resize', () => { | ||
root.configure({ size: { width: window.innerWidth, height: window.innerHeight } }) | ||
}) | ||
|
||
// Trigger resize | ||
window.dispatchEvent(new Event('resize')) | ||
|
||
// Render entry point | ||
root.render(<App />) | ||
|
||
// Unmount and dispose of memory | ||
// root.unmount() | ||
``` | ||
|
||
## Tree-shaking | ||
|
||
New with v8, the underlying reconciler no longer pulls in the THREE namespace automatically. | ||
|
||
This enables a granular catalogue which also enables tree-shaking via the `extend` API: | ||
|
||
```jsx | ||
import { extend, createRoot } from '@react-three/fiber' | ||
import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three' | ||
|
||
extend({ Mesh, BoxGeometry, MeshStandardMaterial }) | ||
|
||
createRoot(canvas).render( | ||
<> | ||
<mesh> | ||
<boxGeometry /> | ||
<meshStandardMaterial /> | ||
</mesh> | ||
</>, | ||
) | ||
``` | ||
|
||
There's an [official babel plugin](https://github.com/pmndrs/react-three-babel) which will do this for you automatically: | ||
|
||
```jsx | ||
// In: | ||
|
||
import { createRoot } from '@react-three/fiber' | ||
|
||
createRoot(canvasNode).render( | ||
<mesh> | ||
<boxGeometry /> | ||
<meshStandardMaterial /> | ||
</mesh>, | ||
) | ||
|
||
// Out: | ||
|
||
import { createRoot, extend } from '@react-three/fiber' | ||
import { Mesh as _Mesh, BoxGeometry as _BoxGeometry, MeshStandardMaterial as _MeshStandardMaterial } from 'three' | ||
|
||
extend({ | ||
Mesh: _Mesh, | ||
BoxGeometry: _BoxGeometry, | ||
MeshStandardMaterial: _MeshStandardMaterial, | ||
}) | ||
|
||
createRoot(canvasNode).render( | ||
<mesh> | ||
<boxGeometry /> | ||
<meshStandardMaterial /> | ||
</mesh>, | ||
) | ||
``` |
Oops, something went wrong.