✨ Added Magical Rarity Effects with Glowing Shadows & Particles
�� Rarity-Based Visual Effects: - Mythic/Legendary: Golden glow with 3-layer pulsing animation - Rare/Holo: Purple glow with shimmering particles - Uncommon: Blue glow with subtle twinkling - Enchanted/Secret: Rainbow cycling glow with rotating particles 💫 Dynamic Particle Systems: - Radial gradient overlays for sparkle effects - Animated opacity and rotation for enchanted cards - Multiple particle layers for depth and richness - Smooth pulsing animations with different timings 🎨 Enhanced Visual Hierarchy: - Rarity-specific border colors and shadows - Hover intensification of glow effects - Side panel inherits rarity styling - Pulsing rarity indicator dots in panel headers ⚡ Performance Optimized: - CSS-only animations using hardware acceleration - Efficient keyframe animations - Proper z-index layering - Responsive particle effects 🎯 Smart Rarity Detection: - Flexible string matching for various rarity names - Supports MTG, Pokemon, Lorcana rarity systems - Fallback to standard styling for common cards - Case-insensitive rarity recognition Cards now have that premium, magical feel! ✨🃏
This commit is contained in:
parent
1387ecaccb
commit
d537474a61
2 changed files with 271 additions and 3 deletions
|
|
@ -21,6 +21,50 @@ export default function CardItem({
|
|||
setImageError(true);
|
||||
};
|
||||
|
||||
// Get rarity-based styling
|
||||
const getRarityEffects = (rarity) => {
|
||||
const rarityLower = rarity?.toLowerCase() || '';
|
||||
|
||||
if (rarityLower.includes('mythic') || rarityLower.includes('legendary')) {
|
||||
return {
|
||||
glow: 'rarity-glow-mythic',
|
||||
particles: 'rarity-particles-mythic',
|
||||
border: 'border-yellow-400',
|
||||
shadow: 'shadow-yellow-400/50'
|
||||
};
|
||||
} else if (rarityLower.includes('rare') || rarityLower.includes('holo')) {
|
||||
return {
|
||||
glow: 'rarity-glow-rare',
|
||||
particles: 'rarity-particles-rare',
|
||||
border: 'border-purple-400',
|
||||
shadow: 'shadow-purple-400/50'
|
||||
};
|
||||
} else if (rarityLower.includes('uncommon')) {
|
||||
return {
|
||||
glow: 'rarity-glow-uncommon',
|
||||
particles: 'rarity-particles-uncommon',
|
||||
border: 'border-blue-400',
|
||||
shadow: 'shadow-blue-400/30'
|
||||
};
|
||||
} else if (rarityLower.includes('enchanted') || rarityLower.includes('secret')) {
|
||||
return {
|
||||
glow: 'rarity-glow-enchanted',
|
||||
particles: 'rarity-particles-enchanted',
|
||||
border: 'border-pink-400',
|
||||
shadow: 'shadow-pink-400/60'
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
glow: '',
|
||||
particles: '',
|
||||
border: 'border-gray-200',
|
||||
shadow: ''
|
||||
};
|
||||
};
|
||||
|
||||
const rarityEffects = getRarityEffects(card.rarity);
|
||||
|
||||
if (viewMode === 'list') {
|
||||
return (
|
||||
<div className={`flex items-center p-4 border rounded-lg transition-all duration-200 ${
|
||||
|
|
@ -134,8 +178,13 @@ export default function CardItem({
|
|||
<div className={`relative bg-white rounded-xl border transition-all duration-300 overflow-hidden ${
|
||||
isSelected
|
||||
? 'border-purple-500 shadow-xl ring-2 ring-purple-200'
|
||||
: 'border-gray-200 group-hover:border-gray-300 group-hover:shadow-lg'
|
||||
}`}>
|
||||
: `${rarityEffects.border} group-hover:border-gray-300 group-hover:shadow-lg ${rarityEffects.shadow ? `shadow-lg ${rarityEffects.shadow}` : ''}`
|
||||
} ${rarityEffects.glow}`}>
|
||||
|
||||
{/* Rarity Particles */}
|
||||
{rarityEffects.particles && (
|
||||
<div className={`absolute inset-0 pointer-events-none ${rarityEffects.particles}`}></div>
|
||||
)}
|
||||
{/* Selection Checkbox */}
|
||||
<div className="absolute top-3 left-3 z-20">
|
||||
<input
|
||||
|
|
@ -193,7 +242,11 @@ export default function CardItem({
|
|||
? 'opacity-100 translate-x-0 pointer-events-auto'
|
||||
: 'opacity-0 translate-x-2 pointer-events-none group-hover:opacity-100 group-hover:translate-x-0 group-hover:pointer-events-auto delay-300 group-hover:delay-500'
|
||||
}`}>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-2xl h-full overflow-hidden">
|
||||
<div className={`bg-white dark:bg-gray-800 rounded-xl border shadow-2xl h-full overflow-hidden ${
|
||||
rarityEffects.border !== 'border-gray-200'
|
||||
? `${rarityEffects.border} dark:${rarityEffects.border.replace('border-', 'border-')} ${rarityEffects.glow}`
|
||||
: 'border-gray-200 dark:border-gray-700'
|
||||
}`}>
|
||||
{/* Panel Header */}
|
||||
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
|
|
@ -262,6 +315,21 @@ export default function CardItem({
|
|||
{card.game}
|
||||
</span>
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">{card.set_name}</span>
|
||||
{rarityEffects.glow && (
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className={`w-2 h-2 rounded-full ${
|
||||
card.rarity?.toLowerCase().includes('mythic') || card.rarity?.toLowerCase().includes('legendary')
|
||||
? 'bg-yellow-400 shadow-sm shadow-yellow-400/50'
|
||||
: card.rarity?.toLowerCase().includes('rare') || card.rarity?.toLowerCase().includes('holo')
|
||||
? 'bg-purple-400 shadow-sm shadow-purple-400/50'
|
||||
: card.rarity?.toLowerCase().includes('uncommon')
|
||||
? 'bg-blue-400 shadow-sm shadow-blue-400/50'
|
||||
: card.rarity?.toLowerCase().includes('enchanted') || card.rarity?.toLowerCase().includes('secret')
|
||||
? 'bg-pink-400 shadow-sm shadow-pink-400/50'
|
||||
: 'bg-gray-400'
|
||||
} animate-pulse`}></div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -395,4 +395,204 @@ body {
|
|||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
transition: all 300ms ease-out;
|
||||
}
|
||||
|
||||
/* Rarity Effects */
|
||||
/* Mythic/Legendary - Golden glow */
|
||||
.rarity-glow-mythic {
|
||||
box-shadow:
|
||||
0 0 20px rgba(251, 191, 36, 0.4),
|
||||
0 0 40px rgba(251, 191, 36, 0.3),
|
||||
0 0 60px rgba(251, 191, 36, 0.2);
|
||||
animation: mythic-pulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes mythic-pulse {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
0 0 20px rgba(251, 191, 36, 0.4),
|
||||
0 0 40px rgba(251, 191, 36, 0.3),
|
||||
0 0 60px rgba(251, 191, 36, 0.2);
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 30px rgba(251, 191, 36, 0.6),
|
||||
0 0 60px rgba(251, 191, 36, 0.4),
|
||||
0 0 90px rgba(251, 191, 36, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.rarity-particles-mythic::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 20% 30%, rgba(251, 191, 36, 0.3) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 70%, rgba(251, 191, 36, 0.2) 0%, transparent 50%),
|
||||
radial-gradient(circle at 60% 20%, rgba(251, 191, 36, 0.25) 0%, transparent 50%);
|
||||
animation: mythic-sparkle 4s ease-in-out infinite;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
@keyframes mythic-sparkle {
|
||||
0%, 100% { opacity: 0.3; }
|
||||
50% { opacity: 0.7; }
|
||||
}
|
||||
|
||||
/* Rare - Purple glow */
|
||||
.rarity-glow-rare {
|
||||
box-shadow:
|
||||
0 0 15px rgba(168, 85, 247, 0.4),
|
||||
0 0 30px rgba(168, 85, 247, 0.3),
|
||||
0 0 45px rgba(168, 85, 247, 0.2);
|
||||
animation: rare-pulse 2.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes rare-pulse {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
0 0 15px rgba(168, 85, 247, 0.4),
|
||||
0 0 30px rgba(168, 85, 247, 0.3),
|
||||
0 0 45px rgba(168, 85, 247, 0.2);
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 25px rgba(168, 85, 247, 0.5),
|
||||
0 0 50px rgba(168, 85, 247, 0.4),
|
||||
0 0 75px rgba(168, 85, 247, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.rarity-particles-rare::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 30% 40%, rgba(168, 85, 247, 0.2) 0%, transparent 40%),
|
||||
radial-gradient(circle at 70% 60%, rgba(168, 85, 247, 0.15) 0%, transparent 40%);
|
||||
animation: rare-shimmer 3s ease-in-out infinite;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
@keyframes rare-shimmer {
|
||||
0%, 100% { opacity: 0.2; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* Uncommon - Blue glow */
|
||||
.rarity-glow-uncommon {
|
||||
box-shadow:
|
||||
0 0 10px rgba(96, 165, 250, 0.3),
|
||||
0 0 20px rgba(96, 165, 250, 0.2);
|
||||
animation: uncommon-pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes uncommon-pulse {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
0 0 10px rgba(96, 165, 250, 0.3),
|
||||
0 0 20px rgba(96, 165, 250, 0.2);
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 15px rgba(96, 165, 250, 0.4),
|
||||
0 0 30px rgba(96, 165, 250, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.rarity-particles-uncommon::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 40% 30%, rgba(96, 165, 250, 0.15) 0%, transparent 30%);
|
||||
animation: uncommon-twinkle 2.5s ease-in-out infinite;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
@keyframes uncommon-twinkle {
|
||||
0%, 100% { opacity: 0.1; }
|
||||
50% { opacity: 0.3; }
|
||||
}
|
||||
|
||||
/* Enchanted/Secret - Pink/Rainbow glow */
|
||||
.rarity-glow-enchanted {
|
||||
box-shadow:
|
||||
0 0 25px rgba(244, 114, 182, 0.5),
|
||||
0 0 50px rgba(244, 114, 182, 0.4),
|
||||
0 0 75px rgba(244, 114, 182, 0.3);
|
||||
animation: enchanted-pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes enchanted-pulse {
|
||||
0%, 100% {
|
||||
box-shadow:
|
||||
0 0 25px rgba(244, 114, 182, 0.5),
|
||||
0 0 50px rgba(244, 114, 182, 0.4),
|
||||
0 0 75px rgba(244, 114, 182, 0.3);
|
||||
}
|
||||
33% {
|
||||
box-shadow:
|
||||
0 0 30px rgba(168, 85, 247, 0.5),
|
||||
0 0 60px rgba(168, 85, 247, 0.4),
|
||||
0 0 90px rgba(168, 85, 247, 0.3);
|
||||
}
|
||||
66% {
|
||||
box-shadow:
|
||||
0 0 30px rgba(59, 130, 246, 0.5),
|
||||
0 0 60px rgba(59, 130, 246, 0.4),
|
||||
0 0 90px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.rarity-particles-enchanted::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(circle at 25% 25%, rgba(244, 114, 182, 0.3) 0%, transparent 40%),
|
||||
radial-gradient(circle at 75% 75%, rgba(168, 85, 247, 0.2) 0%, transparent 40%),
|
||||
radial-gradient(circle at 50% 50%, rgba(59, 130, 246, 0.25) 0%, transparent 40%);
|
||||
animation: enchanted-rainbow 3s ease-in-out infinite;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
@keyframes enchanted-rainbow {
|
||||
0%, 100% {
|
||||
opacity: 0.4;
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
33% {
|
||||
opacity: 0.6;
|
||||
transform: rotate(120deg);
|
||||
}
|
||||
66% {
|
||||
opacity: 0.5;
|
||||
transform: rotate(240deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hover enhancement for rarity effects */
|
||||
.card-item-container:hover .rarity-glow-mythic {
|
||||
box-shadow:
|
||||
0 0 30px rgba(251, 191, 36, 0.6),
|
||||
0 0 60px rgba(251, 191, 36, 0.5),
|
||||
0 0 90px rgba(251, 191, 36, 0.4);
|
||||
}
|
||||
|
||||
.card-item-container:hover .rarity-glow-rare {
|
||||
box-shadow:
|
||||
0 0 25px rgba(168, 85, 247, 0.6),
|
||||
0 0 50px rgba(168, 85, 247, 0.5),
|
||||
0 0 75px rgba(168, 85, 247, 0.4);
|
||||
}
|
||||
|
||||
.card-item-container:hover .rarity-glow-uncommon {
|
||||
box-shadow:
|
||||
0 0 20px rgba(96, 165, 250, 0.5),
|
||||
0 0 40px rgba(96, 165, 250, 0.4);
|
||||
}
|
||||
|
||||
.card-item-container:hover .rarity-glow-enchanted {
|
||||
box-shadow:
|
||||
0 0 35px rgba(244, 114, 182, 0.7),
|
||||
0 0 70px rgba(244, 114, 182, 0.6),
|
||||
0 0 105px rgba(244, 114, 182, 0.5);
|
||||
}
|
||||
Loading…
Reference in a new issue