88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
import { motion } from 'framer-motion'
|
|
|
|
interface AvatarWithBlobProps {
|
|
roles: string[]
|
|
}
|
|
|
|
export function AvatarWithBlob({ roles }: AvatarWithBlobProps) {
|
|
// Floating animation variants for each role blob
|
|
const getBlobVariants = (index: number) => ({
|
|
animate: {
|
|
y: [0, -20, 0],
|
|
x: [0, Math.cos((index * 2 * Math.PI) / roles.length) * 10, 0],
|
|
rotate: [0, 5, -5, 0],
|
|
transition: {
|
|
duration: 4 + index * 0.5,
|
|
repeat: Infinity,
|
|
ease: 'easeInOut',
|
|
},
|
|
},
|
|
})
|
|
|
|
return (
|
|
<div className="relative w-full max-w-md mx-auto aspect-square flex items-center justify-center">
|
|
{/* Animated background blobs */}
|
|
<div className="absolute inset-0">
|
|
{/* Center circle glow */}
|
|
<motion.div
|
|
animate={{
|
|
scale: [1, 1.1, 1],
|
|
opacity: [0.3, 0.5, 0.3],
|
|
}}
|
|
transition={{
|
|
duration: 4,
|
|
repeat: Infinity,
|
|
}}
|
|
className="absolute inset-0 bg-gradient-to-br from-blue-500 via-purple-500 to-pink-500 rounded-full blur-3xl"
|
|
/>
|
|
</div>
|
|
|
|
{/* Avatar center */}
|
|
<motion.div
|
|
initial={{ scale: 0, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
transition={{ duration: 0.8, delay: 0.2 }}
|
|
className="relative z-10 w-32 h-32 mx-auto"
|
|
>
|
|
<div className="w-full h-full rounded-full bg-gradient-to-br from-blue-600 to-purple-600 flex items-center justify-center text-white font-bold text-4xl border-4 border-white dark:border-gray-950 shadow-lg">
|
|
RL
|
|
</div>
|
|
</motion.div>
|
|
|
|
{/* Floating role blobs */}
|
|
{roles.map((role, index) => {
|
|
const angle = (index * 2 * Math.PI) / roles.length
|
|
const radius = 120
|
|
const x = Math.cos(angle) * radius
|
|
const y = Math.sin(angle) * radius
|
|
|
|
return (
|
|
<motion.div
|
|
key={role}
|
|
variants={getBlobVariants(index)}
|
|
animate="animate"
|
|
className="absolute z-20"
|
|
style={{
|
|
left: '50%',
|
|
top: '50%',
|
|
marginLeft: x,
|
|
marginTop: y,
|
|
}}
|
|
>
|
|
<motion.div
|
|
initial={{ scale: 0, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
transition={{ delay: 0.4 + index * 0.15 }}
|
|
className="px-4 py-2 rounded-full bg-white dark:bg-gray-900 border-2 border-blue-400 dark:border-blue-600 shadow-lg whitespace-nowrap text-sm font-semibold text-gray-900 dark:text-white"
|
|
>
|
|
{role}
|
|
</motion.div>
|
|
</motion.div>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
}
|