5 React Motion Use Cases With Examples

Learn how to implement smooth, physics-based animations in React applications with practical Framer Motion examples for modern web development.

What is Framer Motion?

Framer Motion is an open-source React animation and gesture library that offers a low-level API for integrating animations and gestures into elements while preserving HTML and SVG semantics. Unlike CSS animations that use fixed durations and easing curves, Framer Motion uses physics-based spring animations that feel more natural and responsive.

Installing Framer Motion

npm install framer-motion

Core Concept: Physics-Based Animations

Spring animations in Framer Motion create more natural-feeling motion by simulating physical springs with properties like stiffness, damping, and mass. This results in animations that overshoot slightly and settle naturally.

Modern web development relies heavily on animations to create dynamic and engaging user experiences. While creating animations in React applications can be done using traditional CSS or JavaScript, it often becomes cumbersome for complex interactions. Framer Motion (formerly React Motion) is an open-source animation library that makes constructing complicated animations easier by providing utility animation components and hooks. This guide explores five practical use cases with code examples to help you implement smooth, physics-based animations in your React applications.

For teams building complex React applications, implementing consistent animation patterns across components helps maintain a cohesive user experience. Consider how these animations integrate with your overall web development services strategy to create polished, professional interfaces.


Sources

  1. Motion.dev - Official Framer Motion Documentation
  2. Syncfusion - Create Stunning React Animations Easily with Framer Motion

Use Case 1: Spring-Based Animations

Understanding Spring Physics

Spring animations in Framer Motion create more natural-feeling motion by simulating physical springs with properties like stiffness, damping, and mass. This results in animations that overshoot slightly and settle naturally, rather than mechanically reaching their destination. Unlike traditional CSS animations that use fixed durations and easing curves, Framer Motion uses spring physics that respond naturally to user interaction and feel more organic.

Code Example: Basic Spring Animation

import { motion } from "framer-motion";

export default function SpringAnimation() {
 return (
 <motion.div
 initial={{ x: -100, opacity: 0 }}
 animate={{ x: 0, opacity: 1 }}
 transition={{
 type: "spring",
 stiffness: 100,
 damping: 10,
 mass: 1,
 }}
 >
 <h1>Spring-Animated Element</h1>
 </motion.div>
 );
}

Key Spring Properties

PropertyDescription
stiffnessControls how stiff the spring is (higher = faster oscillation)
dampingControls resistance (higher = less oscillation)
massAffects how much momentum is preserved
velocityInitial velocity of the animation

Spring animations work best for UI elements that need to feel tactile and responsive, such as buttons, toggles, modal dialogs, and interactive components. They provide immediate visual feedback that feels grounded and substantial.

When to Use Spring Animations

Spring animations are ideal for interactive elements where you want users to feel a sense of physical connection with the interface. When a user clicks a button or toggles a switch, the spring physics create a satisfying, natural response that enhances the overall user experience. This approach aligns with modern web development best practices for creating intuitive user interfaces.

For applications requiring complex state management alongside animations, understanding how to implement feature flags in React can help you control animation rollouts and A/B test different animation approaches.

Use Case 2: Hover and Gesture Interactions

Gesture Handlers in Framer Motion

Framer Motion adds a straightforward but effective collection of UI gesture handlers to React's core event listeners. Currently, it supports gesture detection for hover, tap, pan, and drag with declarative props that make implementing interactive animations simple and intuitive.

Code Example: Interactive Button

import { motion } from "framer-motion";

export default function InteractiveButton() {
 return (
 <motion.button
 className="px-6 py-3 bg-blue-500 text-white rounded-lg"
 whileHover={{ scale: 1.05, backgroundColor: "#3b82f6" }}
 whileTap={{ scale: 0.95 }}
 transition={{ type: "spring", stiffness: 400, damping: 10 }}
 >
 Click Me
 </motion.button>
 );
}

Code Example: Drag Gesture

export default function DraggableCard() {
 return (
 <motion.div
 drag
 dragConstraints={{ left: -100, right: 100, top: -50, bottom: 50 }}
 whileDrag={{ scale: 1.1, cursor: "grabbing" }}
 whileHover={{ cursor: "grab" }}
 >
 <div className="card-content">
 <h3>Draggable Card</h3>
 <p>Drag me around!</p>
 </div>
 </motion.div>
 );
}

Gesture Props Reference

  • whileHover: Animation state when cursor hovers over element
  • whileTap: Animation state when element is clicked/tapped
  • whileDrag: Animation state during drag operation
  • onHoverStart/onHoverEnd: Event handlers for hover start/end
  • onTapStart/onTapEnd: Event handlers for tap start/end

