学习伴侣App v2.1 - 成就系统视觉升级详解

📋 更新概述

本次更新于 2026-02-10 完成,对成就系统进行了全面的视觉升级,引入了稀有度系统和精美的动画效果。

GitHub 仓库https://github.com/dafenqirunrunrun/love-study-app

✨ 核心更新

更新项 更新前 更新后
成就稀有度 5级(传说/史诗/稀有/精良/普通)
成就筛选 按稀有度筛选按钮
解锁效果 简单勾选标记 弹窗动画 + 彩带效果
卡片样式 统一风格 稀有度差异化样式

🎮 稀有度系统设计

稀有度等级

稀有度 颜色 含义 示例成就
🏆 传说 (Legendary) 金色 最难解锁 千锤百炼、五百小时、全年无休
💜 史诗 (Epic) 紫色 较难解锁 任务狂人、专注大师、百日坚持
💎 稀有 (Rare) 蓝色 中等难度 学习达人、十小时、三十篇心得
🔥 精良 (Uncommon) 绿色 较易解锁 勤奋小蜜蜂、初次专注、一周坚持
⚪ 普通 (Common) 灰色 基础成就 初学者、小小富豪、心得初体验

稀有度配置数据结构

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
const rarityConfig = {
legendary: {
name: '传说',
color: 'text-yellow-500',
bg: 'bg-yellow-500',
gradient: 'from-yellow-400 via-yellow-500 to-yellow-600',
glow: 'shadow-yellow-500/50',
ring: 'ring-yellow-400',
bgClass: 'bg-yellow-100 dark:bg-yellow-900/30',
border: 'border-yellow-400',
iconBg: 'from-yellow-400 to-yellow-600'
},
epic: {
name: '史诗',
color: 'text-purple-500',
bg: 'bg-purple-500',
gradient: 'from-purple-400 via-purple-500 to-purple-600',
glow: 'shadow-purple-500/50',
ring: 'ring-purple-400',
bgClass: 'bg-purple-100 dark:bg-purple-900/30',
border: 'border-purple-400',
iconBg: 'from-purple-400 to-purple-600'
},
rare: {
name: '稀有',
color: 'text-blue-500',
bg: 'bg-blue-500',
gradient: 'from-blue-400 via-blue-500 to-blue-600',
glow: 'shadow-blue-500/50',
ring: 'ring-blue-400',
bgClass: 'bg-blue-100 dark:bg-blue-900/30',
border: 'border-blue-400',
iconBg: 'from-blue-400 to-blue-600'
},
uncommon: {
name: '精良',
color: 'text-green-500',
bg: 'bg-green-500',
gradient: 'from-green-400 via-green-500 to-green-600',
glow: 'shadow-green-500/50',
ring: 'ring-green-400',
bgClass: 'bg-green-100 dark:bg-green-900/30',
border: 'border-green-400',
iconBg: 'from-green-400 to-green-600'
},
common: {
name: '普通',
color: 'text-gray-500',
bg: 'bg-gray-500',
gradient: 'from-gray-400 via-gray-500 to-gray-600',
glow: 'shadow-gray-500/50',
ring: 'ring-gray-400',
bgClass: 'bg-gray-100 dark:bg-gray-700/30',
border: 'border-gray-400',
iconBg: 'from-gray-400 to-gray-600'
}
}

🎨 UI组件升级

1. 稀有度筛选按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 稀有度筛选 -->
<div class="flex flex-wrap gap-2 mb-6">
<button
v-for="rarity in ['all', 'legendary', 'epic', 'rare', 'uncommon', 'common']"
:key="rarity"
@click="activeRarityFilter = rarity"
:class="[
'px-4 py-2 rounded-full text-sm font-medium transition-all duration-300',
activeRarityFilter === rarity
? getRarityActiveClass(rarity)
: 'bg-white/30 dark:bg-gray-700/30 text-gray-600 dark:text-gray-300 hover:bg-white/50 dark:hover:bg-gray-700/50'
]"
>
{{ rarity === 'all' ? '🏆 全部' : `✨ ${getRarityLabel(rarity)}` }}
</button>
</div>

