Spinning 3D cube
An example of using Motion for React's useAnimationFrame hook to animate a 3D cube.
Introduction
The useAnimationFrame example shows how to create complex continuous animations using Motion's useAnimationFrame hook. This hook provides a way to run a function on every frame, perfect for creating dynamic, math-based animations that need to run continuously.
Get started
Let's start with the basic structure of our 3D cube:
export default function UseAnimationFrame() {
return (
<div className="container">
<div className="cube">
<div className="side front" />
<div className="side left" />
<div className="side right" />
<div className="side top" />
<div className="side bottom" />
<div className="side back" />
</div>
</div>
)
}
Let's animate!
Import from Motion
First, we'll import the necessary hooks:
import { useAnimationFrame } from "motion/react"
import { useRef } from "react"
Setting up direct DOM manipulation
For this animation, we're calculating our own transform values every animation frame. So we can directly assign the transform property to the DOM element.
For this, we need a reference to our cube element:
export default function UseAnimationFrame() {
const ref = useRef<HTMLDivElement>(null)
return (
<div className="container">
<div className="cube" ref={ref}>
{/* ... cube sides ... */}
</div>
</div>
)
}
Creating the continuous animation
Now, let's add the frame-by-frame animation using useAnimationFrame. This hook runs a function on every animation frame, providing a timestamp we can use to create smooth continuous motion:
useAnimationFrame((t) => {
if (!ref.current) return
const rotate = Math.sin(t / 10000) * 200
const y = (1 + Math.sin(t / 1000)) * -50
ref.current.style.transform = `translateY(${y}px) rotateX(${rotate}deg) rotateY(${rotate}deg)`
})
The timestamp, t, increases continuously, allowing us to create cyclical motion. We use Math.sin to create smooth oscillating values between -1 and 1.
For rotation: t / 10000 creates a slow cycle, multiplied by 200 for a -200° to 200° range.
For vertical movement (y): t / 1000 creates a faster cycle, transformed to move between 0 and -100px.
Conclusion
In this tutorial, we learned how to:
- Use refs for direct DOM manipulation in React
- Create frame-by-frame animations with
useAnimationFrame - Generate smooth motion using mathematical functions
- Combine multiple transforms for rich 3D effects
- Optimize performance by bypassing React's state system
