Back to Blog
Animation20 min read

Advanced Animation Techniques: Framer Motion and GSAP Mastery

Master advanced animation techniques using Framer Motion and GSAP to create stunning, performant animations.

Animations bring websites to life, creating engaging user experiences. This comprehensive guide covers advanced techniques using Framer Motion and GSAP.

Framer Motion Fundamentals

Basic Animations

typescript
import { motion } from 'framer-motion';

export function AnimatedCard() {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5 }}
      whileHover={{ scale: 1.05 }}
      whileTap={{ scale: 0.95 }}
    >
      Content
    </motion.div>
  );
}

Stagger Animations

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

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

<motion.div variants={container} initial="hidden" animate="show">
  {items.map((item) => (
    <motion.div key={item.id} variants={item}>
      {item.content}
    </motion.div>
  ))}
</motion.div>

Scroll Animations

typescript
import { useInView } from 'framer-motion';
import { useRef } from 'react';

export function ScrollAnimation() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true });
  
  return (
    <motion.div
      ref={ref}
      initial={{ opacity: 0, x: -50 }}
      animate={isInView ? { opacity: 1, x: 0 } : { opacity: 0, x: -50 }}
      transition={{ duration: 0.5 }}
    >
      Content
    </motion.div>
  );
}

GSAP Advanced Techniques

Timeline Animations

typescript
import { useGSAP } from '@/hooks/useGSAP';
import gsap from 'gsap';

export function TimelineAnimation() {
  const containerRef = useRef(null);
  
  useGSAP(() => {
    const tl = gsap.timeline();
    
    tl.from('.title', {
      opacity: 0,
      y: -50,
      duration: 1,
      ease: 'power3.out',
    })
    .from('.subtitle', {
      opacity: 0,
      x: -30,
      duration: 0.8,
    }, '-=0.5')
    .from('.content', {
      opacity: 0,
      y: 30,
      duration: 1,
      stagger: 0.1,
    }, '-=0.3');
  }, { scope: containerRef });
  
  return <div ref={containerRef}>...</div>;
}

ScrollTrigger Animations

typescript
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

useGSAP(() => {
  gsap.fromTo('.element', 
    {
      opacity: 0,
      y: 100,
    },
    {
      opacity: 1,
      y: 0,
      duration: 1,
      scrollTrigger: {
        trigger: '.element',
        start: 'top 80%',
        end: 'bottom 20%',
        toggleActions: 'play none none reverse',
      },
    }
  );
}, {});

Performance Optimization

typescript
// Use will-change for better performance
gsap.set('.animated', {
  willChange: 'transform, opacity',
});

// Clean up after animation
gsap.to('.element', {
  opacity: 0,
  onComplete: () => {
    gsap.set('.element', { willChange: 'auto' });
  },
});

Combining Framer Motion and GSAP

typescript
// Use Framer Motion for component animations
// Use GSAP for complex timeline animations

export function HybridAnimation() {
  const [isVisible, setIsVisible] = useState(false);
  const containerRef = useRef(null);
  
  // GSAP for complex sequence
  useGSAP(() => {
    if (isVisible) {
      gsap.to('.complex-element', {
        rotation: 360,
        scale: 1.2,
        duration: 2,
        ease: 'elastic.out(1, 0.3)',
      });
    }
  }, { scope: containerRef, dependencies: [isVisible] });
  
  // Framer Motion for simple interactions
  return (
    <motion.div
      ref={containerRef}
      onViewportEnter={() => setIsVisible(true)}
    >
      <motion.button whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
        Click Me
      </motion.button>
    </motion.div>
  );
}

Best Practices

  1. 1. Performance: Use transform and opacity for animations
  2. 2. Accessibility: Respect prefers-reduced-motion
  3. 3. Mobile: Optimize for touch interactions
  4. 4. Testing: Test animations across devices
typescript
// Respect reduced motion
const prefersReducedMotion = useReducedMotion();

const animation = prefersReducedMotion
  ? {}
  : {
      initial: { opacity: 0, y: 20 },
      animate: { opacity: 1, y: 0 },
    };

Create stunning, performant animations that enhance user experience.