来源:听见下雨声

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,瓶子君都会在第二天解答哟!

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

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

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

国庆八天教你怎么写出一个钢琴相关推荐

  1. HTML5 + Javascript 写出一个钢琴

    首发:GitHubClub 原文:juejin.im/post/6879708939190009869 学生时代的我们如果有像郎朗一样的琴技,想必追起女生会非常的容易,但在以前,一架钢琴对普通家庭来说 ...

  2. larvel php restful_Laravel教你简单写出专业的RestfulAPI

    下面由Laravel教程栏目给大家介绍Laravel写出专业的RestfulAPI的方法,希望对需要的朋友有所帮助! Laravel教你简单写出专业的URL 引言 在我们连接了数据库,并且使用迁移功能 ...

  3. 怎样写出一个较好的高速排序程序

    写出一个较好的高速排序程序 高速排序是经常使用的排序算法之中的一个,但要想写出一个又快又准的使用程序,就不是那么简单了 须要注意的事项 首先要写正确.通常使用递归实现.其递归相当于二叉树展开,因此假设 ...

  4. linux mysql 不稳定_linux,mysql:今天写出一个十分弱智的bug!

    今天写出一个十分弱智的bug,记录一下,提醒自己以后别这种犯错,不怕丢人哈~ 在写一个分页查询记录的sql时,要根据添加的时间逆序分页输出,之前的写法是酱紫: select record.a, y.c ...

  5. 写出一个缓存系统的伪代码001

    /*** 写出一个缓存系统的伪代码*/ public class CacheDemo {private Map<String, Object> map = new HashMap<S ...

  6. 给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出(算法导论第三版第十章10.4-5)

    给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出.要求除该树本树的存储空间外只能使用固定量的额外存储空间,且过程中不得修改该树,即使是暂时的修改也不允许. (算法导 ...

  7. 给定一个n节点的二叉树,写出一个O(n)时间非递归过程,将该树每个节点关键字输出,可以使用一个栈作为辅助数据结构(算法导论第十章10.4-3)

    给定一个n节点的二叉树,写出一个O(n)时间非递归过程,将该树每个节点关键字输出,可以使用一个栈作为辅助数据结构 (算法导论第十章10.4-3) template<typename T> ...

  8. 给定一个n节点的二叉树,写出一个O(n)时间递归过程,将该树每个节点关键字输出(算法导论第十章10.4-2)

    给定一个n节点的二叉树,写出一个O(n)时间递归过程,将该树每个节点关键字输出 (算法导论第十章10.4-2) #include <iostream> template<typena ...

  9. 如何写出一个较好的快速排序程序

    写出一个较好的快速排序程序 快速排序是常用的排序算法之一,但要想写出一个又快又准的使用程序,就不是那么简单了 需要注意的事项 首先要写正确.通常使用递归实现.其递归相当于二叉树展开,因此如果要用迭代实 ...

最新文章

  1. 远哥谈 使用WebSocket开发在线实时看远程服务器log日志的工具
  2. 两幅相同大小图像的相似程度的两个评价指标-PSNR和SSIM
  3. 实践自定义UI—RLF...(RelativeLayout LinearLayout FrameLayout....)
  4. 快速WinForm开发
  5. 禁用TwebBrowser右键
  6. 不带头结点链表,尾部插入法创建
  7. linux双机ssh互信方法总结
  8. 华为副总鸿蒙,“哄蒙”败北!华为副总裁落实最新消息,鸿蒙3月31日正式亮剑...
  9. 获取iOS任意线程调用堆栈(四)符号化实战
  10. pca图像压缩python_基于PCA的图像降维及图像重构
  11. [undo]ip address ppp-negotiate
  12. 危险,几条可致命的Linux命令!
  13. 常见危险函数及特殊函数(一)
  14. 上周热点回顾(11.11-11.17)
  15. 弹球小游戏c语言编程,scratch丨(1) 弹球小游戏
  16. Python操作Redis之mset和mget
  17. 跟着 Apple 中国学习顶级中文文案排版
  18. 计算机桌面图标怎么变形了,教您电脑桌面图标变大了怎么办
  19. 查询净值连续增长天数
  20. mac下chrome插件安装位置

热门文章

  1. python怎么做彩票概率_小白学数据小抄放送 Python,R,大数据,机器学习
  2. python只有idle 1种编程环境_《Python编程初学者指南》——1.5 IDLE简介
  3. UBL descriptor ti dm365 引导分析 RBL,UBLU-BOOT
  4. 第四届蓝桥杯真题解析【JavaC组】
  5. 常用word快捷键大全
  6. ArcGIS教程:计算行程成本
  7. leetcode脑筋急转弯
  8. java 实现加减乘除混合运算
  9. Windows sever 2022环境下vmware16 Pro安装XP
  10. 世道沧桑,红尘哀彻,事事悲