Mastering Framer Motion: Advanced Animation Techniques

By Jane Smith
12 min read
Mastering Framer Motion: Advanced Animation Techniques

Mastering Framer Motion: Advanced Animation Techniques

Framer Motion has revolutionized how we approach animations in React. In this comprehensive guide, we'll explore advanced techniques that will take your animations to the next level.

Introduction to Framer Motion

Framer Motion is a production-ready motion library for React that makes creating animations simple and intuitive.

💡NOTE

Framer Motion is built on top of the Web Animations API and provides a declarative API for animations.

Basic Animation Concepts

Simple Fade In

Here's a basic fade-in animation:

JSX
import { motion } from 'framer-motion';
 
function FadeIn() {
  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
    >
      Hello World!
    </motion.div>
  );
}

Slide and Fade

Combine multiple properties for more complex animations:

JSX
<motion.div
  initial={{ opacity: 0, y: 50 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ 
    duration: 0.6,
    ease: "easeOut"
  }}
>
  Slide up and fade in
</motion.div>

Advanced Techniques

1. Stagger Animations

Create beautiful sequential animations:

JSX
const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1
    }
  }
};
 
const item = {
  hidden: { opacity: 0, y: 20 },
  show: { opacity: 1, y: 0 }
};
 
function StaggerList() {
  return (
    <motion.ul
      variants={container}
      initial="hidden"
      animate="show"
    >
      {items.map(item => (
        <motion.li key={item} variants={item}>
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

2. Gesture-Based Animations

Add interactivity with gestures:

JSX
<motion.button
  whileHover={{ 
    scale: 1.05,
    boxShadow: "0 10px 20px rgba(0,0,0,0.2)"
  }}
  whileTap={{ scale: 0.95 }}
  transition={{ type: "spring", stiffness: 400 }}
>
  Click Me!
</motion.button>
SUCCESS

Gesture animations provide instant feedback and improve user experience significantly!

3. Scroll-Triggered Animations

Animate elements as they enter the viewport:

JSX
import { motion, useScroll, useTransform } from 'framer-motion';
 
function ScrollAnimation() {
  const { scrollYProgress } = useScroll();
  const scale = useTransform(scrollYProgress, [0, 1], [0.8, 1]);
  
  return (
    <motion.div style={{ scale }}>
      Scales as you scroll
    </motion.div>
  );
}

4. Layout Animations

Animate layout changes automatically:

JSX
<motion.div layout>
  {isExpanded ? (
    <ExpandedContent />
  ) : (
    <CollapsedContent />
  )}
</motion.div>

Performance Optimization

Use Transform Properties

Always prefer transform properties for better performance:

JSX
// ✅ Good - Uses transform
<motion.div animate={{ x: 100, scale: 1.2 }} />
 
// ❌ Bad - Triggers layout
<motion.div animate={{ left: 100, width: 200 }} />

Optimize with willChange

For complex animations:

JSX
<motion.div
  style={{ willChange: 'transform' }}
  animate={{ x: 100 }}
/>
💡TIP

Don't overuse willChange as it can consume memory. Only use it for animations that need extra performance.

Real-World Examples

Card Hover Effect

JSX
function AnimatedCard({ children }) {
  return (
    <motion.div
      className="card"
      whileHover={{ 
        y: -8,
        boxShadow: "0 20px 30px rgba(0,0,0,0.15)"
      }}
      transition={{ 
        type: "spring",
        stiffness: 300,
        damping: 20
      }}
    >
      {children}
    </motion.div>
  );
}

Modal Animation

JSX
import { AnimatePresence } from 'framer-motion';
 
function Modal({ isOpen, onClose, children }) {
  return (
    <AnimatePresence>
      {isOpen && (
        <>
          <motion.div
            className="backdrop"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            onClick={onClose}
          />
          <motion.div
            className="modal"
            initial={{ opacity: 0, scale: 0.8, y: 50 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.8, y: 50 }}
          >
            {children}
          </motion.div>
        </>
      )}
    </AnimatePresence>
  );
}

Page Transitions

JSX
function PageTransition({ children }) {
  return (
    <motion.div
      initial={{ opacity: 0, x: -20 }}
      animate={{ opacity: 1, x: 0 }}
      exit={{ opacity: 0, x: 20 }}
      transition={{ duration: 0.3 }}
    >
      {children}
    </motion.div>
  );
}

Best Practices

  1. Keep animations subtle - Don't overdo it
  2. Respect prefers-reduced-motion - Accessibility matters
  3. Use spring animations - They feel more natural
  4. Test on various devices - Ensure smooth performance
  5. Combine with CSS - Use CSS for simple animations

Respecting User Preferences

Always check for reduced motion preference:

JSX
import { useReducedMotion } from 'framer-motion';
 
function AccessibleAnimation() {
  const shouldReduceMotion = useReducedMotion();
  
  return (
    <motion.div
      animate={{ 
        scale: shouldReduceMotion ? 1 : 1.2 
      }}
    >
      Accessible animation
    </motion.div>
  );
}

Conclusion

Framer Motion provides powerful tools for creating beautiful, performant animations. By following these techniques and best practices, you can create engaging user experiences that delight your users.

Key Takeaways

  • Start simple and build complexity gradually
  • Always consider performance
  • Test animations on various devices
  • Respect user preferences
  • Use spring animations for natural feel

Happy animating! ✨

About the Author

Written by Jane Smith