引言
本文介绍如何用javascripty语法写一个简单的琴键(drum ang piano)网页,通过敲击特定键盘(音键),可以发出不同音调。
网址为(https://janice143.github.io/musicKit.github.io/)
正文
1网页布局与功能
网页整体分为3个部分:
1是最顶上居中排布的乐器切换(Drum Kit, Piano Kit)组块,选中响应的kit,背景图和琴键切换为响应的内容,同时kit字体变为白色;
2是页面居中排布的琴键;
3是背景图。
琴键可以通过鼠标点击或者按下响应的键盘来操作,可以发出对应的音效(黄色字体表示音效的名称)。琴键被点击按下后,加以一定的css动画(黄色高亮边框)来区分。
2实现原理
一、 html代码
1 乐器切换组块:
1 2 3 4
| <div id="switch"> <a class="drum chosen" href="#" onclick="addChosenDrum()">Drum Kit</a> <a class="piano" href="#" onclick="addChosen()">Piano Kit</a> </div>
|
2 Drum Kit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <div id="pianoKit"> <div data-key="65" class="key1 key" > <a href="#" onclick="clickPlaySound(65)"> <p class="key-ABC">A</p> <p class="key-tune">DO</p> </a> </div>
<div data-key="83" class="key2 key"> <a href="#" onclick="clickPlaySound(83)"> <p class="key-ABC">S</p> <p class="key-tune">RE</p> </a>
</div> <div data-key="68" class="key3 key"> <a href="#" onclick="clickPlaySound(68)"> <p class="key-ABC">D</p> <p class="key-tune">MI</p> </a>
</div> <div data-key="70" class="key4 key"> <a href="#" onclick="clickPlaySound(70)"> <p class="key-ABC">F</p> <p class="key-tune">FA</p> </a>
</div> <div data-key="71" class="key5 key"> <a href="#" onclick="clickPlaySound(71)"> <p class="key-ABC">G</p> <p class="key-tune">SOL</p> </a>
</div> <div data-key="72" class="key6 key"> <a href="#" onclick="clickPlaySound(72)"> <p class="key-ABC">H</p> <p class="key-tune">LA</p> </a>
</div> <div data-key="74" class="key7 key"> <a href="#" onclick="clickPlaySound(74)"> <p class="key-ABC">J</p> <p class="key-tune">SI</p> </a>
</div>
<audio data-key="65" src="sounds/1.MP3"></audio> <audio data-key="83" src="sounds/2.MP3"></audio> <audio data-key="68" src="sounds/3.MP3"></audio> <audio data-key="70" src="sounds/4.MP3"></audio> <audio data-key="71" src="sounds/5.MP3"></audio> <audio data-key="72" src="sounds/6.MP3"></audio> <audio data-key="74" src="sounds/7.MP3"></audio>
</div>
|
3 Piano Kit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <div id="drumKit" class="chosen"> <div data-key="65" class="key1 key"> <a href="#1" onclick="clickPlaySound(65)"> <p class="key-ABC">A</p> <p class="key-tune">CLAP</p> </a>
</div> <div data-key="83" class="key2 key"> <a href="#1" onclick="clickPlaySound(83)"> <p class="key-ABC">S</p> <p class="key-tune">HIHAT</p> </a>
</div> <div data-key="68" class="key3 key"> <a href="#1" onclick="clickPlaySound(68)"> <p class="key-ABC">D</p> <p class="key-tune">KICK</p> </a>
</div> <div data-key="70" class="key4 key"> <a href="#1" onclick="clickPlaySound(70)"> <p class="key-ABC">F</p> <p class="key-tune">OPENHAP</p> </a>
</div> <div data-key="71" class="key5 key"> <a href="#1" onclick="clickPlaySound(71)"> <p class="key-ABC">G</p> <p class="key-tune">BOOM</p> </a>
</div> <div data-key="72" class="key6 key"> <a href="#1" onclick="clickPlaySound(72)"> <p class="key-ABC">H</p> <p class="key-tune">RIDE</p> </a>
</div> <div data-key="74" class="key7 key"> <a href="#1" onclick="clickPlaySound(74)"> <p class="key-ABC">J</p> <p class="key-tune">SNARE</p> </a>
</div> <div data-key="75" class="key7 key"> <a href="#1" onclick="clickPlaySound(75)"> <p class="key-ABC">K</p> <p class="key-tune">TOM</p> </a>
</div> <div data-key="76" class="key7 key"> <a href="#1" onclick="clickPlaySound(76)"> <p class="key-ABC">L</p> <p class="key-tune">TINK</p> </a> </div> <audio data-key="65" src="sounds/clap.wav"></audio> <audio data-key="83" src="sounds/hihat.wav"></audio> <audio data-key="68" src="sounds/kick.wav"></audio> <audio data-key="70" src="sounds/openhat.wav"></audio> <audio data-key="71" src="sounds/boom.wav"></audio> <audio data-key="72" src="sounds/ride.wav"></audio> <audio data-key="74" src="sounds/snare.wav"></audio> <audio data-key="75" src="sounds/tom.wav"></audio> <audio data-key="76" src="sounds/tink.wav"></audio> </div>
|
二、css代码
1 实现顶部的切换组块(Drum Kit, Piano Kit)固定在窗口的某个位置,不占位置,脱离标准文档流;居中排布
1 2 3 4
| position: fixed; left:0; right:0; margin:0 auto;
|
2 实现琴键居中排布:用Flex 布局实现垂直、水平居中。
任何一个容器都可以指定为 Flex 布局(flex容器),display: flex即可实现。采用 Flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称”Item”。
容器具有6个属性:
· flex-direction:水平主轴的方向
· flex-wrap:如果主轴拍不下,可以用这个属性来设置换行的形式
· flex-flow:合并了flex-direction 和flex-wrap的功能,用这个属性可以同时设置这两个属性。
· justify-content:定义了item在主轴(水平方向上)的对齐方式
·align-items:定义了item在垂直方向上的对齐方式
· align-content:定义了多跟轴线的对齐方式
1 2 3 4 5 6 7 8 9
| #drumKit,#pianoKit{ display: flex; flex:1; min-height: 90vh;
justify-content: center; }
|
90vh表示占窗口(当前页面窗口)大小的90%。
3 键盘被点击时,js会添加playing类,其css布局为
1 2 3 4 5
| .playing{ transform: scale(1.1); border-color: #ffc600; box-shadow: 0 0 1rem #ffc600; }
|
4 drum kit 和piano kit被选中时,js会添加chosen类名。设置css代码让选中字体变为白色以区分
1 2 3
| #switch .chosen{ color:white; }
|
三、 javascript代码
1 切换键盘(drum kit, piano kit)
对于drum kit:点击drum,添加.chosen,同时去掉piano kit 的.chosen类名;显示drum琴键,隐藏piano琴键;显示响应背景background-image。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| function addChosen(){ const chosen = document.getElementsByClassName("piano"); const notChosen = document.getElementsByClassName("drum"); chosen[0].classList.add('chosen'); notChosen[0].classList.remove('chosen'); const notChosenKit = document.getElementById("drumKit"); notChosenKit.classList.remove('chosen'); notChosenKit.style.display = "none"; const chosenKit = document.getElementById("pianoKit"); chosenKit.style.display = "flex"; chosenKit.classList.add('chosen'); const wallpaper = document.getElementsByTagName("html"); wallpaper[0].style.backgroundImage="url(./pianoback.jpg)"; } function addChosenDrum(){ const chosen = document.getElementsByClassName("drum"); const notChosen = document.getElementsByClassName("piano"); chosen[0].classList.add('chosen'); notChosen[0].classList.remove('chosen'); const notChosenKit = document.getElementById("pianoKit"); notChosenKit.classList.remove('chosen'); notChosenKit.style.display = "none"; const chosenKit = document.getElementById("drumKit"); chosenKit.style.display = "flex"; chosenKit.classList.add('chosen'); const wallpaper = document.getElementsByTagName("html"); wallpaper[0].style.backgroundImage="url(./drumback.jpg)"; }
|
2 键盘敲击琴键,用keycode标注,给对应琴键添加.playing类名。设置audio.play发出音效。
1 2 3 4 5 6 7 8 9 10 11
| function playSound(e){ const audio = document.querySelector(`.chosen audio[data-key="${e.keyCode}"]`); if (!audio) return; const key = document.querySelector(`.chosen div[data-key="${e.keyCode}"]`); key.classList.add('playing'); audio.currentTime = 0;
audio.play(); }
|
3 如果连续敲击多个琴键,多个琴键都会显示过渡特效(黄色Border,放大1.2倍),为了让最后一个琴键之前的琴键过滤样式去掉,可以利用transitionend事件,让已经过渡的琴键去掉.playing类名。
1 2 3 4 5 6 7 8 9 10
| function removeTransition(e){ if (e.propertyName !='transform') return; this.classList.remove('playing'); }
const keys = document.querySelectorAll('.key'); keys.forEach(key=>key.addEventListener('transitionend',removeTransition)); window.addEventListener('keydown',playSound);
|
4 鼠标点击也可以实现琴键发出音效。设置onclick事件,传入keycode参数。
1 2 3 4 5 6 7 8 9 10 11
| function clickPlaySound(keycode){ const audio = document.querySelector(`.chosen audio[data-key="${keycode}"]`); if (!audio) return; const key = document.querySelector(`.chosen div[data-key="${keycode}"]`); key.classList.add('playing'); audio.currentTime = 0; audio.play(); };
|
总结
完整代码放在了Github上,如果读者有兴趣,不妨试一试。