63 lines
1.4 KiB
TypeScript
63 lines
1.4 KiB
TypeScript
'use client'
|
|||
|
|
|
||
|
|
import { motion } from 'framer-motion'
|
||
|
|
|
||
|
|
interface AnimatedRolesProps {
|
||
|
|
roles: string[]
|
||
|
|
className?: string
|
||
|
|
}
|
||
|
|
|
||
|
|
export function AnimatedRoles({ roles, className }: AnimatedRolesProps) {
|
||
|
|
const animations = [
|
||
|
|
{
|
||
|
|
initial: { opacity: 0, x: -20 },
|
||
|
|
animate: { opacity: 1, x: 0 },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
initial: { opacity: 0, y: 20 },
|
||
|
|
animate: { opacity: 1, y: 0 },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
initial: { opacity: 0, x: 20 },
|
||
|
|
animate: { opacity: 1, x: 0 },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
initial: { opacity: 0, scale: 0.8 },
|
||
|
|
animate: { opacity: 1, scale: 1 },
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className={className}>
|
||
|
|
{roles.map((role, index) => {
|
||
|
|
const animation = animations[index % animations.length]
|
||
|
|
return (
|
||
|
|
<motion.span
|
||
|
|
key={index}
|
||
|
|
initial={animation.initial}
|
||
|
|
animate={animation.animate}
|
||
|
|
transition={{
|
||
|
|
duration: 0.6,
|
||
|
|
delay: 0.2 + index * 0.15,
|
||
|
|
ease: 'easeOut',
|
||
|
|
}}
|
||
|
|
className="inline-block"
|
||
|
|
>
|
||
|
|
{role}
|
||
|
|
{index < roles.length - 1 && (
|
||
|
|
<motion.span
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ delay: 0.2 + index * 0.15 + 0.3 }}
|
||
|
|
className="mx-2"
|
||
|
|
>
|
||
|
|
•
|
||
|
|
</motion.span>
|
||
|
|
)}
|
||
|
|
</motion.span>
|
||
|
|
)
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|