✨ 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);
|
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') {
|
if (viewMode === 'list') {
|
||||||
return (
|
return (
|
||||||
<div className={`flex items-center p-4 border rounded-lg transition-all duration-200 ${
|
<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 ${
|
<div className={`relative bg-white rounded-xl border transition-all duration-300 overflow-hidden ${
|
||||||
isSelected
|
isSelected
|
||||||
? 'border-purple-500 shadow-xl ring-2 ring-purple-200'
|
? '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 */}
|
{/* Selection Checkbox */}
|
||||||
<div className="absolute top-3 left-3 z-20">
|
<div className="absolute top-3 left-3 z-20">
|
||||||
<input
|
<input
|
||||||
|
|
@ -193,7 +242,11 @@ export default function CardItem({
|
||||||
? 'opacity-100 translate-x-0 pointer-events-auto'
|
? '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'
|
: '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 */}
|
{/* Panel Header */}
|
||||||
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
|
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<div className="flex items-start justify-between mb-2">
|
<div className="flex items-start justify-between mb-2">
|
||||||
|
|
@ -262,6 +315,21 @@ export default function CardItem({
|
||||||
{card.game}
|
{card.game}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-sm text-gray-600 dark:text-gray-400">{card.set_name}</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -396,3 +396,203 @@ body {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
transition: all 300ms ease-out;
|
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