首发:GitHubClub
原文:juejin.im/post/6879708939190009869

学生时代的我们如果有像郎朗一样的琴技,想必追起女生会非常的容易,但在以前,一架钢琴对普通家庭来说,消费还蛮高的,所以我们不如自己写一架属于自己的钢琴,哈哈,虽然音效不如真的钢琴,但是能写出来,还挺有成就感的。

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

该项目的 Gitee 地址:关注微信公众号 逛逛GitHub,回复 钢琴 获取。

绘制出一个钢琴

首先我们要创造出钢琴的琴键,这里用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);

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

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

分享一些歌曲的简谱

该项目的 Gitee 地址:关注微信公众号 逛逛GitHub,回复 钢琴 获取。
推荐阅读
1. 给新手的 11 个 Docker 免费上手项目
2. 我在 GitHub 上找到开源的《植物大战僵尸》
3. 推荐 22 款好用的命令行工具
4. 百度网盘突然大调整喜欢文章,点个在看

HTML5 + Javascript 写出一个钢琴相关推荐

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

    来源:听见下雨声 https://juejin.im/post/6879708939190009869 前言 国庆节八天来娱乐一下,教你怎么用代码写出一个钢琴????,并用它弹奏歌曲.学生时代的我们如 ...

  2. 自己用JavaScript写出吉他和弦图生成器

    前言:因为自己有个设计衣服的想法,但网络搜到的和弦图都太模糊,也对市场上的和弦图生成器不太清楚,于是,用自己所学,使用JavaScript写出和弦图 和弦图画起来也是比较简单的,分析一下,就是横竖线, ...

  3. 用JavaScript写出100以内与7有关的数

    用JavaScript写出100以内与7有关的数,代码如下: a%7==0:表示的是7的倍数: a%10==7:表示的是十位是7的数: parseInt(a/10)==7:表示的是个位是7数: 与7有 ...

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. 基于STC8G1K17的信号转换方案
  2. 第三课 弹性盒模型知识点
  3. php和python和java-Java、PHP和Python各有什么优势 分别能做什么
  4. Golden Software Surfer 17中文版
  5. [java][工具类][Collections]
  6. 自然数 素数 质数_在Java中获取素数的无限列表
  7. matlab uigetfile的用法,matlab中uigetfile的用法
  8. Linux AIO的新归宿:io_uring(介绍,系统调用)
  9. python爬虫ip代理池_爬虫教程-Python3网络爬虫开发——IP代理池的维护
  10. 面向对象的基本概念(二)--UML.类之间的关系
  11. 软件测试国际化测试指标,国际化软件测试内容解析(2)
  12. DSP PMBus 相关知识储备
  13. linux操作系统原理【3】
  14. win8.1 删除这台电脑里,默认的库文件夹
  15. 统计二叉树的叶子结点个数(C语言数据结构)
  16. 洛谷在线测试P1878_舞蹈课
  17. C语言处理按键的 单击(短按),长按,双击,多击 处理
  18. PythonMagick将png转ico
  19. 关于三维制作技术软件的调研分析
  20. android 好友功能,ListView模拟微信好友功能

热门文章

  1. HTTP协议——HTTP报文组成
  2. Vue 打包 静态文件路径问题
  3. macOS Big Sur 11.2候选版本发布黑屏怎么办
  4. 有效利用Oracle官方的免费学习资源
  5. android 多个微信图标,安卓微信发布 8.0.3 正式版,加入了多个新功能!
  6. Libnids--函数调用顺序之nids_init()
  7. 可复制的领导力-负面反馈流程及处理方式
  8. java(五)-迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类
  9. 软件测试面试必备网络知识要点
  10. MySQL基础操作增,删,改,查。