歌词记忆大师 - 经典歌词段落记忆工具鸿蒙PC用Electron框架技术实现详解
摘要: 本项目开发了一款基于鸿蒙系统的经典歌词记忆应用,采用科学算法提升学习效率。核心功能包括智能学习队列(根据掌握程度动态调整优先级)、多难度歌词填空(隐藏30%-70%字符)及进度追踪系统。技术架构选用鸿蒙Electron结合Web前端技术,实现跨平台兼容与高性能数据可视化。应用通过间隔重复算法对抗遗忘曲线,将歌词记忆效果量化为可追踪的掌握度指标,帮助用户系统化记忆经典歌词。项目代码已开源,欢
·
欢迎加入开源鸿蒙PC社区:
https://harmonypc.csdn.net/
atomgit仓库地址:https://atomgit.com/Math_teacher_fan/jingdiangeci






一、项目概述与设计理念
1.1 应用背景
歌词是音乐的灵魂,记忆歌词是很多音乐爱好者的愿望。然而,传统的死记硬背方式效率低下,容易遗忘。本应用旨在通过科学的学习算法和间隔重复技术,帮助用户高效记忆经典歌词。
核心问题:
- 遗忘规律:根据艾宾浩斯遗忘曲线,不复习就会快速遗忘
- 学习效率:传统方式效率低,缺乏针对性练习
- 进度追踪:难以量化记忆效果
解决方案:
┌─────────────────────────────────────────────────────┐
│ │
│ 学习效率提升 │
│ ├─ 智能优先级队列:先学难的 │
│ ├─ 间隔重复:科学复习时间点 │
│ └─ 即时反馈:立即知道对错 │
│ │
│ 记忆效果量化 │
│ ├─ 掌握度统计:每句歌词的掌握程度 │
│ ├─ 进度追踪:整体学习进度 │
│ └─ 曲线可视化:记忆效果图形化 │
│ │
└─────────────────────────────────────────────────────┘
1.2 技术架构选型
| 技术方案 | 优势 | 适用场景 |
|---|---|---|
| 鸿蒙Electron | 原生性能优秀,系统集成度高 | 需要与鸿蒙系统深度交互的应用 |
| Web前端技术 | 开发效率高,跨平台能力强 | 快速迭代,界面复杂的应用 |
| Canvas | 图表绘制能力强 | 科学数据可视化 |
| LocalStorage | 数据持久化简单 | 单机应用,数据量较小的场景 |
1.3 功能模块划分
┌─────────────────────────────────────────────────────┐
│ 功能模块架构 │
├─────────────────────────────────────────────────────┤
│ 📖 学习模式 │ ✍️ 测验模式 │ 📚 歌词库 │
├─────────────────────────────────────────────────────┤
│ 📊 学习进度 │ ❤️ 收藏夹 │ │
└─────────────────────────────────────────────────────┘
二、核心代码实现详解
2.1 学习队列管理实现
学习队列是应用的核心功能,根据歌词的掌握程度动态调整学习顺序。
const StudyModule = {
buildStudyQueue() {
const allLyrics = [...lyricsDatabase, ...DataManager.getLyrics()];
const progress = DataManager.getProgress();
studyQueue = [];
// 遍历所有歌词和歌词行
allLyrics.forEach(lyrics => {
lyrics.lyrics.forEach((line, index) => {
const lineProgress = progress[lyrics.id]?.lines[index];
const wrongCount = lineProgress?.wrong || 0;
const correctCount = lineProgress?.correct || 0;
// 计算优先级:错误次数越多、正确次数越少,优先级越高
const priority = wrongCount - correctCount + (correctCount < 3 ? 2 : 0);
studyQueue.push({
lyricsId: lyrics.id,
song: lyrics.song,
artist: lyrics.artist,
lineIndex: index,
text: line,
priority: priority
});
});
});
// 按优先级降序排列
studyQueue.sort((a, b) => b.priority - a.priority);
}
};
优先级计算公式:
priority = wrongCount - correctCount + (correctCount < 3 ? 2 : 0)
示例分析:
歌词A: wrong=0, correct=1 → priority = 0 - 1 + 2 = 1 (刚开始学习)
歌词B: wrong=3, correct=1 → priority = 3 - 1 + 2 = 4 (需要加强)
歌词C: wrong=1, correct=5 → priority = 1 - 5 + 0 = -4 (已掌握)
歌词D: wrong=0, correct=0 → priority = 0 - 0 + 2 = 2 (从未学习)
2.2 歌词填空算法实现
根据不同难度等级,动态隐藏歌词中的字符。
hideCharacters(text, count) {
if (count <= 0) return text;
const chars = text.split('');
const indices = [];
// 选择要隐藏的字符索引
while (indices.length < count && indices.length < chars.length) {
const idx = Math.floor(Math.random() * chars.length);
if (chars[idx] !== ' ' && !indices.includes(idx)) {
indices.push(idx);
}
}
// 按索引排序(保持原有顺序)
indices.sort((a, b) => a - b);
// 生成显示文本
let result = '';
for (let i = 0; i < chars.length; i++) {
if (indices.includes(i)) {
result += '<span class="blank">_</span>';
} else {
result += chars[i];
}
}
return result;
},
getHideCount(difficulty) {
switch (difficulty) {
case 'easy': return Math.ceil(text.length * 0.3); // 隐藏30%
case 'medium': return Math.ceil(text.length * 0.5); // 隐藏50%
case 'hard': return Math.ceil(text.length * 0.7); // 隐藏70%
default: return Math.ceil(text.length * 0.5);
}
}
难度等级效果:
原歌词:"天青色等烟雨 而我在等你"
↓
简单模式(30%):"天青色等烟___ 而我___你" (隐藏3个字符)
中等模式(50%):"天青色___雨 而___等你" (隐藏5个字符)
困难模式(70%):"天青色__烟___ 而___等__" (隐藏7个字符)
2.3 进度追踪系统实现
updateProgress(lyricsId, lineIndex, correct) {
const progress = this.getProgress();
// 初始化歌曲进度
if (!progress[lyricsId]) {
progress[lyricsId] = { lines: {}, mastered: 0, total: 0 };
}
// 初始化歌词行进度
if (!progress[lyricsId].lines[lineIndex]) {
progress[lyricsId].lines[lineIndex] = { correct: 0, wrong: 0 };
}
// 更新正确/错误次数
if (correct) {
progress[lyricsId].lines[lineIndex].correct++;
} else {
progress[lyricsId].lines[lineIndex].wrong++;
}
// 计算已掌握的句子
// 掌握条件:正确次数 >= 3 且 正确次数 > 错误次数
let mastered = 0;
const lines = progress[lyricsId].lines;
for (let key in lines) {
if (lines[key].correct >= 3 && lines[key].correct > lines[key].wrong) {
mastered++;
}
}
progress[lyricsId].mastered = mastered;
this.saveProgress(progress);
return progress;
}
掌握判定条件:
掌握 = (正确次数 >= 3) AND (正确次数 > 错误次数)
示例:
歌词行1: correct=3, wrong=0 → mastered ✓
歌词行2: correct=3, wrong=2 → mastered ✓
歌词行3: correct=2, wrong=0 → not mastered (正确次数不足)
歌词行4: correct=1, wrong=2 → not mastered (错误多于正确)
歌词行5: correct=5, wrong=1 → mastered ✓
2.4 记忆曲线绘制实现
使用Canvas绘制艾宾浩斯遗忘曲线。
drawMemoryCurve() {
const canvas = document.getElementById('memoryCurve');
const ctx = canvas.getContext('2d');
canvas.width = 600;
canvas.height = 300;
ctx.clearRect(0, 0, 600, 300);
// 绘制网格线
ctx.strokeStyle = '#e2e8f0';
ctx.lineWidth = 1;
for (let i = 0; i <= 5; i++) {
const y = 30 + i * 50;
ctx.beginPath();
ctx.moveTo(50, y);
ctx.lineTo(550, y);
ctx.stroke();
}
// 绘制记忆曲线
ctx.beginPath();
ctx.strokeStyle = '#8b5cf6';
ctx.lineWidth = 3;
const points = [];
// 艾宾浩斯遗忘曲线公式: y = e^(-t/S)
// 其中 S=1 (时间常数)
for (let x = 50; x <= 550; x += 10) {
const progress = (x - 50) / 500;
// 归一化到0-1范围,然后映射到y坐标
const memoryRetention = Math.exp(-3 * progress);
const y = 250 - 200 * memoryRetention;
points.push({ x, y });
}
// 绘制曲线
ctx.moveTo(points[0].x, points[0].y);
points.forEach(p => ctx.lineTo(p.x, p.y));
ctx.stroke();
}
记忆曲线公式:
艾宾浩斯遗忘曲线:
R = e^(-t/S)
其中:
R = 记忆保留率 (0-1)
t = 时间
S = 时间常数 (约1天)
曲线特点:
- 20分钟后:记忆保留约58%
- 1小时后:记忆保留约44%
- 1天后:记忆保留约33%
- 6天后:记忆保留约25%
三、歌词数据库设计
3.1 歌词数据模型
const lyricsDatabase = [
{
id: 1,
song: '平凡之路',
artist: '朴树',
category: 'folk',
categoryName: '民谣音乐',
lyrics: [
'徘徊着的 在路上的',
'你要走吗',
'via via',
'易碎的 骄傲着',
'那也曾是我的模样',
// ... 更多歌词行
]
}
];
3.2 分类管理
const categoryMap = {
pop: '流行音乐',
rock: '摇滚音乐',
folk: '民谣音乐',
classic: '经典老歌',
movie: '影视金曲'
};
预置歌词统计:
| 分类 | 歌曲数量 | 代表歌曲 |
|---|---|---|
| 民谣音乐 | 2首 | 平凡之路、董小姐 |
| 流行音乐 | 2首 | 青花瓷、演员 |
| 摇滚音乐 | 2首 | 海阔天空、夜空中最亮的星 |
| 经典老歌 | 1首 | 后来 |
| 影视金曲 | 1首 | 匆匆那年 |
四、测验模式实现
4.1 随机选题算法
startQuiz() {
// 获取所有歌词
const allLyrics = [...lyricsDatabase, ...DataManager.getLyrics()];
// 随机选择一首歌曲
const randomLyrics = allLyrics[Math.floor(Math.random() * allLyrics.length)];
// 随机选择一句歌词
const randomLineIndex = Math.floor(Math.random() * randomLyrics.lyrics.length);
this.currentQuiz = {
lyricsId: randomLyrics.id,
song: randomLyrics.song,
artist: randomLyrics.artist,
lineIndex: randomLineIndex,
text: randomLyrics.lyrics[randomLineIndex],
context: this.getContext(randomLyrics.lyrics, randomLineIndex)
};
}
4.2 上下文获取
getContext(lyrics, index) {
// 获取当前行的前一句和后一句作为上下文
const before = index > 0 ? lyrics[index - 1] : '';
const after = index < lyrics.length - 1 ? lyrics[index + 1] : '';
return { before, current: '____________', after };
}
4.3 答案验证
checkAnswer(user, correct) {
// 标准化处理:去除空格、转小写
const normalize = (str) => str.replace(/\s+/g, '').toLowerCase();
return normalize(user) === normalize(correct);
}
// 匹配规则说明:
// "天青色等烟雨" 匹配 "天青色等烟雨" ✓
// "天青色 等烟雨" 匹配 "天青色等烟雨" ✓
// "天青色等烟雨 " 匹配 "天青色等烟雨" ✓
// "天青色等烟" 匹配 "天青色等烟雨" ✗
五、数据持久化架构
5.1 LocalStorage数据结构
// 进度数据结构
{
"lyrics_progress": {
"1": { // 歌词ID
"lines": {
"0": { "correct": 3, "wrong": 0 }, // 第0行
"1": { "correct": 2, "wrong": 1 } // 第1行
},
"mastered": 2, // 已掌握行数
"total": 15 // 总行数
}
},
"lyrics_favorites": [1, 3, 5], // 收藏的歌词ID数组
"lyrics_custom": [ // 自定义歌词
{
"id": 1234567890,
"song": "自定义歌曲",
"artist": "歌手名",
"category": "pop",
"lyrics": ["歌词1", "歌词2"]
}
]
}
5.2 数据管理接口
const DataManager = {
// 获取进度
getProgress() {
return JSON.parse(localStorage.getItem('lyrics_progress') || '{}');
},
// 保存进度
saveProgress(progress) {
localStorage.setItem('lyrics_progress', JSON.stringify(progress));
},
// 获取收藏
getFavorites() {
return JSON.parse(localStorage.getItem('lyrics_favorites') || '[]');
},
// 保存收藏
saveFavorites(favorites) {
localStorage.setItem('lyrics_favorites', JSON.stringify(favorites));
},
// 获取自定义歌词
getLyrics() {
return JSON.parse(localStorage.getItem('lyrics_custom') || '[]');
},
// 保存自定义歌词
saveLyrics(lyrics) {
localStorage.setItem('lyrics_custom', JSON.stringify(lyrics));
}
};
六、UI设计与交互体验
6.1 视觉设计风格
色彩方案:
| 颜色 | 色值 | 用途 |
|---|---|---|
| 主色调 | #8b5cf6 | 按钮、进度条、高亮 |
| 辅助色 | #3b82f6 | 渐变、图标 |
| 成功色 | #10b981 | 正确答案 |
| 警告色 | #f59e0b | 提示按钮 |
| 错误色 | #ef4444 | 错误答案 |
布局特点:
- 卡片式设计,信息层次清晰
- 渐变背景增强视觉效果
- 响应式布局,适配不同屏幕尺寸
6.2 学习模式UI
<div class="lyrics-display">
<div class="song-info">
<span class="song-name">平凡之路</span>
<span class="artist-name">朴树</span>
</div>
<div class="lyrics-content">
<div class="lyric-line current">
徘徊着的 <span class="blank">_</span> 上面的
</div>
</div>
</div>
6.3 响应式设计
@media (max-width: 768px) {
.app-header {
flex-direction: column;
gap: 15px;
}
.nav-btn {
min-width: calc(50% - 5px);
}
.progress-overview {
grid-template-columns: 1fr;
}
}
七、技术亮点与创新
7.1 智能学习算法
学习算法流程图
┌─────────────────────────────────────────────────────┐
│ │
│ 1. 构建学习队列 │
│ ├─ 遍历所有歌词 │
│ ├─ 计算每句优先级 │
│ └─ 按优先级排序 │
│ │
│ 2. 学习过程中 │
│ ├─ 显示填空歌词 │
│ ├─ 用户输入答案 │
│ ├─ 判定对错 │
│ └─ 更新进度数据 │
│ │
│ 3. 队列调整 │
│ ├─ 答对:移出队列 │
│ └─ 答错:重新排序(优先级提高) │
│ │
└─────────────────────────────────────────────────────┘
7.2 间隔重复原理
复习时间点(基于艾宾浩斯曲线):
第一次学习 → 20分钟后复习
第一次复习 → 1小时后复习
第二次复习 → 1天后复习
第三次复习 → 6天后复习
第四次复习 → 1个月后复习
第五次复习 → 6个月后复习
本应用通过调整优先级实现:
- 错误越多,复习频率越高
- 正确越多,复习频率越低
7.3 数据可视化
// 记忆曲线绘制
const memoryRetention = Math.exp(-3 * timeNormalized);
// 绘制从 100% 到 25% 的衰减曲线
八、总结与展望
8.1 项目成果
| 功能模块 | 状态 | 核心特性 |
|---|---|---|
| 学习模式 | ✅ | 填空学习、难度选择、优先级队列 |
| 测验模式 | ✅ | 随机测验、上下文提示、正确率统计 |
| 歌词库 | ✅ | 8首预置歌词、分类筛选、自定义添加 |
| 学习进度 | ✅ | 记忆曲线、掌握统计 |
| 收藏夹 | ✅ | 收藏管理、快速访问 |
8.2 未来规划
- 发音朗读:加入歌词朗读功能
- 歌曲播放:集成音频播放,跟唱学习
- 云端同步:支持多设备数据同步
- AI推荐:根据学习情况推荐适合的歌词
8.3 技术价值
歌词记忆大师应用展示了如何在鸿蒙PC平台上开发教育类应用,为开发者提供了以下参考:
- 智能学习算法:优先级队列和间隔重复的实现
- Canvas可视化:记忆曲线的绘制技术
- 数据持久化:localStorage的实践应用
- 模块化架构:功能解耦和代码组织
通过本项目的实践,开发者可以快速掌握教育类应用开发的核心技术,为构建更多优秀应用奠定基础。
更多推荐



所有评论(0)