Canvas
The Canvas object is your portal into three.js.
The Canvas
object is where you start to define your React Three Fiber Scene.
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 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 iforthographic
is true - A
THREE.PCFSoftShadowMap
ifshadows
is true - A
THREE.Scene
(into which all the JSX is rendered) and aTHREE.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.
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:
<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.
import { useErrorBoundary } from 'use-error-boundary'
function App() {
const { ErrorBoundary, didCatch, error } = useErrorBoundary()
return didCatch ? (
<div>{error.message}</div>
) : (
<ErrorBoundary>
<Canvas>
<mesh />
</Canvas>
</ErrorBoundary>
)
}
Ideally, and if possible, your fallback is a seamless, visual replacement for what the canvas would have otherwise rendered.
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.
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:
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 which will do this for you automatically:
// 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>,
)