---
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
Book Now
Learn More
);
}
```
## 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
```
## 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 (
setIsOpen(!isOpen)}
className="w-full py-4 flex justify-between items-center"
>
{title}
▼
{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)