Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Aduwoayooluwa/animations/llms.txt
Use this file to discover all available pages before exploring further.
Advanced animations combine multiple properties, timing functions, and interactions to create sophisticated visual effects. Master these techniques to build professional-grade animation experiences.
Combining multiple properties
Create rich animations by orchestrating multiple CSS properties simultaneously.
Scale animation
const scaleAnimation = {
animate: { scale: [1, 1.5, 0.5, 1] },
transition: {
duration: 2,
repeat: Infinity,
repeatType: "loop" as const
}
}
<motion.div
animate={scaleAnimation.animate}
transition={scaleAnimation.transition}
/>
Rotation animation
const rotateAnimation = {
animate: { rotate: [0, 180, -180, 0] },
transition: {
duration: 2,
repeat: Infinity,
repeatType: "loop" as const,
ease: "linear"
}
}
Fade with scale
Combine opacity and scale for smooth fade effects:
const fadeAnimation = {
animate: {
opacity: [1, 0.2, 1],
scale: [1, 0.9, 1]
},
transition: {
duration: 1.5,
repeat: Infinity,
repeatType: "reverse" as const,
ease: "easeInOut"
}
}
Bounce with scale
const bounceAnimation = {
animate: {
y: [0, -50, 0],
scale: [1, 0.9, 1]
},
transition: {
duration: 0.8,
repeat: Infinity,
repeatType: "reverse" as const,
ease: "easeOut"
}
}
3D flip animation
const flipAnimation = {
animate: { rotateY: [0, 360] },
transition: {
duration: 1.5,
repeat: Infinity,
repeatType: "loop" as const,
ease: "easeInOut"
}
}
<motion.div
animate={flipAnimation.animate}
transition={flipAnimation.transition}
style={{
transformStyle: 'preserve-3d',
backfaceVisibility: 'visible'
}}
/>
Gesture-based animations
Create interactive animations that respond to user input with real-time transformations.
const x = useMotionValue(0)
const y = useMotionValue(0)
const rotate = useTransform(x, [-100, 100], [-30, 30])
const scale = useTransform(y, [-100, 100], [0.5, 3])
<motion.div
drag
dragElastic={0.2}
dragConstraints={{
top: -100,
left: -100,
right: 100,
bottom: 100
}}
style={{ x, y, rotate, scale }}
whileDrag={{ boxShadow: "0 8px 32px rgba(0,0,0,0.2)" }}
/>
Interactive controls
Let users control animation parameters in real-time:
const [rotationSpeed, setRotationSpeed] = useState(2)
const [scaleAmount, setScaleAmount] = useState(1.2)
<motion.div
animate={{
scale: [1, scaleAmount, 1],
rotate: [0, 180, 0],
borderRadius: ["0%", "50%", "0%"]
}}
transition={{
duration: rotationSpeed,
ease: "easeInOut",
repeat: Infinity,
repeatDelay: 0.5
}}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
/>
Link animations to scroll position for immersive experiences:
import { useScroll, useSpring } from "framer-motion"
const { scrollYProgress } = useScroll()
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001
})
<motion.div
style={{ scaleX }}
className="fixed top-0 left-0 right-0 h-1 bg-blue-500 origin-left"
/>
Animation orchestration
Manage multiple animations with a unified control system.
Toggle multiple animations
type AnimationType = 'scale' | 'rotate' | 'fade' | 'bounce' | 'flip'
const [activeAnimations, setActiveAnimations] = useState<AnimationType[]>([])
const animations: Record<AnimationType, AnimationConfig> = {
scale: {
animate: { scale: [1, 1.5, 0.5, 1] },
transition: {
duration: 2,
repeat: Infinity,
repeatType: "loop" as const
}
},
rotate: {
animate: { rotate: [0, 180, -180, 0] },
transition: {
duration: 2,
repeat: Infinity,
repeatType: "loop" as const,
ease: "linear"
}
},
fade: {
animate: { opacity: [1, 0.2, 1], scale: [1, 0.9, 1] },
transition: {
duration: 1.5,
repeat: Infinity,
repeatType: "reverse" as const,
ease: "easeInOut"
}
},
bounce: {
animate: { y: [0, -50, 0], scale: [1, 0.9, 1] },
transition: {
duration: 0.8,
repeat: Infinity,
repeatType: "reverse" as const,
ease: "easeOut"
}
},
flip: {
animate: { rotateY: [0, 360] },
transition: {
duration: 1.5,
repeat: Infinity,
repeatType: "loop" as const,
ease: "easeInOut"
}
}
}
const toggleAnimation = (type: AnimationType) => {
setActiveAnimations(prev =>
prev.includes(type)
? prev.filter(t => t !== type)
: [...prev, type]
)
}
Conditional animation rendering
<motion.div
initial={false}
animate={activeAnimations.includes(type) ? animations[type].animate : {}}
transition={animations[type].transition}
style={{
transformStyle: 'preserve-3d',
backfaceVisibility: 'visible'
}}
/>
Animation breakdown
Debug complex animations by breaking them down into individual steps:
const [progress, setProgress] = useState(0)
const [isPlaying, setIsPlaying] = useState(false)
// Calculate animation values based on progress
const translateY = -50 * Math.sin(progress * Math.PI)
const opacity = 0.5 + 0.5 * Math.sin(progress * Math.PI * 2)
const scale = 1 + 0.3 * Math.sin(progress * Math.PI)
<motion.div
animate={{
y: translateY,
scale: scale,
opacity: opacity
}}
/>
Frame-by-frame control
const [selectedSpeed, setSelectedSpeed] = useState<'slow' | 'normal' | 'frame-by-frame'>('normal')
const speeds = {
'slow': 0.25,
'normal': 1,
'frame-by-frame': 0
}
const advanceFrame = () => {
setProgress(prev => Math.min(prev + 0.05, 1))
}
const resetFrame = () => {
setProgress(0)
}
Progress tracking
useEffect(() => {
if (isPlaying && selectedSpeed !== 'frame-by-frame') {
const startTime = Date.now()
const duration = 2000
const animate = () => {
const elapsed = (Date.now() - startTime) * speeds[selectedSpeed]
const newProgress = Math.min((elapsed % duration) / duration, 1)
setProgress(newProgress)
animationRef.current = requestAnimationFrame(animate)
}
animationRef.current = requestAnimationFrame(animate)
return () => {
if (animationRef.current) cancelAnimationFrame(animationRef.current)
}
}
}, [isPlaying, selectedSpeed])
// Good: Uses GPU-accelerated transform
transform: `translateY(${y}px) scale(${scale})`
// Avoid: Triggers layout recalculation
top: `${y}px`
width: `${width}px`
Will-change hint
.animated-element {
will-change: transform, opacity;
}
Responsive calculations
const getAnimationDistance = () => {
if (!containerRef.current) return 50
const containerWidth = containerRef.current.clientWidth
return Math.min(containerWidth * 0.25, 100)
}
Complex animation patterns
Staggered animations
Animate lists with sequential timing:
<motion.ul
variants={{
visible: {
transition: {
staggerChildren: 0.1
}
}
}}
initial="hidden"
animate="visible"
>
{items.map(item => (
<motion.li
key={item}
variants={{
hidden: { opacity: 0, x: -20 },
visible: { opacity: 1, x: 0 }
}}
/>
))}
</motion.ul>
Sequence animations
Chain multiple animations together:
<motion.div
animate={{
scale: [1, 1.2, 1],
rotate: [0, 90, 0],
borderRadius: ["0%", "50%", "0%"]
}}
transition={{
duration: 3,
times: [0, 0.5, 1],
ease: "easeInOut"
}}
/>
Dynamic keyframes
Generate animation keyframes programmatically:
const generateKeyframes = (count: number) => {
return Array.from({ length: count }, (_, i) => ({
rotate: (360 / count) * i,
scale: 1 + Math.sin((i / count) * Math.PI) * 0.5
}))
}