Creating Animated UI with Framer Motion
Animation plays a crucial role in enhancing user experience by making interfaces feel more dynamic and responsive. For React developers, Framer Motion stands out as one of the most powerful libraries for creating captivating animations with ease. In this article, we will explore how to effectively use Framer Motion to create animated UI elements in your web applications.
What is Framer Motion?
Framer Motion is an open-source animation library designed for React. It brings animations to life using a simple API that allows developers to create sophisticated animations without the complexities often associated with CSS animations or JavaScript animations. It excels in managing animations for different states, making it ideal for building interactive UIs.
With Framer Motion, you can create animations that respond to user input, allowing for seamless transitions between different components, states, or views.
Getting Started with Framer Motion
To begin using Framer Motion, first, ensure that you have a React development environment set up. If you haven’t done that yet, follow these steps to create a new React app:
npx create-react-app framer-motion-demo
cd framer-motion-demo
npm start
Next, you’ll need to install Framer Motion. You can do this using npm:
npm install framer-motion
Basic Usage
Now that you have Framer Motion installed, let’s create a simple animated component. Start by importing the necessary modules into your React component:
import { motion } from 'framer-motion';
Here’s a simple example of a bouncing box:
const BouncingBox = () => {
return (
<motion.div
style={{
width: '100px',
height: '100px',
backgroundColor: 'blue',
}}
animate={{ y: [0, -50, 0] }}
transition={{ duration: 0.5, repeat: Infinity }}
/>
);
};
This code snippet creates a blue box that bounces indefinitely using Framer Motion’s animate and transition properties. The y value in the animate property dictates its vertical movement.
Animating on Mount and Unmount
Framer Motion also allows you to specify animations when components mount or unmount. You can achieve this using the initial and exit props:
const BoxWithMountUnmount = () => {
const [isVisible, setIsVisible] = useState(true);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>Toggle Box</button>
{isVisible && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
style={{
width: '100px',
height: '100px',
backgroundColor: 'red',
}}
/>
)}
</div>
);
};
In this example, clicking the “Toggle Box” button will fade the red box in and out by animating its opacity on mount and unmount using the initial and exit props.
Creating Routes with Animation
Animating routes can greatly improve the perceived performance of a web app. You can achieve this by leveraging AnimatePresence, which allows you to animate components as they enter and leave the DOM:
import { AnimatePresence } from 'framer-motion';
const App = () => {
const [showFirstContainer, setShowFirstContainer] = useState(true);
return (
<div>
<button onClick={() => setShowFirstContainer(!showFirstContainer)}>Toggle Container</button>
<AnimatePresence>
{showFirstContainer ? (
<motion.div
key="first"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<h1>First Container</h1>
</motion.div>
) : (
<motion.div
key="second"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
exit={{ scale: 0 }}
>
<h1>Second Container</h1>
</motion.div>
)}
</AnimatePresence>
</div>
);
};
In this code, clicking the button toggles between two containers, each with its own unique animation defined by the initial and exit states.
Transitions and Easing Functions
To enhance the sophistication of your animations, Framer Motion provides options for transitions and easing. You can customize the duration, ease, and various other properties:
const EasedBox = () => {
return (
<motion.div
initial={{ x: '-100vw' }}
animate={{ x: 0 }}
exit={{ x: '100vw' }}
transition={{
duration: 1,
ease: [0.5, 0, 0.5, 1]
}}
style={{ width: '100px', height: '100px', backgroundColor: 'green' }}
/>
);
};
In this case, the green box smoothly enters from the left and smoothly exits to the right using a cubic bezier easing function.
Complex Animations: Staggered Effects
Framer Motion makes it simple to create staggered animations for lists or collections. You can pass an array of animations for each item, creating a nice entrance or exit effect:
const StaggeredList = () => {
const items = [1, 2, 3, 4, 5];
return (
<motion.ul initial="hidden" animate="visible">
{items.map((item, index) => (
<motion.li
key={item}
variants={{
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
}}
transition={{ delay: index * 0.2 }}
>
Item {item}
</motion.li>
))}
</motion.ul>
);
};
This example demonstrates how to animate a list of items with a staggered effect that adds a touch of elegance to the component’s entrance.
Using Hooks and Custom Components
Framer Motion allows developers to create custom hooks for complex animations, enhancing reusability. Here’s an example of a custom hook that handles a toggled state with animations:
import { useEffect } from 'react';
const useAnimationToggle = () => {
const [isVisible, setIsVisible] = useState(false);
const toggle = () => setIsVisible(!isVisible);
useEffect(() => {
// Animation logic can be included here
}, [isVisible]);
return { isVisible, toggle };
};
const AnimatedToggleBox = () => {
const { isVisible, toggle } = useAnimationToggle();
return (
<div>
<button onClick={toggle}>Toggle Box</button>
{isVisible && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
style={{ width: '100px', height: '100px', backgroundColor: 'orange' }}
/>
)}
</div>
);
};
This custom hook abstracts the visibility toggling logic and can be reused for different animated components, promoting code reusability and separation of concerns.
Conclusion
Framer Motion is an incredibly powerful tool for React developers, enabling them to add animations quickly and efficiently. With its intuitive API, managing animations becomes a relatively straightforward task, allowing developers to focus more on building dynamic user interfaces. Through the examples provided, you can see how Framer Motion simplifies tasks such as animating component transitions, staggering lists, and creating sophisticated, interactive UIs.
To further your knowledge and skills, experiment with Framer Motion’s advanced features and combine it with other React libraries to create even richer experiences. As you incorporate animations into your projects, remember that good animation practice enhances usability and should be used thoughtfully to create an enjoyable user experience.
Further Reading
For more detailed documentation and advanced techniques, visit the official Framer Motion documentation. Happy animating!