Spaces:
No application file
No application file
File size: 3,369 Bytes
b4e31eb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
import React, { useState, useEffect } from 'react';
interface CompactPetAvatarProps {
health: number;
energy: number;
attention: number;
}
const CompactPetAvatar: React.FC<CompactPetAvatarProps> = ({ health, energy, attention }) => {
const [isBlinking, setIsBlinking] = useState(false);
const [mood, setMood] = useState<'happy' | 'normal' | 'tired' | 'sick'>('normal');
useEffect(() => {
const blinkInterval = setInterval(() => {
setIsBlinking(true);
setTimeout(() => setIsBlinking(false), 150);
}, 3000 + Math.random() * 2000);
return () => clearInterval(blinkInterval);
}, []);
useEffect(() => {
const avgStats = (health + energy + attention) / 3;
if (avgStats >= 80) setMood('happy');
else if (avgStats >= 60) setMood('normal');
else if (avgStats >= 30) setMood('tired');
else setMood('sick');
}, [health, energy, attention]);
const getMoodColor = () => {
switch (mood) {
case 'happy': return '#A7F3D0';
case 'normal': return '#BFDBFE';
case 'tired': return '#FDE68A';
case 'sick': return '#FECACA';
default: return '#BFDBFE';
}
};
return (
<div className="flex items-center justify-center">
<div
className="relative w-20 h-20 rounded-full animate-pulse transition-all duration-1000 shadow-lg"
style={{ backgroundColor: getMoodColor() }}
>
{/* Pet body with gentle bounce animation */}
<div className="absolute inset-1 rounded-full bg-white/20 animate-bounce" style={{ animationDuration: '3s' }}>
{/* Eyes */}
<div className="absolute top-4 left-2 flex space-x-3">
<div className={`w-3 h-3 bg-gray-800 rounded-full transition-all duration-150 ${isBlinking ? 'h-0.5' : 'h-3'}`}>
{!isBlinking && <div className="w-1 h-1 bg-white rounded-full mt-0.5 ml-0.5"></div>}
</div>
<div className={`w-3 h-3 bg-gray-800 rounded-full transition-all duration-150 ${isBlinking ? 'h-0.5' : 'h-3'}`}>
{!isBlinking && <div className="w-1 h-1 bg-white rounded-full mt-0.5 ml-0.5"></div>}
</div>
</div>
{/* Mouth based on mood */}
<div className="absolute top-11 left-1/2 transform -translate-x-1/2">
{mood === 'happy' && (
<div className="w-3 h-1.5 border-b-2 border-gray-800 rounded-full"></div>
)}
{mood === 'normal' && (
<div className="w-2 h-1 bg-gray-800 rounded-full"></div>
)}
{(mood === 'tired' || mood === 'sick') && (
<div className="w-3 h-1.5 border-t-2 border-gray-800 rounded-full"></div>
)}
</div>
{/* Cheek blush for happy mood */}
{mood === 'happy' && (
<>
<div className="absolute top-6 left-1 w-2 h-2 bg-pink-300 rounded-full opacity-60"></div>
<div className="absolute top-6 right-1 w-2 h-2 bg-pink-300 rounded-full opacity-60"></div>
</>
)}
</div>
{/* Floating particles for happy mood */}
{mood === 'happy' && (
<div className="absolute -top-1 -right-1">
<div className="w-1 h-1 bg-yellow-300 rounded-full animate-ping"></div>
</div>
)}
</div>
</div>
);
};
export default CompactPetAvatar;
|