Interactive animations using gesture handlers create immediate visual feedback that helps users understand they are interacting with a responsive interface. Whether it's a subtle scale effect on hover or a full drag-and-drop experience, these animations make your application feel polished and professional.

Gesture-based animations are particularly valuable for React Native applications where touch interactions are the primary input method, creating intuitive mobile experiences.

Use Case 3: Layout Animations

The Layout Prop

The layout prop is effective for animating layout changes like height, width, and flex properties. It performs these animations performantly by animating layout-related structures with transforms under the hood rather than triggering browser layout recalculations. Layout animations eliminate the jarring snap that typically occurs when DOM elements change size or position.

Code Example: Expandable Accordion

import { useState } from "react";
import { motion } from "framer-motion";

export default function AccordionItem({ title, children }) {
 const [isOpen, setIsOpen] = useState(false);

 return (
 <motion.div
 layout
 className="border rounded-lg overflow-hidden"
 data-expanded={isOpen}
 >
 <motion.button
 className="w-full p-4 flex justify-between items-center bg-gray-100"
 onClick={() => setIsOpen(!isOpen)}
 layout
 >
 <span>{title}</span>
 <motion.span
 animate={{ rotate: isOpen ? 180 : 0 }}
 transition={{ duration: 0.2 }}
 >
 ▼
 </motion.span>
 </motion.button>

 <motion.div
 layout
 initial={{ opacity: 0 }}
 animate={{ opacity: isOpen ? 1 : 0 }}
 transition={{ duration: 0.3 }}
 className="p-4 bg-white"
 >
 {isOpen && children}
 </motion.div>
 </motion.div>
 );
}

Code Example: List Reordering

import { motion, Reorder } from "framer-motion";

export default function ReorderableList() {
 const [items, setItems] = useState(["Item 1", "Item 2", "Item 3"]);

 return (
 <Reorder.Group axis="y" values={items} onReorder={setItems}>
 {items.map((item) => (
 <Reorder.Item key={item} value={item}>
 <motion.div
 layout
 initial={{ opacity: 0, y: 20 }}
 animate={{ opacity: 1, y: 0 }}
 whileHover={{ scale: 1.02 }}
 className="p-4 bg-white border rounded shadow-sm mb-2"
 >
 {item}
 </motion.div>
 </Reorder.Item>
 ))}
 </Reorder.Group>
 );
}

Layout Animation Benefits

Layout animations create a polished, professional feel by smoothly transitioning elements to their new positions. Instead of jarring snaps when DOM elements change size or position, elements glide gracefully. The layout prop handles all the complex coordinate calculations internally, making it easy to implement sophisticated animations with minimal code.

This pattern is particularly useful for expandable sections, modal dialogs, list reordering, and any scenario where elements change size or position dynamically. When building React applications with TypeScript, layout animations help maintain visual continuity during dynamic content updates.

For teams using Next.js applications, layout animations provide smooth transitions during route changes and content updates, enhancing the perceived performance of your application.

Use Case 4: Staggered List Animations

Stagger Effect Pattern

Staggered animations create a cascading effect where elements animate one after another rather than all at once. This is achieved using the staggerChildren option in transition configurations. Staggered animations draw attention to each element individually while creating an engaging entrance sequence.

Code Example: Staggered Card Grid

import { motion } from "framer-motion";

const container = {
 hidden: { opacity: 0 },
 show: {
 opacity: 1,
 transition: {
 staggerChildren: 0.1,
 },
 },
};

const item = {
 hidden: { opacity: 0, y: 20 },
 show: { opacity: 1, y: 0 },
};

export default function StaggeredGrid() {
 const cards = [
 { title: "Card 1", content: "Content for first card" },
 { title: "Card 2", content: "Content for second card" },
 { title: "Card 3", content: "Content for third card" },
 ];

 return (
 <motion.div
 variants={container}
 initial="hidden"
 animate="show"
 className="grid grid-cols-3 gap-4"
 >
 {cards.map((card, index) => (
 <motion.div
 key={index}
 variants={item}
 className="p-6 bg-white rounded-lg shadow-md"
 >
 <h3 className="text-lg font-semibold">{card.title}</h3>
 <p className="text-gray-600 mt-2">{card.content}</p>
 </motion.div>
 ))}
 </motion.div>
 );
}

Code Example: Animated List with Variants

import { motion } from "framer-motion";

