--- name: framer-motion-animations description: Subtle animation patterns for hero sections, card reveals, page transitions, and scroll-triggered effects using Framer Motion. Use when adding animations to components, implementing scroll effects, or creating page transitions. --- # Framer Motion Animations ## Installation ```bash npm install framer-motion ``` ## Basic Fade In ```tsx 'use client'; import { motion } from 'framer-motion'; export function FadeIn({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ## Staggered Children ```tsx 'use client'; 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 function StaggeredList({ items }: { items: React.ReactNode[] }) { return ( {items.map((child, i) => ( {child} ))} ); } ``` ## Scroll-Triggered Animation ```tsx 'use client'; import { motion, useInView } from 'framer-motion'; import { useRef } from 'react'; export function ScrollReveal({ children }: { children: React.ReactNode }) { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: '-100px' }); return ( {children} ); } ``` ## Hero Animation ```tsx 'use client'; import { motion } from 'framer-motion'; export function HeroSection() { return (
Pilates & Yoga Transform your body and mind
); } ``` ## Card Hover Effect ```tsx 'use client'; import { motion } from 'framer-motion'; export function AnimatedCard({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ## Section Wrapper ```tsx 'use client'; import { motion } from 'framer-motion'; import { useInView } from 'framer-motion'; import { useRef } from 'react'; interface SectionProps { children: React.ReactNode; className?: string; delay?: number; } export function AnimatedSection({ children, className, delay = 0 }: SectionProps) { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: '-50px' }); return ( {children} ); } ``` ## Counter Animation ```tsx 'use client'; import { motion, useMotionValue, useTransform, animate } from 'framer-motion'; import { useEffect } from 'react'; interface CounterProps { from: number; to: number; duration?: number; } export function AnimatedCounter({ from, to, duration = 2 }: CounterProps) { const count = useMotionValue(from); const rounded = useTransform(count, (latest) => Math.round(latest)); useEffect(() => { const controls = animate(count, to, { duration }); return controls.stop; }, [count, to, duration]); return {rounded}; } // Usage
+ Happy Clients
``` ## Page Transition Wrapper ```tsx 'use client'; import { motion, AnimatePresence } from 'framer-motion'; import { usePathname } from 'next/navigation'; export function PageTransition({ children }: { children: React.ReactNode }) { const pathname = usePathname(); return ( {children} ); } ``` ## Accordion Animation ```tsx 'use client'; import { motion, AnimatePresence } from 'framer-motion'; import { useState } from 'react'; interface AccordionItemProps { title: string; children: React.ReactNode; } export function AccordionItem({ title, children }: AccordionItemProps) { const [isOpen, setIsOpen] = useState(false); return (
{isOpen && (
{children}
)}
); } ``` ## Performance Tips 1. Use `layoutId` for shared element transitions 2. Use `useReducedMotion()` to respect user preferences 3. Avoid animating layout properties (width, height) - use transforms 4. Use `will-change` sparingly via Tailwind's `will-change-transform` 5. Prefer `opacity` and `transform` animations (GPU accelerated)