1. HTML로 UI를 만들고,
audio 태그를 만들어 오디오 파일을 src로 걸어둔다
<div class="drum_kit">
<div data-key="KeyA" class="key">
<h3>A</h3>
<span class="sound">Clap</span>
</div>
<div data-key="KeyH" class="key">
<h3>H</h3>
<span class="sound">HiHat</span>
</div>
<div data-key="KeyG" class="key">
<h3>G</h3>
<span class="sound">OpenHat</span>
</div>
.
.
.
</div>
<audio data-key="KeyA" src="./sound/clap.wav"></audio>
<audio data-key="KeyH" src="./sound/hihat.wav"></audio>
<audio data-key="KeyG" src="./sound/openhat.wav"></audio>
.
.
.
2. HTML의 UI를 담당하는 태그와 audio 태그에
dataset 속성을 이용하여 한 쌍씩 만들어 놓는다
예시. dataset 속성이 data-key = "KeyH"
인 한 쌍
<.html>
// UI
<div data-key="KeyH" class="key">
<h3>H</h3>
<span class="sound">HiHat</span>
</div>
// audio
<audio data-key="KeyH" src="./sound/hihat.wav"></audio>
3. 키를 눌렀을 때
누른 키와 같은 dataset 속성을 가진 audio 요소를 재생
누른 키와 한 쌍인 요소가 없다면 return만 반환
<.js>
window.addEventListener('keydown', (e) => {
// audio 태그 중 dataset.key 가 누르는 키의 .code 값과 같은 것 (data-key = "KeyH")
const audio = document.querySelector(`audio[data-key = "${e.code}"]`)
// 클래스명이 key이고 data-key의 값이 누르는 키의 .code 값과 같은 것 (data-key = "KeyH")
const key = document.querySelector(`.key[data-key = "${e.code}"]`)
if (!audio) return;
// currentTime: 음악의 재생 지점(초 단위)
// 값이 0인 경우 처음부터 소스를 재생
audio.currentTime = 0;
audio.play()
4. 키가 눌릴 때 이벤트가 발생한 키 값과 일치하는 dataset 속성을 가진
요소의 classList에 'playing'을 추가해 트랜지션을 주고
transitionend
이벤트를 통해 트랜지션이 끝날 때 'playing'을 제거
const keys = document.querySelectorAll('.key');
keys.forEach(el => {
// 각각의 요소가 트랜지션이 끝나면 클래스명이 제거됨
el.addEventListener('transitionend', () => {
el.classList.remove('playing')
})
})
누르는 키와 audio 태그를 같은 값을 가진 한 쌍으로 하기 위해
KeyBoardEvent.keyCode
를 dataset 속성
에 썼는데
에디터가 keyCode로 표기하길래 MDN을 찾아보니
더는 권장하지 않는 속성이라고 쓰여있었다.
그래서 KeyBoardEvent.code
속성을 사용해서 접근하였다.
KeyboardEvent의 code 속성
너무 멋있어요!