HTML5 + Javascript 寫出一個鋼琴

ios

web

首發: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>
<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);
}
// 給鋼琴添加音頻
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");

微信


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')
};
}

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');
}
}
}
};

// 操做鍵盤鋼琴白鍵發出聲音
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>

<div>
請輸入簡譜:
<input type="text" id="song" placeholder="請輸入歌曲名">
<button id="check">肯定</button>
</div>


而後開始寫邏輯部分,scroe 對象是用來存放歌曲信息的,不想去網上找歌曲信息的,能夠直接複製最後面部分的簡譜。格式相似於 {‘歌曲名’:‘歌詞和簡譜’} ,這裏能夠用模板字符串的形式。app

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)

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++
}
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++
}

而後再在對應的按鍵事件和鼠標點擊事件加上這段代碼。dom

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)
}
}
})

// 給琴鍵加上數字
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);

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. 百度網盤忽然大調整
 
     
     
      
      
               
      
 
     


在看 

本文分享自微信公衆號 - 逛逛GitHub(ggGithub)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。ide

相關文章
相關標籤/搜索