Examples
Simple examples for animation, gestures, components, transforms and more.
#Animation
The animate
prop can accept an object of values. When one of them changes, the motion
component will automatically animate to the new state.
The animation used can be configured using the transition
prop.
import { motion } from "framer-motion"
export const MyComponent = () => ( <motion.div animate={{ scale: 2 }} transition={{ duration: 0.5 }} />)
#Keyframes
Set a value as an array and Motion will animate through each of these values in turn.
By default, each keyframe will be spaced evenly throughout the animation, but the exact timing and easing can be configured via the transition
property.
import { motion } from "framer-motion"
export const MyComponent = () => ( <motion.div animate={{ scale: [1, 2, 2, 1, 1], rotate: [0, 0, 270, 270, 0], borderRadius: ["20%", "20%", "50%", "50%", "20%"], }} />)
#Variants
Variants are pre-defined visual states that a component can be in. By giving a component and its children variants
with matching names, whole React trees can be animated by changing a single prop.
By using variants, a parent can easily orchestrate the animations of its children with special transition
props like staggerChildren
.
Variants can also be dynamic functions that return different props based on data passed to each component's custom
prop.
import { motion } from "framer-motion"
const variants = { open: { opacity: 1, x: 0 }, closed: { opacity: 0, x: "-100%" },}
export const MyComponent = () => { const [isOpen, setIsOpen] = useState(false)
return ( <motion.nav animate={isOpen ? "open" : "closed"} variants={variants} > <Toggle onClick={() => setIsOpen(isOpen => !isOpen)} /> <Items /> </motion.nav> )}
#Gesture animations
Motion provides whileHover
, whileTap
, whileDrag
and whileFocus
helper props, that will temporarily animate a component to a visual state while a gesture is active.
Like animate
, these can either be set as an object of properties (each with their own transition
prop), or the name of a variant.
Motion will also automatically handle the interplay of the two gestures, so if a component is being pressed while a hover gestures starts/stops, the whileTap
gesture will take priority.
import { motion } from "framer-motion"
export const MyComponent = () => ( <motion.button whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} />)
#Drag
A component can be made draggable with the addition of the drag
prop. Lock it to either axis by setting drag
to "x"
or "y"
.
The component can be constrained to a specific range, defined either in pixels, or by providing a ref
to another DOM element.
These constraints are elastic, and the strength of this elasticity can be configured with the dragElastic
prop.
import { motion } from "framer-motion"
export const MyComponent = () => ( <motion.div drag dragConstraints={{ top: -50, left: -50, right: 50, bottom: 50, }} />)
#MotionValues
Motion uses MotionValue
s to track the state and velocity of every animating value.
By making MotionValue
s yourself, you can create declarative chains of values that map from one into the other.
import { motion, useMotionValue, useTransform,} from "framer-motion"
export const MyComponent = () => { const x = useMotionValue(0) const background = useTransform( x, [-100, 0, 100], ["#ff008c", "#7700ff", "rgb(230, 255, 0)"] )
return ( <motion.div style={{ background }}> <motion.div drag="x" dragConstraints={{ left: 0, right: 0 }} style={{ x }} > <Icon x={x} /> </motion.div> </motion.div> )}
#Scroll-triggered animations
Motion also provides a whileInView
prop that defines a visual state to animate to while a component is in the viewport.
<motion.div initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }}/>
#Scroll-linked animations
The useViewportScroll
hook provides four read-only MotionValue
s, two that return the viewport's x/y scroll position in pixels, and two that return it as progress value between 0
and 1
.
You can use these MotionValue
s to declaratively drive features like progress indicators or parallax effects.
import { motion, useViewportScroll } from "framer-motion"
export const CircleIndicator = () => { const { scrollYProgress } = useViewportScroll()
return ( <motion.path d="M 0, 20 a 20, 20 0 1,0 40,0 a 20, 20 0 1,0 -40,0" style={{ pathLength: scrollYProgress }} /> )}
#Exit animations
In React, it's usually difficult to animate components once they've been removed from the DOM.
By wrapping motion
components with AnimatePresence
, they gain the use of an exit
property that can define either a set of values or a variant name to animate to before being removed.
import { motion, AnimatePresence } from "framer-motion"
export const Slideshow = ({ image }) => ( <AnimatePresence> <motion.img key={image.src} src={image.src} initial={{ opacity: 0, y: 200 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} /> </AnimatePresence>)
You can also add the exitBeforeEnter
prop to AnimatePresence
if you'd like the entrance animation to wait until the exit animation has ended before starting.
#Layout animations
To automatically animate the layout of a motion
component when its size or position changes, give it a layout
prop.
<motion.div layout />
It doesn't matter what causes the layout change, whether it's a parent flexbox direction, width, top/right etc, the animation itself will be performed with transforms for maximum performance.
#Shared layout animations
When a new motion
component is added, it can be automatically animated from another one by giving them both the same layoutId
prop.
isSelected ? <motion.div layoutId="underline" /> : null
#Line drawing
Line drawing animations are made simple with the special `pathLength`, `pathSpacing` and `pathOffset` properties available on many SVG elements.
<motion.circle initial={{ pathLength: 0 }} animate={{ pathLength: 1 }}/>
#Path morphing
With the help of external libraries like Flubber, it's possible to animate between very different SVG shapes.