Please use Desktop to view and interact with components
Decorative2000mseaseInOut
Animated Quote Block
Quote that types itself in, pauses, then subtly breathes
quotetypewriterbreathingpulse
Useto navigate between components
Preview
"
— Steve Jobs
Code
TypeScript + React
'use client'
import { useState, useEffect } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
export function AnimatedQuoteBlock() {
const quote = 'The only way to do great work is to love what you do.'
const author = 'Steve Jobs'
const typingSpeed = 50
const [displayedText, setDisplayedText] = useState('')
const [isTyping, setIsTyping] = useState(true)
const [showPulse, setShowPulse] = useState(false)
useEffect(() => {
let index = 0
const timer = setInterval(() => {
if (index < quote.length) {
setDisplayedText(quote.slice(0, index + 1))
index++
} else {
setIsTyping(false)
setShowPulse(true)
clearInterval(timer)
}
}, typingSpeed)
return () => clearInterval(timer)
}, [quote, typingSpeed])
return (
<div className="w-full max-w-2xl rounded-2xl border border-border bg-card p-8">
<motion.div
animate={{ scale: showPulse ? [1, 1.02, 1] : 1 }}
transition={{ duration: 2, repeat: showPulse ? Infinity : 0, ease: 'easeInOut' }}
className="relative"
>
<div className="text-4xl font-bold text-primary">"</div>
<div className="py-4 text-xl leading-relaxed">
<AnimatePresence mode="wait">
{isTyping ? (
<motion.span key="typing" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
{displayedText}
<motion.span
animate={{ opacity: [1, 0, 1] }}
transition={{ duration: 0.8, repeat: Infinity }}
className="inline-block w-0.5 bg-current"
/>
</motion.span>
) : (
<motion.span key="complete" initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
{quote}
</motion.span>
)}
</AnimatePresence>
</div>
<div className="mt-4 text-right text-sm text-muted-foreground">— {author}</div>
</motion.div>
</div>
)
}
How to Use
- 1Install Framer Motion:
npm install framer-motion - 2Copy the code from above
- 3Paste it into your project and customize as needed
- 4Colors are customizable via Tailwind CSS classes. The default theme uses dark mode colors defined in your globals.css file