React Three Fiber animation - useFrame, useAnimations, spring physics, keyframes...
Check installed Fiber, Drei, and React versions first. These examples target Fiber 9 / React 19. Keep the project's animation library when it already meets the task.
useFrame and refs for continuous transforms/uniforms; React state describes discrete goals such as selected, open, or active.useAnimations for authored GLTF clips. Read clip playback for independent animated instances and cleanup.Mount below Canvas; this also works with frameloop="demand". Click the box to change its target.
import { useEffect, useRef, useState } from 'react'
import { useFrame, useThree } from '@react-three/fiber'
import { MathUtils, type Mesh } from 'three'
export default function Example() {
const mesh = useRef<Mesh>(null)
const [active, setActive] = useState(false)
const invalidate = useThree((state) => state.invalidate)
const target = active ? 1 : -1
useEffect(() => { invalidate() }, [target, invalidate])
useFrame((_, delta) => {
if (!mesh.current) return
// Cap a visual transition's resume jump, not a physics simulation step.
const x = MathUtils.damp(mesh.current.position.x, target, 6, Math.min(delta, 0.1))
const moving = Math.abs(x - target) > 0.001
mesh.current.position.x = moving ? x : target
if (moving) invalidate()
})
return (
<mesh ref={mesh} name="moving-box" onClick={() => setActive((value) => !value)}>
<boxGeometry />
<meshStandardMaterial color={active ? 'orange' : 'coral'} />
</mesh>
)
}
delta is seconds. Integrate velocity as position += velocity * delta; use MathUtils.damp or lerp with 1 - exp(-lambda * delta) for exponential smoothing. A fixed lerp fraction depends on refresh rate; delta * speed can overshoot.state.clock; do not replace Fiber internals because Three.js deprecated new standalone Clock instances. For independent Three.js timing, consult Timer in the installed release.getState()); subscribe React only to UI-relevant changes. Clean up external subscriptions.Compare motion at different frame rates, background/resume behavior, and repeated target changes. On demand, confirm the object wakes, reaches its goal, and stops requesting frames. For clips, test two instances playing different actions.