<ThreeCanvas>
A wrapper for React Three Fiber's <Canvas />
which synchronizes with Remotions useCurrentFrame()
.
Since React Three Fiber is a custom renderer, normally the React contexts that surround it don't work inside. This would normally break the usage of it in Remotion, but this component wraps the contexts so you can write your markup as expected.
Instead of using React Three Fibers useFrame
API, you can (and must) write your animations fully declaratively using Remotions useCurrentFrame
API. This will ensure that you can scrub back and forth in the timeline and pause the animation.
A browser bug would normally cause the layout to be broken because we apply a scale
transform to the canvas in preview mode. To work around this problem, the <ThreeCanvas />
requires the width
and height
props to be set.
Example
A spinning, color changing, scaling cube. This example can also be found in the examples
folder of the Remotion repo.
tsx
import {ThreeCanvas } from "@remotion/three";import {interpolate ,useCurrentFrame ,useVideoConfig } from "remotion";constThreeBasic :React .FC = () => {constframe =useCurrentFrame ();const {width ,height } =useVideoConfig ();return (<ThreeCanvas orthographic ={false}width ={width }height ={height }style ={{backgroundColor : "white",}}camera ={{fov : 75,position : [0, 0, 470] }}><ambientLight intensity ={0.15} /><pointLight args ={[undefined , 0.4]}position ={[200, 200, 0]} /><mesh position ={[0, 0, 0]}rotation ={[frame * 0.06 * 0.5,frame * 0.07 * 0.5,frame * 0.08 * 0.5]}scale ={interpolate (Math .sin (frame / 10), [-1, 1], [0.8, 1.2])}><boxGeometry args ={[100, 100, 100]} /><meshStandardMaterial color ={[Math .sin (frame * 0.12) * 0.5 + 0.5,Math .cos (frame * 0.11) * 0.5 + 0.5,Math .sin (frame * 0.08) * 0.5 + 0.5,]}/></mesh ></ThreeCanvas >);};export defaultThreeBasic ;
tsx
import {ThreeCanvas } from "@remotion/three";import {interpolate ,useCurrentFrame ,useVideoConfig } from "remotion";constThreeBasic :React .FC = () => {constframe =useCurrentFrame ();const {width ,height } =useVideoConfig ();return (<ThreeCanvas orthographic ={false}width ={width }height ={height }style ={{backgroundColor : "white",}}camera ={{fov : 75,position : [0, 0, 470] }}><ambientLight intensity ={0.15} /><pointLight args ={[undefined , 0.4]}position ={[200, 200, 0]} /><mesh position ={[0, 0, 0]}rotation ={[frame * 0.06 * 0.5,frame * 0.07 * 0.5,frame * 0.08 * 0.5]}scale ={interpolate (Math .sin (frame / 10), [-1, 1], [0.8, 1.2])}><boxGeometry args ={[100, 100, 100]} /><meshStandardMaterial color ={[Math .sin (frame * 0.12) * 0.5 + 0.5,Math .cos (frame * 0.11) * 0.5 + 0.5,Math .sin (frame * 0.08) * 0.5 + 0.5,]}/></mesh ></ThreeCanvas >);};export defaultThreeBasic ;
Note on <Sequence>
A <Sequence>
by default will return a <div>
component which is not allows inside a <ThreeCanvas>
. To avoid an error, pass layout="none"
to <Sequence>
.