✨ Add Rarity-Based Gradients & Animated Particles
🎨 Rarity-Based Visual System: - Replaced TCG-based gradients with subtle rarity-based backgrounds - Common: Subtle gray gradient (no particles) - Uncommon: Subtle green gradient (15 particles) - Rare: Subtle gold gradient (25 particles) - Mythic: Rich gold gradient (40 particles) - Holographic: Subtle pink gradient (50 particles) - Enchanted: Subtle purple gradient (60 particles) - Super Rare: Subtle blue gradient (45 particles) - Legendary: Vibrant gold gradient (80 particles) ✨ Animated Particle Effects: - Floating particle animation with random positioning - Particles match rarity colors with glowing effects - Random animation delays and durations for natural movement - More rare cards = more magical particle effects - Particles are pointer-events-none (do not interfere with UI) 🎯 Smart Text Contrast: - Light rarities (common/uncommon/rare) use dark text - Dark rarities (mythic+) use white text for readability - Automatic contrast adaptation based on background 🌟 Enhanced Atmosphere: - Subtle background patterns (reduced opacity) - Rarity-appropriate visual hierarchy - Immersive, magical feel for rare cards The hero section now creates a truly magical experience
This commit is contained in:
parent
36fe4a6f0f
commit
2867a8ff23
2 changed files with 99 additions and 9 deletions
|
|
@ -132,13 +132,49 @@ export default function CardDetail() {
|
||||||
}
|
}
|
||||||
}, [card, id]);
|
}, [card, id]);
|
||||||
|
|
||||||
const getTCGGradient = (game) => {
|
const getRarityGradient = (rarity) => {
|
||||||
|
const rarityKey = rarity?.toLowerCase();
|
||||||
const gradients = {
|
const gradients = {
|
||||||
'MTG': '#9333ea, #8b5cf6, #4f46e5',
|
'common': '#f3f4f6, #e5e7eb, #d1d5db', // Subtle gray
|
||||||
'Pokemon': '#2563eb, #3b82f6, #0891b2',
|
'uncommon': '#ecfdf5, #d1fae5, #a7f3d0', // Subtle green
|
||||||
'Lorcana': '#db2777, #ec4899, #a855f7'
|
'rare': '#fef3c7, #fde68a, #fcd34d', // Subtle gold
|
||||||
|
'mythic': '#fef9c3, #fef08a, #facc15', // Rich gold
|
||||||
|
'holographic': '#fce7f3, #fbcfe8, #f9a8d4', // Subtle pink
|
||||||
|
'enchanted': '#f3e8ff, #e9d5ff, #c4b5fd', // Subtle purple
|
||||||
|
'super rare': '#dbeafe, #bfdbfe, #93c5fd', // Subtle blue
|
||||||
|
'legendary': '#fef3c7, #fde68a, #f59e0b' // Vibrant gold
|
||||||
};
|
};
|
||||||
return gradients[game] || '#4b5563, #374151';
|
return gradients[rarityKey] || '#f9fafb, #f3f4f6, #e5e7eb';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getParticleCount = (rarity) => {
|
||||||
|
const rarityKey = rarity?.toLowerCase();
|
||||||
|
const particleCounts = {
|
||||||
|
'common': 0,
|
||||||
|
'uncommon': 15,
|
||||||
|
'rare': 25,
|
||||||
|
'mythic': 40,
|
||||||
|
'holographic': 50,
|
||||||
|
'enchanted': 60,
|
||||||
|
'super rare': 45,
|
||||||
|
'legendary': 80
|
||||||
|
};
|
||||||
|
return particleCounts[rarityKey] || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getParticleColor = (rarity) => {
|
||||||
|
const rarityKey = rarity?.toLowerCase();
|
||||||
|
const colors = {
|
||||||
|
'common': '#ffffff',
|
||||||
|
'uncommon': '#10b981',
|
||||||
|
'rare': '#f59e0b',
|
||||||
|
'mythic': '#ffd700',
|
||||||
|
'holographic': '#ff6b6b',
|
||||||
|
'enchanted': '#a855f7',
|
||||||
|
'super rare': '#3b82f6',
|
||||||
|
'legendary': '#ffd700'
|
||||||
|
};
|
||||||
|
return colors[rarityKey] || '#ffffff';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTCGIcon = (game) => {
|
const getTCGIcon = (game) => {
|
||||||
|
|
@ -338,13 +374,39 @@ export default function CardDetail() {
|
||||||
<div
|
<div
|
||||||
className="relative min-h-96 flex items-center justify-center overflow-hidden"
|
className="relative min-h-96 flex items-center justify-center overflow-hidden"
|
||||||
style={{
|
style={{
|
||||||
background: `linear-gradient(135deg, ${getTCGGradient(card.game)})`
|
background: `linear-gradient(135deg, ${getRarityGradient(card.rarity)})`
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{/* Animated Particles Background */}
|
||||||
|
{getParticleCount(card.rarity) > 0 && (
|
||||||
|
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
||||||
|
{Array.from({ length: getParticleCount(card.rarity) }).map((_, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className="absolute animate-float"
|
||||||
|
style={{
|
||||||
|
left: `${Math.random() * 100}%`,
|
||||||
|
top: `${Math.random() * 100}%`,
|
||||||
|
animationDelay: `${Math.random() * 3}s`,
|
||||||
|
animationDuration: `${3 + Math.random() * 2}s`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="w-1 h-1 rounded-full opacity-60"
|
||||||
|
style={{
|
||||||
|
backgroundColor: getParticleColor(card.rarity),
|
||||||
|
boxShadow: `0 0 6px ${getParticleColor(card.rarity)}`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Background Pattern */}
|
{/* Background Pattern */}
|
||||||
<div className="absolute inset-0 opacity-10">
|
<div className="absolute inset-0 opacity-5">
|
||||||
<div className="absolute inset-0" style={{
|
<div className="absolute inset-0" style={{
|
||||||
backgroundImage: `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`
|
backgroundImage: `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23000000' fill-opacity='0.1'%3E%3Ccircle cx='30' cy='30' r='2'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`
|
||||||
}}></div>
|
}}></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -385,7 +447,11 @@ export default function CardDetail() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Card Info */}
|
{/* Card Info */}
|
||||||
<div style={{ color: 'white' }}>
|
<div style={{
|
||||||
|
color: ['common', 'uncommon', 'rare'].includes(card.rarity?.toLowerCase())
|
||||||
|
? 'var(--text-primary)'
|
||||||
|
: 'white'
|
||||||
|
}}>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h1 className="text-4xl font-bold mb-2">{card.name}</h1>
|
<h1 className="text-4xl font-bold mb-2">{card.name}</h1>
|
||||||
<p className="text-xl opacity-90 mb-4">{card.oracle_text || card.card_type}</p>
|
<p className="text-xl opacity-90 mb-4">{card.oracle_text || card.card_type}</p>
|
||||||
|
|
|
||||||
|
|
@ -674,3 +674,27 @@ body {
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Floating particle animation */
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% {
|
||||||
|
transform: translateY(0px) translateX(0px) scale(1);
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
transform: translateY(-20px) translateX(10px) scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-10px) translateX(-15px) scale(0.9);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: translateY(-25px) translateX(5px) scale(1.05);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-float {
|
||||||
|
animation: float 4s ease-in-out infinite;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue