国庆八天教你怎么写出一个钢琴

    科技2026-08-03  2

    来源:听见下雨声 

    https://juejin.im/post/6879708939190009869

    前言

    国庆节八天来娱乐一下,教你怎么用代码写出一个钢琴????,并用它弹奏歌曲。学生时代的我们如果有像郎朗一样的琴技,想必追起女生会非常的容易,但在以前,一架钢琴对普通家庭来说,消费还蛮高的,所以我们不如自己写一架属于自己的钢琴,哈哈,虽然音效不如真的钢琴,但是能写出来,还挺有成就感的。

    这里不会用到很复杂或者很难的知识,只要按照文章中的步骤一步一步来,最后都可以做出来。心动不如行动,我们赶快开始吧。

    该项目的Gitee地址: 

    https://gitee.com/Dream-Star/piano

    绘制出一个钢琴

    首先我们要创造出钢琴的琴键,这里用ul+li当钢琴的骨架,其中div代表钢琴白键,p代表钢琴黑键。

    <ul>  <li><div></div><p></p></li>  <li><div></div><p></p></li>  <li><div></div></li>  <li><div></div><p></p></li>  <li><div></div><p></p></li>  <li><div></div><p></p></li>  <li><div></div></li>  <li><div></div></li> </ul> 

    写完了骨架我们还要给它加一点样式,至少让琴键的外表看起来更像真正的钢琴。

    /*-------钢琴部分--------*/ ul{   width:480px;   height:360px;   transform: translate(-50%, -50%);   position: absolute;   top: 50%;   left: 50%; } li{   float:left;   list-style-type: none;   position: relative; } li>div{   height: 360px;   width: 60px;   background: rgba(255,255,255,.3);   border: 1px solid;   border-color:rgba(0, 0, 0, .8);   border-bottom-left-radius : 8px;   border-bottom-right-radius: 8px;   box-sizing: border-box;   box-shadow: /*inset  3px 0  10px  #c9c6c6,*/   inset 5px -8px  0  #00000023;   text-align: center;   display:table-cell;   vertical-align: bottom; } li:not(:last-child)>div{   border-right: none; } li>div:hover{   background: rgb(255, 97, 97); } /* 当白键按下时的样式 */ .white_active{   box-shadow: inset 3px -2px  0  #00000036;   background: linear-gradient(45deg, rgba(255,255,255,.7), rgba(255,255,255,.5)); } li>p{   height: 200px;   width: 40px;   background-color: #000;   border-bottom-left-radius : 5.5px;   border-bottom-right-radius: 5.5px;   box-shadow: inset 5px -7px 0 #2c2c2c;   position: absolute;   top:0;   left: 40px;   z-index: 999; } li>p:hover{   background: linear-gradient(45deg, #4c4c4c, #444444); } /* 当黑键按下时的样式 */ .black_active{   box-shadow:inset 3px -5px 0 #2c2c2c; } 

    现在的钢琴就是下面这个样子,外形已经有了,但只是一个画面,我们点击琴键听不到声音。

    给钢琴添加声音

    钢琴有了画面,我们就要开始添加声音了,这里要用到js,首先把音源引入。

    // 给钢琴添加音频 for (var i = 1; i <= 8; i++) {  var addaudio = document.createElement("audio");  addaudio.setAttribute("src", "audios/" + "w" + i + ".ogv");  document.body.appendChild(addaudio); } for (var i = 1; i <= 5; i++) {  var addaudio = document.createElement("audio");  addaudio.setAttribute("src", "audios/" + "b" + i + ".ogv");  document.body.appendChild(addaudio); } 

    音源现在引入了,我们只需要让钢琴琴键按下时,播放对应的音频就行了。这里我们可以实现两种演奏钢琴的方式,一种是直接点击琴键弹奏,另一种是通过我们的键盘按键来弹奏。

    使用键盘上的S~L键操作钢琴白键,E,R,Y,U,I操作钢琴黑键。我们先用js获取到相关的dom。

    let audios = document.getElementsByTagName("audio"), buttons = document.querySelectorAll("ul>li>div"), blacks = document.querySelectorAll("ul>li>p"); 

    ①鼠标点击琴键

    前面我们已经获取到琴键的dom了,现在用for循环按顺序给琴键的dom添加对应的鼠标事件就行了。

    for (var i = 0; i < 8; i++) {  buttons[i].index = i;  buttons[i].onmousedown = function () {  //alert(this.index);  buttons[this.index].classList.add('white_active')  audios[this.index].load();  audios[this.index].play();  };  buttons[i].onmouseup = function () {  buttons[this.index].classList.remove('white_active')  }; } for (var i = 0; i < 5; i++) {  blacks[i].index = i + 8;  blacks[i].onmousedown = function () {  //alert(this.index);  blacks[this.index-8].classList.add('black_active')  audios[this.index].load();  audios[this.index].play();  //alert(audios[this.index].src);  };  blacks[i].onmouseup = function () {  blacks[this.index-8].classList.remove('black_active')  }; } 

    ②键盘当做琴键

    首先我们要知道按键的keyCode键码值,这样才能给按键添加事件。知道相关按键的键值码后放到一个数组里,然后用 for 循环给每个按键添加对应的事件。

    // 操作键盘钢琴白键发出声音 var keyCodes = new Array(83, 68, 70, 71, 72, 74, 75, 76, 69, 82, 89, 85, 73); document.body.onkeydown = function (e) {  for (var i = 0; i < keyCodes.length; i++) {  if (e.keyCode == keyCodes[i]) {  if (i < 8) {  buttons[i].classList.add('white_active');  } else {  blacks[i-8].classList.add('black_active');  }  audios[i].load();  audios[i].play();  }  } };  // 操作键盘钢琴黑键发出声音 document.body.onkeyup = function (e) {  //document.title=e.keyCode;  for (var i = 0; i < keyCodes.length; i++) {  if (e.keyCode == keyCodes[i]) {  if (i < 8) {  buttons[i].classList.remove('white_active');  } else {  blacks[i-8].classList.remove('black_active');  }  }  } };

    到这里我们的钢琴已经能进行弹奏了。

    添加曲库

    光有钢琴没有曲子怎么行呢,我们可以自己在网上找个曲谱,然后添加到对应的地方就可以了。

    首先把布局写出来,这里就不添加那些花里胡哨的样式了。

    <div>  请输入简谱:  <input type="text" id="song" placeholder="请输入歌曲名">  <button id="check">确定</button>  </div> 

    然后开始写逻辑部分,scroe对象是用来存放歌曲信息的,不想去网上找歌曲信息的,可以直接复制最后面部分的简谱。格式类似于{‘歌曲名’:‘歌词和简谱’},这里可以用模板字符串的形式。

    var scroe = {}; var numReg = /[1-9]/g; var wordReg = /[\u4e00-\u9fa5]+/g; var str; var shows; var words; var wordsIndex; var wordsCurrent; var current; function play(){  buttons.forEach((el)=>el.classList.remove('show'))  var songName = song.value;  if(songName === ''){    return alert('请输入歌曲名')  }   if(scroe.hasOwnProperty(songName)){    str = scroe[songName];    shows = str.match(numReg);    words = str.match(wordReg);    wordsIndex = 0;    wordsCurrent = 0;    current = 0;    console.log(songName)    buttons[shows[0]/1 - 1].classList.add('show');    text.textContent = words[0]   }else{    return alert('您输入的歌曲名尚未加入曲库')   } } check.addEventListener('click',play)

    现在的效果图就是下面这个样子????。

    添加歌词和琴键提示

    布局最上面的那部分代码里已经写好了,直接开始写逻辑。

    function start(){  // 显示歌词的部分  if(wordsCurrent>=words[wordsIndex].length-1){  wordsCurrent = 0;  wordsIndex++;  text.textContent = words[wordsIndex]  }else{  wordsCurrent++  }  if(current === shows.length-1){  buttons[shows[shows.length-1]/1 - 1].classList.remove('show');  return console.log('演奏结束',current)  }  var showButton = shows[current+1]/1 - 1;  var hiddenButton = shows[current]/1 - 1;  buttons[hiddenButton].classList.remove('show');  buttons[showButton].classList.add('show');  current++ } 

    然后再在对应的按键事件和鼠标点击事件加上这段代码。

    i == shows[current]-1 ? start() : '';

    现在我们想要的效果基本已经实现。

    加些小的装饰

    我们可以给钢琴按键加上对应的编号,方便我们弹奏。

    // 给琴键加上数字 buttons.forEach((el,index)=>el.textContent = index+1)  window.addEventListener('keydown',function(e){  if(e.keyCode == 86){  if(buttons[0].textContent != ''){  buttons.forEach((el)=>el.textContent = '')  }else{  buttons.forEach((el,index)=>el.textContent = index+1)  }     } }) 

    此时琴键上已经有了对应的编号。我们还可以通过快捷键V实现编号显示与隐藏的切换。我们再给钢琴加个使用说明。

    let x = document.getElementById("btn-js"), y = document.getElementById("js"),  //介绍的隐藏与显示 function hide() {  y.style.display === "block" ? y.style.display = "none" : y.style.display = "block" }  x.addEventListener('click',hide);

    可以看到在演奏歌曲的同时也显示歌词了。

    现在一个简易版的钢琴已经做出来了,外形是不是和真的钢琴挺像的。赶紧用它来演奏歌曲吧????。

    分享一些歌曲的简谱

    晴天

    3243 157 1751 - 166 655 543 2343

    刮风这天我试过握着你手 但偏偏雨渐渐大到我看你不见

    3453 457 2711 - 115 5654 2345 61 6 77

    还要多久我才能在你身边 等到放晴的那天也许我会比较好一点

    3243 157 1751 - 166 655 543 2343

    从前从前有个人爱你很久 但偏偏风渐渐把距离吹得好远

    3453 457 2711 - 115 5654 6712 32 1 1

    好不容易又能再多爱一天 但故事的最后你好像还是说了拜拜

    最长的电影

    12433 345431 12433 321622

    我们的开始 是很长的电影 放映了三年 我票都还留着

    12433 345431[45] 431 32211

    冰上的芭蕾 脑海中还在旋转 望着你 慢慢忘记你

    12433 345431 12433 321622

    朦胧的时间 我们溜了多远 冰刀画的圈 圈起了谁改变

    1[21]433 34543112 4431 432171

    如果再重来 会不会稍显狼狈 爱是不是 不开口才珍贵

    321622 32152211 321622 14321 543323

    再给我两分钟 让我把回忆结成冰 别融化了眼泪 你妆都花了 要我怎么记得

    34363322 23252272 53411 243211

    记得你叫我忘了吧 记得你叫我忘了吧 你说你会哭 不是因为在乎

    同桌的你

    55553457 - 6666465

    明天你是否会想起 昨天你写的日记

    55557654 - 4444321

    明天你是否还惦记 曾经最爱哭的你

    55553457 - 6666465

    老师们都已想不起 猜不出问题的你

    55557654 - 4444321

    我也是偶然翻相片 才想起同桌的你

    111156113 - 2222176

    谁娶了多愁善感的你 谁看了你的日记

    77777125 - 7712171

    谁把你的长发盘起 谁给你做的嫁衣

    最后

    欢迎关注「前端瓶子君」,回复「交流」加入前端交流群!

    回复「算法」,你可以每天学习一道大厂算法编程题(阿里、腾讯、百度、字节等等)或 leetcode,瓶子君都会在第二天解答哟!

    另外,每周还有手写源码题,瓶子君也会解答哟!

    》》面试官也在看的算法资料《《

    “在看和转发”就是最大的支持

    Processed: 0.008, SQL: 9