Wesbos - Drum Kit


완성본

키보드를 누르면 해당 키값에 맞는 드럼 사운드가 재생되는 간단한 웹페이지다.
우선, 각 키를 눌렀을 때 기능해야하는 것들 + 웹페이지 작동 원리와 로직은 이하와 같다!


로직

키보드를 눌렀을 때?

  1. 해당 키값 찾기 (keyCode)
  2. 해당 오디오 태그 값 찾아서 play
  3. 연타 가능하도록 Currenttime = 0으로 설정
  4. css 적용 (.playing 삽입)
  5. 적용된 css 제거하며 역트랜지션 구현 가능하도록 구현

코딩 과정

1. 해당 키값 찾기 (keyCode)

각 키보드에는 고유한 키값이 존재한다.
http://keycode.info/ 이곳에 들어가 각 키값(keyCode)들을 알아보자.

  1. html파일에서 key블록을 구성하고 있는 div에 data-key = “nn”형식으로 키값을 부여한다.

    1
    2
    3
    <div data-key="65" class="key">
    <kbd>A<kbd>
    </div>
    변경된 배열

    참고로 본인은 기존에 설정 되어있던 [a-s-d-f-g-h-j-k-l] 배열이 불편하다 생각이 들어 오투잼 배열로 키보드 배열을 변경했음.
    (div와 audio 태그 내의 data-key만 변경해주면 쉽게 변경 가능!)

  2. 완료했다면, JS파일로 돌아가 keys라는 변수를 querySelectorAll을 통해 지정해준다.

    1
    const keys = document.querySelectorAll('.key');
  3. 이제 키보드를 눌렀다는 event를 컴퓨터가 감지할 수 있도록
    addEventListener를 통해 keydown 이벤트에 반응하는 함수를 만들어준다.

    1
    window.addEventListener('keydown', keydown);

    forEach

    💡 배열에 사용되는 함수!
    편리하게도 배열의 각 요소에 대한 callback 함수를 적용할 수 있음

    1
    2
    3
    4
    5
    6
    //예시
    const array1 = ['가', '나', '다'];
    array1.forEach((element) => console.log(element));
    // 예상 아웃풋: "가"
    // 예상 아웃풋: "나"
    // 예상 아웃풋: "다"
  4. 이제 위에서 설정한 keydown 이벤트를 들을 수 있는 keydown함수를 작성해준다.
    그리고 console.log를 통해 누른 키에 해당하는 keyCode값을 콘솔 창에 찍어보자.

    1
    2
    3
    function keydown(e) {
    console.log(e.keyCode);
    }

2. 키 값을 활용해 audio를 play

audio에 입력된 data-key와 입력된 키의 keyCode가 상호 연결되어,
입력된 키에 해당하는 audio만 재생이 돼야 한다.

⇒ 따라서, audio를 따로 변수처리 해서 해당 오디오 파일을 재생시켜줘야 함

1
2
3
4
5
6
7
8
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);

// 이렇게 e.keyCode를 변수화 하여 audio에 대입시키면 audio는 특정 audio,
// 즉 눌러진 키에 해당하는 사운드만 플레이 될 수 있도록 지정할 수 있는 것!

audio.play();

//이제 play함수를 적용시키면 눌려진 키 값에 해당하는 사운드만 재생되는 것을 확인 할 수 있다.

3. currentTime을 활용한 연타 기능 추가

But… 키값에 맞는 오디오가 잘 플레이 되기는 하지만, 키를 연속적으로 눌러도 한 사운드의 재생이 끝날 때 까지 다음 키의 재생이 이루어지지 않는 것을 확인할 수 있다.

⇒ 따라서 currentTime을 활용해 키가 연속적으로 눌렸을 때 이에 즉각적으로 play() 함수가 반응되도록 해보자.

1
2
3
4
5
6
function keydown(e) {
console.log(e.keycode); //이제는 필요 없는 코드
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
audio.currentTime = 0;
audio.play();
}

currentTime

currentTime은 HTML 내의

  • currentTime = n; 을 통해 특정 수를 부여하면 audio는 해당 숫자에 해당되는 초로 이동한다.
    이에 따라, 위에서와 같이 currentTime=0; 을 사용하게 되면
    어떤 키가 눌렸을 때 해당 audio의 현재 플레이 위치는 0이 되는 것이다.
    즉, “재생이 정지된 것과 같은 효과 ⇒ 그에 따른 연타 가능”의 기능이 적용될 수 있는 것!

4. CSS 적용!

이제 CSS 적용만 하면 된다 :)
audio에서 적용했던 논리와 동일하게 내가 누른 키에 해당하는

에만 css가 적용되도록 하면 됨!

1
2
3
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);

key.classList.add('playing'); //미리 작성해둔 css 클래스를 적용

하지만….

트랜지션이 안돌아 옴...

위의 코드만으론 css가 “적용”되기만 할 뿐, 키보드를 떼었을 때 css가 제거되지는 않는다.


5. 역트랜지션 구현

위의 키보드 div들의 .playing CSS의 적용과 트랜지션이 끝났을 때 곧바로 CSS가 제거되도록 코드를 짜주면 된다.

1
2
3
4
5
6
keys.forEach((key) => key.addEventListener('transitionend', transitionRemove));

function transitionRemove(e) {
if (e.propertyName !== 'transform') return;
this.classList.remove('playing'); //transition이 끝난 div들의 playing css는 모두 제거된다.
}

이제 모든 필요 기능들에 필요한 코드를 다 짰다.

아래는 그에 따른 최종 완성 코드다 :)


최종 완성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function playsound(e) {
const key = document.querySelector(`.key[data-key = "${e.keyCode}"]`);
const audio = document.querySelector(`audio[data-key = "${e.keyCode}"]`);
if (!audio) return;
//반드시 필요한 것은 아니지만, audio의 data-key에 해당하지 않는 키값이 입력됐을 때 함수가 종료되도록
//위와 같은 코드를 추가했음!
audio.currentTime = 0;
audio.play();
key.classList.add('playing');
}

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

Author

Hoonjoo

Posted on

2022-01-01

Updated on

2022-02-07

Licensed under

Comments