const listVariants = {
 hidden: { opacity: 0 },
 visible: {
 opacity: 1,
 transition: {
 staggerChildren: 0.15,
 delayChildren: 0.2,
 },
 },
};

const itemVariants = {
 hidden: { x: -20, opacity: 0 },
 visible: { x: 0, opacity: 1, transition: { type: "spring" } },
};

export default function AnimatedList() {
 const items = ["First item", "Second item", "Third item", "Fourth item"];

 return (
 <motion.ul
 variants={listVariants}
 initial="hidden"
 animate="visible"
 className="space-y-2"
 >
 {items.map((item) => (
 <motion.li
 key={item}
 variants={itemVariants}
 className="p-3 bg-white rounded shadow"
 >
 {item}
 </motion.li>
 ))}
 </motion.ul>
 );
}

Stagger Configuration Options

  • staggerChildren: Time delay between each child's animation
  • delayChildren: Initial delay before the first child animates
  • when: Animation sequencing (beforeChildren, afterChildren, false)

Staggered animations are particularly effective for displaying lists of content, card grids, or any collection of related elements. The cascading entrance draws the eye through the content in a natural, engaging way.

When working with Vue applications using Vuex 4, similar staggered animation patterns can be implemented to create smooth entrance effects for list-based content.

Use Case 5: Scroll-Triggered Animations

Using useScroll Hook

Framer Motion provides the useScroll hook to track scroll position and create animations that respond to user scrolling. Combined with useTransform, you can map scroll position to animation values, enabling parallax effects, reveal-on-scroll animations, and progress indicators.

Code Example: Scroll-Linked Fade In

import { motion, useScroll, useTransform } from "framer-motion";
import { useRef } from "react";

export default function ScrollRevealSection() {
 const ref = useRef(null);
 const { scrollYProgress } = useScroll({
 target: ref,
 offset: ["start end", "end start"],
 });

 const opacity = useTransform(scrollYProgress, [0, 0.3, 0.7, 1], [0, 1, 1, 0]);
 const scale = useTransform(scrollYProgress, [0, 0.3, 0.7, 1], [0.8, 1, 1, 0.8]);

 return (
 <div ref={ref} className="h-screen flex items-center justify-center">
 <motion.div
 style={{ opacity, scale }}
 className="p-12 bg-white rounded-xl shadow-lg"
 >
 <h2 className="text-2xl font-bold">Scroll Revealed Content</h2>
 <p className="mt-4 text-gray-600">
 This content fades in and scales as you scroll.
 </p>
 </motion.div>
 </div>
 );
}

Code Example: Progress Bar

import { motion, useScroll } from "framer-motion";

export default function ScrollProgressBar() {
 const { scrollYProgress } = useScroll();

 return (
 <motion.div
 className="fixed top-0 left-0 right-0 h-1 bg-blue-500 origin-left z-50"
 style={{ scaleX: scrollYProgress }}
 />
 );
}

Code Example: Parallax Effect

import { motion, useScroll, useTransform } from "framer-motion";
import { useRef } from "react";

export default function ParallaxHero() {
 const ref = useRef(null);
 const { scrollYProgress } = useScroll({
 target: ref,
 offset: ["start start", "end start"],
 });

 const y = useTransform(scrollYProgress, [0, 1], ["0%", "50%"]);
 const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);

 return (
 <div ref={ref} className="h-[150vh] relative overflow-hidden">
 <motion.div style={{ y, opacity }} className="absolute inset-0">
 <img
 src="/hero-image.jpg"
 alt="Hero"
 className="w-full h-full object-cover"
 />
 </motion.div>
 <div className="absolute inset-0 flex items-center justify-center">
 <h1 className="text-5xl font-bold text-white drop-shadow-lg">
 Welcome
 </h1>
 </div>
 </div>
 );
}

Scroll Hook Options

  • useScroll(): Track scroll position of the entire page
  • useScroll({ target }): Track scroll relative to a specific element
  • offset: Control when scroll tracking starts/ends ("start end", "end start", etc.)

Scroll-triggered animations create engaging experiences that reveal content as users explore your page. Whether it's a subtle fade-in effect, a reading progress bar, or an eye-catching parallax hero section, these animations keep users engaged with your content.

Implementing scroll-triggered animations alongside creative CSS text flows can create visually stunning hero sections that capture user attention immediately upon page load.

Best Practices for Performance

