v0.11: 解码晶体卡片 hover 增强 + StatsPanel selector 性能优化

DecodeArray CrystalCard:
- hover 流光边框动画 (echo-border-flow)
- hover 扫描线动画 (echo-scan)
- T标签/tierLabel 上移至顶部 z-10, 不被底部覆盖层遮挡
- hover 底部显示晶体数值 (+6/+22/+90) + 解码提示
- 晶体图形 hover 旋转 200deg + scale 110%

StatsPanel (page.tsx):
- 全量订阅 useGameStore() → shallow 聚合 selector
- 避免每 tick(250ms) 无关字段变化触发重渲染

globals.css:
- 新增 echo-scan / echo-border-flow keyframes

QA: VLM hover 效果 9/10, lint 零错误
This commit is contained in:
2026-06-24 02:08:13 +00:00
parent 803857298f
commit 43c203ebd2
3 changed files with 75 additions and 8 deletions
+34 -7
View File
@@ -408,13 +408,33 @@ function CrystalCard({
return (
<button
onClick={onClick}
className="group relative aspect-square rounded-2xl border border-white/10 bg-black/40 hover:border-white/30 transition-all duration-300 hover:scale-[1.03] focus:outline-none overflow-hidden"
className="group relative aspect-square rounded-2xl border border-white/10 bg-black/40 hover:border-white/40 transition-all duration-300 hover:scale-[1.04] focus:outline-none overflow-hidden"
style={{ boxShadow: `inset 0 0 24px ${tierColor}22` }}
>
{/* v0.11 hover 流光边框 */}
<div
className="absolute inset-0 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none"
style={{
background: `linear-gradient(120deg, transparent 30%, ${tierColor}40 50%, transparent 70%)`,
backgroundSize: "200% 100%",
animation: "echo-border-flow 2s linear infinite",
mixBlendMode: "screen",
}}
/>
{/* v0.11 hover 扫描线 */}
<div className="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none overflow-hidden">
<div
className="absolute inset-x-0 h-px"
style={{
background: `linear-gradient(90deg, transparent, ${tierColor}, transparent)`,
animation: "echo-scan 1.8s ease-in-out infinite",
}}
/>
</div>
{/* 晶体图形 */}
<div className="absolute inset-0 flex items-center justify-center">
<div
className="relative h-12 w-12 transition-transform duration-500 group-hover:rotate-180"
className="relative h-12 w-12 transition-transform duration-500 group-hover:rotate-[200deg] group-hover:scale-110"
style={{ filter: `drop-shadow(0 0 12px ${tierColor}88)` }}
>
<div
@@ -430,15 +450,22 @@ function CrystalCard({
/>
</div>
</div>
{/* 标签 */}
<div className="absolute top-1.5 left-1.5 text-[10px] font-mono px-1.5 py-0.5 rounded bg-black/50" style={{ color: tierColor }}>
{/* v0.11 标签上移至顶部,z-10 避免被底部覆盖层遮挡 */}
<div
className="absolute top-1.5 left-1.5 z-10 text-[10px] font-mono font-semibold px-1.5 py-0.5 rounded bg-black/60 backdrop-blur-sm border"
style={{ color: tierColor, borderColor: `${tierColor}40` }}
>
T{crystal.tier}
</div>
<div className="absolute bottom-1.5 right-1.5 text-[10px] text-white/70">
<div className="absolute top-1.5 right-1.5 z-10 text-[9px] text-white/60 font-mono tracking-wider">
{tierLabel}
</div>
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2">
<span className="text-[11px] font-medium text-white"> </span>
{/* v0.11 hover 底部显示晶体数值 + 解码提示 */}
<div className="absolute inset-x-0 bottom-0 z-10 bg-gradient-to-t from-black/85 via-black/50 to-transparent pt-4 pb-1.5 px-1 text-center opacity-0 group-hover:opacity-100 transition-opacity duration-200">
<div className="text-[12px] font-mono font-bold leading-none" style={{ color: tierColor }}>
+{crystal.value}
</div>
<div className="text-[8px] text-white/60 uppercase tracking-[0.15em] mt-0.5"> </div>
</div>
</button>
);