3D: Introduction
Get started with Framer Motion 3D
#Overview
Framer Motion 3D is a simple yet powerful animation library for React Three Fiber. It offers most of the same functionality as Framer Motion for declarative 3D scenes.
This guide will help you create animations with Motion 3D, but assumes you know the basics of both Framer Motion and React Three Fiber.
#Installation
Framer Motion 3D is built upon the Three.js and React Three Fiber (R3F) libraries. Install all three from npm:
npm install three @react-three/fiber framer-motion-3d
#Usage
#motion
components
For every R3F component, there's a motion
equivalent. Import motion
from "framer-motion-3d"
:
import { motion } from "framer-motion-3d"
And use in place of your R3F components:
<motion.pointLight animate={{ x: 2 }} />
#Animation
Motion 3D supports all the same animation options as usual, including the initial
and animate
props, variants, and the imperative useAnimation
controls.
const variants = { hidden: { opacity: 0 }, visible: { opacity: 1 },}
return ( <motion.meshStandardMaterial initial="hidden" animate="visible" variants={variants} />)
Currently, variants can't be automatically passed between the DOM and 3D worlds, but you can still share state to achieve similar results:
// index.jsimport { motion } from "framer-motion"import { Scene } from "./scene"
export function App() { const [isHovered, setIsHovered] = useState(false) return ( <motion.div whileHover={{ scale: 1.2 }} onHoverStart={() => setIsHovered(true)} onHoverEnd={() => setIsHovered(true)} > <Scene isHovered={isHovered} /> </motion.div> )}
// scene.jsimport { Canvas } from "@react-three/fiber"import { motion } from "framer-motion-3d"
export function Scene({ isHovered }) { return ( <Canvas> <motion.group animate={isHovered ? "hover" : "rest"}> <motion.mesh variants={{ hover: { z: 1 } }} /> </motion.group> </Canvas> )}
#Supported values
3D motion
components support most of the the same transforms as their 2D equivalents:
x
,y
andz
scale
,scaleX
,scaleY
andscaleZ
rotateX
,rotateY
androtateZ
Additionally, color
and opacity
are supported on 3D primitives that support them, like meshStandardMaterial
, with support for more values coming in the near future.
#Gestures
3D motion
components support the hover and tap gestures on R3F with a physical presence (like mesh
).
<motion.mesh whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} onHoverStart={() => console.log('hover start')} onTap={() => console.log('tapped!')}/>
#MotionValue
MotionValue
s are used to track the state and velocity of animating values, outside of React's render lifecycle.
With 3D motion
components, MotionValue
s are injected via their R3F attribute:
import { useMotionValue, useTransform } from "framer-motion"import { motion } from "framer-motion-3d"
export function Box() { const x = useMotionValue(0) const scaleZ = useTransform(x, v => v / 100) return ( <motion.mesh position-x={x} scale={[1, 1, scaleZ]} animate={{ x: 100 }} /> )}
#Layout animations
Images, and therefore 3D scenes, involved in layout animations can exhibit scale distortion. With the LayoutCamera
and LayoutOrthographicCamera
components this distortion can be corrected and the 3D scene can be incorporated into the layout animation naturally.