Animation can significantly enhance user experience by making web applications feel more responsive, interactive, and engaging. In the React ecosystem, Framer Motion stands out as a powerful and easy-to-use library for creating sophisticated animations.
This article will guide you through the basics of animating React components using Framer Motion, providing detailed examples to illustrate various use cases.
Table of Contents
- Introduction to Framer Motion
- Setting Up Framer Motion in a React Project
- Basic Animations
- Animating a Simple Box
- Hover and Tap Animations
- Advanced Animations
- Keyframes
- Gestures and Drag
- Exit Animations
- Orchestrating Animations
- Variants
- Animation Controls
- Practical Examples
- Modal with Animation
- Animated List Items
- Page Transitions
- Performance Considerations
- Conclusion
1. Introduction to Framer Motion
Framer Motion is a production-ready motion library for React, developed by Framer, a company known for its design and prototyping tools. It combines ease of use with powerful features, making it a go-to choice for adding animations to React applications.
Key Features
- Declarative Syntax: Write animations in a way that’s natural within React’s component-based architecture.
- Intuitive API: Easy-to-understand props and methods for common animation tasks.
- Powerful Gestures: Built-in support for drag, hover, and tap interactions.
- Variants and Orchestration: Manage complex animations and sequence them efficiently.
2. Setting Up Framer Motion in a React Project
To get started with Framer Motion, you need to install it in your React project. Assuming you have a React project set up, you can install Framer Motion using npm or yarn:
npm install framer-motion
or
yarn add framer-motion
After installation, you can start importing and using Framer Motion components in your React application.
3. Basic Animations
Let’s begin with some basic animations to get a feel for how Framer Motion works.
Animating a Simple Box
We’ll start by animating a simple box. Create a new component called AnimatedBox.js
:
import React from 'react';
import { motion } from 'framer-motion';
const AnimatedBox = () => {
return (
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto'
}}
animate={{ rotate: 360 }}
transition={{ duration: 2 }}
/>
);
};
export default AnimatedBox;
In this example:
- We use the
motion.div
component to create an animatablediv
. - The
animate
prop specifies the end state of the animation (a full 360-degree rotation). - The
transition
prop controls the duration of the animation.
Hover and Tap Animations
Framer Motion makes it easy to add animations for hover and tap interactions. Let’s enhance our box to change color on hover and scale on tap.
import React from 'react';
import { motion } from 'framer-motion';
const InteractiveBox = () => {
return (
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto'
}}
whileHover={{ scale: 1.2, backgroundColor: 'red' }}
whileTap={{ scale: 0.8 }}
/>
);
};
export default InteractiveBox;
Here:
whileHover
prop specifies the animation to play when the element is hovered over.whileTap
prop specifies the animation to play when the element is tapped (or clicked).
4. Advanced Animations
Moving beyond basic animations, Framer Motion provides more advanced features such as keyframes, gestures, and exit animations.
Keyframes
Keyframes allow you to animate through a sequence of values. Let’s animate a box changing colors over time.
import React from 'react';
import { motion } from 'framer-motion';
const KeyframeBox = () => {
return (
<motion.div
style={{
width: 100,
height: 100,
margin: 'auto'
}}
animate={{ backgroundColor: ['blue', 'green', 'yellow', 'red'] }}
transition={{ duration: 4, repeat: Infinity }}
/>
);
};
export default KeyframeBox;
In this example:
- The animate prop is an array of color values that the box will transition through.
- The
transition
prop includesrepeat: Infinity
looping the animation indefinitely.
Gestures and Drag
Framer Motion also supports drag interactions, which can be particularly useful for creating sliders, carousels, or draggable elements.
import React from 'react';
import { motion } from 'framer-motion';
const DraggableBox = () => {
return (
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto',
cursor: 'grab'
}}
dragConstraints={{ top: -50, bottom: 50, left: -50, right: 50 }}
whileDrag={{ scale: 1.2 }} />
);
};
export default DraggableBox;
In this example:
- The
drag
prop makes the box draggable. dragConstraints
limits the draggable area.whileDrag
animates the box while it is being dragged.
Exit Animations
Exit animations allow you to animate a component when it is removed from the DOM. This can be useful for modals, notifications, or any component that needs to transition out gracefully.
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const ExitAnimationBox = () => {
const [isVisible, setIsVisible] = useState(true);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>Toggle</button>
<AnimatePresence>
{isVisible && (
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto'
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
</AnimatePresence>
</div>
);
};
export default ExitAnimationBox;
Here:
AnimatePresence
enables exit animations for components.- The
initial
,animate
, andexit
props control the opacity of the box as it enters and exits.
5. Orchestrating Animations
For more complex animations, Framer Motion offers tools like variants and animation controls.
Variants
Variants allow you to define multiple animation states and switch between them easily.
import React from 'react';
import { motion } from 'framer-motion';
const boxVariants = {
hidden: { opacity: 0, scale: 0.8 },
visible: { opacity: 1, scale: 1 }
};
const VariantsBox = () => {
return (
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto'
}}
initial="hidden"
animate="visible"
variants={boxVariants}
transition={{ duration: 1 }}
/>
);
};
export default VariantsBox;
In this example:
boxVariants
defines two states:hidden
andvisible
.- The component uses these variants to control the animation state.
Animation Controls
Animation controls give you programmatic control over animations, useful for triggering animations based on specific events or conditions.
import React from 'react';
import { motion, useAnimation } from 'framer-motion';
const ControlsBox = () => {
const controls = useAnimation();
return (
<div>
<button onClick={() => controls.start({ scale: 1.5, transition: { duration: 0.5 } })}>
Enlarge
</button>
<motion.div
style={{
width: 100,
height: 100,
backgroundColor: 'blue',
margin: 'auto'
}}
animate={controls}
/>
</div>
);
};
export default ControlsBox;
Here:
useAnimation
hook provides control over the animation.- The button click triggers the animation to start with specified properties.
6. Practical Examples
Let’s apply what we’ve learned to some practical examples.
Modal with Animation
Animating a modal can enhance the user experience by providing smooth entry and exit transitions.
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const Modal = ({ isVisible, onClose }) => {
return (
<AnimatePresence>
{isVisible && (
<motion.div
className="backdrop"
initial={{ opacity: 0 }}
animate={{ opacity: 0.5 }}
exit={{ opacity: 0 }}
onClick={onClose}
>
<motion.div
className="modal"
initial={{ y: -50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ y: 50, opacity: 0 }}
onClick={(e) => e.stopPropagation()}
>
<h2>Modal Content</h2>
<button onClick={onClose}>Close</button>
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
};
const ModalExample = () => {
const [isModalVisible, setModalVisible] = useState(false);
return (
<div>
<button onClick={() => setModalVisible(true)}>Open Modal</button>
<Modal isVisible={isModalVisible} onClose={() => setModalVisible(false)} />
</div>
);
};
export default ModalExample;
Here:
Modal
component usesAnimatePresence
to handle the mounting and unmounting of the modal.- The modal fades in and out and slides up and down on entry and exit.
Animated List Items
Animating list items can make dynamic lists more visually appealing.
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const ListItem = ({ item }) => (
<motion.li
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
transition={{ duration: 0.3 }}
>
{item}
</motion.li>
);
const AnimatedList = () => {
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const addItem = () => {
setItems([...items, `Item ${items.length + 1}`]);
};
const removeItem = () => {
setItems(items.slice(0, -1));
};
return (
<div>
<button onClick={addItem}>Add Item</button>
<button onClick={removeItem}>Remove Item</button>
<ul>
<AnimatePresence>
{items.map((item, index) => (
<ListItem key={index} item={item} />
))}
</AnimatePresence>
</ul>
</div>
);
};
export default AnimatedList;
In this example:
- Each list item is us
ed
AnimatePresence
to animate its entry and exit. - Buttons allow for dynamically adding and removing items from the list.
Page Transitions
Framer Motion can also be used to create smooth transitions between pages.
import React from 'react';
import { motion } from 'framer-motion';
import { BrowserRouter as Router, Route, Switch, useLocation } from 'react-router-dom';
const HomePage = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<h1>Home Page</h1>
</motion.div>
);
const AboutPage = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<h1>About Page</h1>
</motion.div>
);
const PageTransitionExample = () => {
const location = useLocation();
return (
<AnimatePresence exitBeforeEnter>
<Switch location={location} key={location.pathname}>
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
</Switch>
</AnimatePresence>
);
};
const App = () => {
return (
<Router>
<PageTransitionExample />
</Router>
);
};
export default App;
Here:
AnimatePresence
ensures that page transitions are animated.- Each page component defines its own animation for entry and exit.
7. Performance Considerations
While Framer Motion is optimized for performance, it’s essential to follow best practices to ensure smooth animations:
- Limit DOM Elements: Animate only necessary elements to reduce computational load.
- Use Transform Properties: Prefer
transform
(e.g.,translate
,scale
,rotate
) over properties liketop
,left
,width
, andheight
for smoother animations. - Batch Updates: Use
motion.div
similar components to batch updates for better performance. - Profile Animations: Use browser performance tools to profile your animations and identify bottlenecks.
8. Conclusion
Framer Motion provides a robust and intuitive API for adding animations to your React applications. From basic animations to complex gestures and orchestrations, Framer Motion makes it easy to enhance your UI with smooth, performant animations.
By following the examples and best practices outlined in this article, you can start creating engaging and dynamic user experiences in your React projects. Whether you are animating a simple box or orchestrating complex page transitions, Framer Motion has the tools you need to bring your UI to life.
Leave a Reply