背景
钢琴是"乐器之王",但传统学习存在门槛高、成本高、反馈慢等问题。本文介绍如何借助 Web 技术,构建一个零门槛的在线钢琴学习平台。
在线体验:https://www.ytecn.com/lab/piano
源码下载:https://gitee.com/ytecnsong/piano
技术选型
| 类别 | 方案 |
|---|---|
| 框架 | Vue 3 (Composition API) |
| 构建 | Vite |
| 音频 | Tone.js |
| 存储 | localStorage |
| 主题 | 纯 CSS 星空主题 |
为什么选 Tone.js?
Web Audio API 功能强大但 API 复杂,Tone.js 对其进行了高级封装,支持多音 polyphony、音符 scheduling、效果器链等专业功能,代码更简洁。
核心实现
1. 音频引擎
import * as Tone from 'tone'
export const audioEngine = {
synth: null,
async init() {
await Tone.start()
this.synth = new Tone.PolySynth(Tone.Synth).toDestination()
this.synth.volume.value = -6
},
playNote(note, duration = '8n') {
if (this.synth) {
this.synth.triggerAttackRelease(note, duration)
}
}
}
注意:Tone.start() 必须用户触发后调用,这是浏览器自动播放策略要求。
2. 键盘映射
钢琴三个八度,共36个音,黑白键共88个但这里简化为36个:
const LOW_MAPPING = {
'z': 'C3', 'x': 'D3', 'c': 'E3', 'v': 'F3', 'b': 'G3', 'n': 'A3', 'm': 'B3' }
const MID_MAPPING = {
'a': 'C4', 's': 'D4', 'd': 'E4', 'f': 'F4', 'g': 'G4', 'h': 'A4', 'j': 'B4' }
const HIGH_MAPPING = {
'q': 'C5', 'w': 'D5', 'e': 'E5', 'r': 'F5', 't': 'G5', 'y': 'A5', 'u': 'B5' }
黑键映射到字母上方数字键:1#=C#4 2#=D#4 5#=F#5 6#=G#5 7#=A#5
3. 曲目播放与高亮
曲目数据结构:
{
id: 'twinkle',
name: '小星星',
notes: [
{
note: 'C4', duration: 1 },
{
note: 'C4', duration: 1 },
// ...
]
}
播放时逐音符触发,配合 CSS 高亮当前键:
function playSong(song, onNote) {
let i = 0
const timer = setInterval(() => {
if (i >= song.notes.length) {
clearInterval(timer)
return
}
const {
note } = song.notes[i]
audioEngine.playNote(note)
onNote(i) // 高亮回调
i++
}, 500)
}
4. 数据持久化
用户曲目存 localStorage,支持导入导出 JSON:
const STORAGE_KEY = 'yutang-piano-songs'
export function saveSongs(songs) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(songs))
}
export function exportSong(song) {
const blob = new Blob([JSON.stringify(song, null, 2)], {
type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.download = `${
song.name}.json`
a.href = url
a.click()
}
项目结构
yutang-piano/
├── index.html
├── vite.config.js
└── src/
├── main.js
├── App.vue
├── song-manager.js
├── audio-engine.js
└── components/
├── SplashScreen.vue
├── PianoKeyboard.vue
├── SongPanel.vue
├── SongEditor.vue
└── VolumeControl.vue
技术亮点
- 零后端:所有数据存 localStorage,可扩展为 IndexedDB 或云存储
- 跨平台:浏览器即用,PC/平板/手机均可
- 响应式:Composition API 管理状态,逻辑清晰
- 可嵌入:iframe 可嵌入现有教育平台
未来方向
- MIDI 输入支持
- 多音色切换
- 录音回放
- 云端曲库同步
关于作者
汤阴县豫唐网络科技有限公司,专注教育类 Web 产品开发。
相关资源