본문 바로가기

Develop/기타

JavaScript 30 - DAY 01 Drum Kit

 

JavaScript 30

Build 30 things with vanilla JS in 30 days with 30 tutorials

javascript30.com

 

ajyng/javascript-study

Contribute to ajyng/javascript-study development by creating an account on GitHub.

github.com

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Drum Kit</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>


  <div class="keys">
    <div data-key="65" class="key">
      <kbd>A</kbd>
      <span class="sound">clap</span>
    </div>
    <div data-key="83" class="key">
      <kbd>S</kbd>
      <span class="sound">hihat</span>
    </div>
    <div data-key="68" class="key">
      <kbd>D</kbd>
      <span class="sound">kick</span>
    </div>
    <div data-key="70" class="key">
      <kbd>F</kbd>
      <span class="sound">openhat</span>
    </div>
    <div data-key="71" class="key">
      <kbd>G</kbd>
      <span class="sound">boom</span>
    </div>
    <div data-key="72" class="key">
      <kbd>H</kbd>
      <span class="sound">ride</span>
    </div>
    <div data-key="74" class="key">
      <kbd>J</kbd>
      <span class="sound">snare</span>
    </div>
    <div data-key="75" class="key">
      <kbd>K</kbd>
      <span class="sound">tom</span>
    </div>
    <div data-key="76" class="key">
      <kbd>L</kbd>
      <span class="sound">tink</span>
    </div>
  </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>

<script>
    function playSound(e) {
      const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
      const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
      if (!audio) return;
        
      audio.currentTime = 0;
      audio.play();
      key.classList.add('playing');
    }
    
    function removeTransition(e) {
        console.log(e);
        //if (e.propertyName !== 'transform') return; //skip
        // this.classList.remove('playing');
        //this.classList.remove('playing');
    }

    const keys = document.querySelectorAll('.key');
    keys.forEach(key => key.addEventListener('transitionend', removeTransition));

    window.addEventListener('keydown', playSound);

</script>


</body> 
</html>​

목표


키보드 키 입력 시에 애니메이션 효과와 드럼 소리 출력

코드 분석


function playSound(e) {
  const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
  const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
  if (!audio) return;
    
  audio.currentTime = 0;
  audio.play();
  key.classList.add('playing');
} 
  • keydown 이벤트가 발생한 keyCode와 일치하는 audio와 key를 찾아낸다.
  • 해당 드럼 소리가 끝나기 전에 다른 key를 입력할 수도 있으니 audio.currentTime 을 0으로 설정한다.
  • 애니메이션 효과를 설정하기 위해 해당 key의 classList 에 playing 클래스를 추가해준다.
function removeTransition(e) {
    if (e.propertyName !== 'transform') return;
    this.classList.remove('playing');
}
  • 이벤트가 발생한 key의 속성명이 transform이라면 classList 에서 playing 클래스를 제거한다.
const keys = document.querySelectorAll('.key');
keys.forEach(key => key.addEventListener('transitionend', removeTransition));

window.addEventListener('keydown', playSound);
  • key 클래스의 요소들을 keys 배열로 모아서, transitionend 이벤트에 대한 핸들러를 설정한다.
  • CSS를 전환이 완료되면 transitionend 이벤트가 발생한다.
  • window에서 keydown 이벤트에 대한 playSound 이벤트 핸들러를 설정한다.