2. 成就卡片设计

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
<div
v-for="badge in filteredBadges"
:key="badge.id"
@click="showBadgeDetail(badge)"
class="group relative p-5 rounded-2xl text-center cursor-pointer transition-all duration-500 hover:scale-105 hover:-translate-y-2"
:class="[
isUnlocked(badge.id) ? getRarityBgClass(badge.rarity) : 'bg-white/30 dark:bg-gray-800/30 opacity-70 grayscale',
`rarity-border-${badge.rarity || 'common'}`
]"
>
<!-- 稀有度标签 -->
<div
v-if="isUnlocked(badge.id)"
class="absolute -top-2 left-1/2 transform -translate-x-1/2 px-2 py-0.5 rounded-full text-xs font-bold z-10 rarity-tag-${badge.rarity}"
>
{{ getRarityLabel(badge.rarity) }}
</div>

<!-- 图标发光效果 -->
<div
v-if="isUnlocked(badge.id)"
class="absolute inset-0 rounded-full blur-xl opacity-50 animate-pulse rarity-glow-bg-${badge.rarity}"
></div>

<div class="text-4xl relative z-10 filter drop-shadow-lg">{{ badge.icon }}</div>
</div>

3. 解锁弹窗组件

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
<!-- 成就解锁弹窗 -->
<Transition name="modal">
<div v-if="showUnlockModal" class="fixed inset-0 z-50 flex items-center justify-center p-4">
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm"></div>

<div class="achievement-unlock-modal relative bg-white dark:bg-gray-800 rounded-3xl p-8 max-w-md w-full text-center">
<!-- 成就图标 -->
<div class="relative w-32 h-32 mx-auto mb-6">
<div :class="['unlock-ring', `ring-${unlockingBadge?.rarity}`]"></div>
<div :class="['unlock-icon-bg', `bg-${unlockingBadge?.rarity}`]">
<span class="text-6xl">{{ unlockingBadge?.icon }}</span>
</div>
</div>

<!-- 新成就标签 -->
<div class="inline-flex items-center gap-2 px-4 py-1 rounded-full bg-gradient-to-r from-orange-500 to-pink-500 text-white text-sm font-bold mb-4">
<span>✨</span>
<span>新成就解锁</span>
</div>

<!-- 成就名称 -->
<h3 :class="['text-2xl font-bold mb-2', `text-${unlockingBadge?.rarity}`]">
{{ unlockingBadge?.name }}
</h3>

<!-- 稀有度标签 -->
<div :class="['inline-flex items-center gap-2 px-4 py-2 rounded-full text-sm font-bold', `rarity-tag-${unlockingBadge?.rarity}`]">
<span>{{ getRarityLabel(unlockingBadge?.rarity) }}</span>
</div>
</div>
</div>
</Transition>

🎬 动画效果实现

1. 稀有度边框发光动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 传说级发光 */
.rarity-glow-legendary {
box-shadow: 0 0 20px rgba(251, 191, 36, 0.5),
0 0 40px rgba(251, 191, 36, 0.3),
inset 0 0 20px rgba(251, 191, 36, 0.1);
}

/* 悬停脉冲动画 */
.group:hover .rarity-glow-legendary {
animation: pulse-glow 1.5s infinite;
}

@keyframes pulse-glow {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}

2. 进度条闪光动画

1
2
3
4
5
6
7
8
9
10
.rarity-progress-legendary {
background: linear-gradient(90deg, #fbbf24, #f59e0b, #fbbf24);
background-size: 200% 100%;
animation: shimmer 2s infinite linear;
}

@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}

3. 解锁弹窗缩放动画

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
.achievement-unlock-modal {
animation: unlock-scale 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes unlock-scale {
0% {
transform: scale(0.8);
opacity: 0;
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
opacity: 1;
}
}

/* 弹窗过渡动画 */
.modal-enter-active,
.modal-leave-active {
transition: all 0.3s ease;
}

.modal-enter-from,
.modal-leave-to {
opacity: 0;
}

.modal-enter-from .achievement-unlock-modal,
.modal-leave-to .achievement-unlock-modal {
transform: scale(0.8) translateY(20px);
opacity: 0;
}

4. 解锁环脉冲动画

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
.unlock-ring {
position: absolute;
inset: -8px;
border-radius: 50%;
border: 3px solid;
animation: ring-pulse 2s infinite;
}

@keyframes ring-pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.05);
opacity: 0.7;
}
}