Optimize Animation Performance

  1. Use transform and opacity: Animate only transform (scale, translate, rotate) and opacity properties for optimal 60fps performance. These properties can be GPU-accelerated and don't trigger browser layout recalculations.

  2. Avoid layout properties: Properties like width, height, margin, and padding trigger browser reflows and should be avoided for smooth animations. Use the layout prop instead when layout changes are needed.

  3. Use layout prop for position changes: When elements move around in the DOM, adding the layout prop handles the animation efficiently without manual coordinate calculations.

  4. Leverage variants for complex sequences: Define animation variants to manage coordinated multi-element animations cleanly and reuse them across components.

  5. Consider will-change for complex animations: For elements with frequent animation updates, adding will-change: transform can help browser optimization.

Optimized Component Template

import { motion } from "framer-motion";

export default function OptimizedAnimation() {
 return (
 <motion.div
 initial={{ opacity: 0, scale: 0.9 }}
 animate={{ opacity: 1, scale: 1 }}
 transition={{ duration: 0.3 }}
 >
 {/* Content */}
 </motion.div>
 );
}

By following these best practices, you can create smooth, performant animations that enhance user experience without sacrificing performance. Focus on transform and opacity properties, use the layout prop efficiently, and leverage variants for complex sequences to build animations that feel natural and responsive.

Performance-optimized animations are essential for maintaining high Core Web Vitals scores, which directly impact your SEO performance. Slow, janky animations can increase bounce rates and reduce search rankings, while smooth, performant animations contribute to a positive user experience that search engines reward.

For teams implementing GraphQL with React and TypeScript, efficient animations help maintain snappy UI responses even when fetching and displaying dynamic data content.

Integration with Next.js

Client-Side Animation

Since Framer Motion uses React hooks and browser APIs, animations must be rendered client-side in Next.js applications. Use the "use client" directive for animation components.

"use client";

import { motion } from "framer-motion";

export default function AnimatedComponent() {
 return (
 <motion.div
 initial={{ opacity: 0 }}
 animate={{ opacity: 1 }}
 transition={{ duration: 0.5 }}
 >
 Animated Content
 </motion.div>
 );
}

Animation in Server Components

For animations in pages that use Server Components, separate the animation logic into client components and import them into the server component.

// AnimatedWrapper.tsx (Client Component)
"use client";

import { motion } from "framer-motion";

export function AnimatedWrapper({ children }) {
 return (
 <motion.div
 initial={{ opacity: 0, y: 20 }}
 animate={{ opacity: 1, y: 0 }}
 transition={{ duration: 0.5 }}
 >
 {children}
 </motion.div>
 );
}

// page.tsx (Server Component)
import { AnimatedWrapper } from "./AnimatedWrapper";

export default function Page() {
 return (
 <AnimatedWrapper>
 <h1>Server Component with Animation</h1>
 </AnimatedWrapper>
 );
}

Integrating Framer Motion with Next.js requires understanding the distinction between server and client components. By wrapping animated elements in client components and importing them into server components, you can maintain the benefits of server-side rendering while still providing rich, animated user experiences.

For Next.js applications requiring Incremental Static Regeneration, animations can be implemented in client components while the page content remains statically generated and efficiently updated.

Conclusion

Framer Motion provides a powerful yet approachable way to add animations to React applications. From simple spring animations to complex scroll-linked effects, the library's declarative API makes it straightforward to implement professional-quality animations that enhance user engagement.

The five use cases covered in this guide represent common animation patterns that can elevate any React application:

  • Spring-based animations create natural, physics-driven transitions that feel tactile and responsive
  • Gesture interactions provide immediate visual feedback for user interactions
  • Layout animations smoothly transition elements when their size or position changes
  • Staggered animations create cascading entrance effects for lists and grids
  • Scroll-triggered animations reveal content dynamically as users explore your pages

By following best practices--focusing on transform and opacity properties, using the layout prop efficiently, and leveraging variants for complex sequences--you can create smooth, performant animations that enhance user experience without sacrificing performance. Start with simple hover effects and gradually incorporate more advanced techniques to build engaging, polished user interfaces.

When building production React applications, remember to consider error boundary implementation to gracefully handle any animation-related errors without breaking the user experience. For large-scale React Native applications, optimizing animation performance becomes even more critical for maintaining smooth interactions across diverse device capabilities.


Sources

  1. Motion.dev - Official Framer Motion Documentation
  2. LogRocket Blog - 5 React Motion use cases with examples
  3. Syncfusion - Create Stunning React Animations Easily with Framer Motion
  4. Refine - Framer Motion React Animations

Frequently Asked Questions

Ready to Add Animations to Your React Application?

Our team specializes in building performant, engaging React applications with smooth animations and transitions that enhance user experience.