.unlock-ring.ring-legendary {
border-color: #fbbf24;
box-shadow: 0 0 20px rgba(251, 191, 36, 0.5);
}

.unlock-ring.ring-epic {
border-color: #a855f7;
box-shadow: 0 0 20px rgba(168, 85, 247, 0.5);
}

5. 彩带背景动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.confetti-bg {
position: absolute;
inset: 0;
background-image:
radial-gradient(circle at 20% 80%, rgba(251, 191, 36, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(168, 85, 247, 0.3) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(59, 130, 246, 0.3) 0%, transparent 50%),
radial-gradient(circle at 60% 60%, rgba(34, 197, 94, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.3) 0%, transparent 50%);
animation: confetti-rotate 10s infinite linear;
}

@keyframes confetti-rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

📊 成就稀有度分布

当前版本稀有度统计

| 稀有度 | 任务成就 | 专注成就 | 打卡成就 | 积分成就 | 心得成就 | 里程碑 | 习惯 | 特殊 | 总计 |
|——–|———|———|———|———|———|———|——-|——|——|——|
| 🏆 传说 | 1 | 2 | 1 | 1 | 0 | 1 | 0 | 1 | 7 |
| 💜 史诗 | 2 | 3 | 2 | 2 | 0 | 1 | 1 | 0 | 11 |
| 💎 稀有 | 2 | 2 | 2 | 1 | 1 | 0 | 2 | 2 | 12 |
| 🔥 精良 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 6 |
| ⚪ 普通 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 6 |
| 总计 | 7 | 9 | 7 | 6 | 3 | 4 | 3 | 3 | 42 |

注:部分成就根据具体条件分配不同稀有度,上表为参考分布。

🎯 设计亮点

1. 视觉层次

1
2
3
4
5
6
7
8
9
10
成就卡片视觉层次:
┌─────────────────────────────────┐
│ 🏷️ 稀有度标签(顶部) │ ← 最先看到
├─────────────────────────────────┤
│ ✨ 图标 + 发光效果 │ ← 视觉焦点
├─────────────────────────────────┤
│ 📛 名称(渐变色文字) │ ← 重要信息
├─────────────────────────────────┤
│ 📝 描述 + 进度条 │ ← 详情信息
└─────────────────────────────────┘

2. 颜色心理暗示

稀有度 颜色 心理感受 激励效果
传说 金色 尊贵、荣耀 强烈追求欲望
史诗 紫色 神秘、力量 强烈收集欲望
稀有 蓝色 冷静、专业 中等追求欲望
精良 绿色 平衡、成长 稳定进步感
普通 灰色 基础、起点 入门鼓励

3. 交互反馈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
用户交互反馈流程:
┌────────────┐
│ 点击成就 │ → 显示手型光标
└────┬───────┘

┌────────────┐
│ 悬停效果 │ → 卡片放大+发光动画
└────┬───────┘

┌────────────┐
│ 解锁状态 │ → 显示勾选标记
└────┬───────┘

┌────────────┐
│ 点击详情 │ → 弹出解锁动画
└────────────┘

🧪 测试验证

构建测试

1
2
3
4
5
6
7
8
9
$ npm run build

✓ vite v5.4.21 building for production...
✓ 81 modules transformed
✓ built in 10.37s

Output files:
- dist/assets/Achievements-xxx.js (26.64 kB) ← 成就模块
- dist/assets/Achievements-xxx.css (8.65 kB) ← 成就样式

功能验证清单

功能 预期行为 验证状态
稀有度筛选 点击按钮只显示对应稀有度成就
卡片样式 不同稀有度卡片有不同颜色和发光
进度条动画 稀有度对应的闪光动画
解锁弹窗 点击解锁成就显示动画弹窗
响应式适配 移动端卡片布局正常

📱 响应式设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@media (max-width: 640px) {
.grid-cols-2 {
gap: 0.75rem; /* 移动端卡片间距 */
}

.p-5 {
padding: 0.75rem; /* 移动端内边距 */
}

.w-16 {
width: 3.5rem; /* 移动端图标尺寸 */
}

.text-sm {
font-size: 0.75rem; /* 移动端字体 */
}
}

🔧 技术实现要点

1. 稀有度动态类名

1
2
3
4
5
6
7
8
9
10
// 动态获取稀有度样式
const getRarityBgClass = (rarity) => {
const config = rarityConfig[rarity] || rarityConfig.common
return config.bgClass
}

const getRarityTextClass = (rarity) => {
const config = rarityConfig[rarity] || rarityConfig.common
return config.color
}

2. 成就数据增强

1
2
3
4
5
6
7
8
9
10
11
12
const badges = ref([
{
id: 'task_1000',
name: '千锤百炼',
icon: '💎',
description: '完成1000个任务',
category: 'task',
rarity: 'legendary', // 新增稀有度字段
progress: computed(() => ({...}))
},
// ...
])

3. 筛选逻辑

1
2
3
4
5
6
const activeRarityFilter = ref('all')

const filteredBadges = computed(() => {
if (activeRarityFilter.value === 'all') return badges.value
return badges.value.filter(b => (b.rarity || 'common') === activeRarityFilter.value)
})

📈 性能优化

1. CSS 动画优化

  • 使用 transformopacity 触发 GPU 加速
  • 避免动画导致重排(reflow)
  • 使用 will-change 提示浏览器优化
1
2
3
4
5
6
7
.group {
will-change: transform, opacity;
}

.rarity-glow-bg-legendary {
will-change: opacity;
}

2. 条件渲染优化

1
2
<!-- 只在解锁时渲染特效 -->
<div v-if="isUnlocked(badge.id)" class="rarity-glow-effect"></div>

🎨 设计师视角

成就系统设计原则

  1. 视觉差异化

    • 通过颜色、发光强度区分稀有度
    • 传说级使用最强烈的金色发光
    • 普通级使用低调的灰色
  2. 渐进式揭示

    • 未解锁成就使用灰度和透明度处理
    • 保持神秘感,激发解锁欲望
    • 保留文字可读性
  3. 即时反馈

    • 悬停即有放大效果
    • 点击有明确的视觉响应
    • 解锁有仪式感(弹窗+动画)
  4. 情感化设计

    • 稀有度标签增加成就感
    • 解锁弹窗增加惊喜感
    • 闪光动画增强愉悦感

色彩系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 传说级 - 金色系 */
--color-legendary: #fbbf24;
--color-legendary-glow: rgba(251, 191, 36, 0.5);

/* 史诗级 - 紫色系 */
--color-epic: #a855f7;
--color-epic-glow: rgba(168, 85, 247, 0.5);

/* 稀有级 - 蓝色系 */
--color-rare: #3b82f6;
--color-rare-glow: rgba(59, 130, 246, 0.5);

/* 精良级 - 绿色系 */
--color-uncommon: #22c55e;
--color-uncommon-glow: rgba(34, 197, 94, 0.5);

/* 普通级 - 灰色系 */
--color-common: #9ca3af;
--color-common-glow: rgba(156, 163, 175, 0.4);

🔮 后续优化方向

  • 添加成就解锁音效
  • 支持成就分享功能(生成分享图)
  • 添加稀有成就动画(传说级专属动画)
  • 支持自定义成就徽章
  • 添加成就收集统计页面
  • 支持成就序列帧动画

📚 参考资料


设计感悟:成就系统的视觉升级不仅仅是美化,更是一种情感化设计。通过稀有度系统、动画效果和交互反馈,让用户在解锁成就时获得成就感和惊喜感,这是游戏化设计的核心价值。这次升级让”学习”这件枯燥的事情变得有趣味性、有仪式感。