이곳의 코스과정을 정리하여 공부하는 중입니다.

키보드의 ASDFGHJKL 을 누르면 소리가 나는 드럼을 만드는 예제 입니다.

예제는 이곳에서 clone 받을 수 있습니다.

<!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>
    </script>
  </body>
</html>

이게 기본적으로 제공되는 START.html 이다.

그리고 CSS 파일이다.

html {
  font-size: 10px;
  background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
  background-size: cover;
}

body,html {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

.keys {
  display: flex;
  flex: 1;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}

.key {
  border: .4rem solid black;
  border-radius: .5rem;
  margin: 1rem;
  font-size: 1.5rem;
  padding: 1rem .5rem;
  transition: all .07s ease;
  width: 10rem;
  text-align: center;
  color: white;
  background: rgba(0,0,0,0.4);
  text-shadow: 0 0 .5rem black;
}

.playing {
  transform: scale(1.1);
  border-color: #ffc600;
  box-shadow: 0 0 1rem #ffc600;
}

kbd {
  display: block;
  font-size: 4rem;
}

.sound {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: .1rem;
  color: #ffc600;
}

이제 <script> 태그 안에 함수들을 만들어 넣을 것이다.

먼저 처음 보는 HTML tag 들이 있다. <audio> 태그와 <kbd> 태그 이다.
audio 태그는 오디오 파일을 가지고와 재생할 수 있다. kbd 태그는 키보드 태그이다...

2개의 함수로 나눠서 보겠다.

<script>
// 1번 함수
  playsound = e => {
	const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
  	
  	const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
  
  	if(!audio) return;
  
  	key.classList.add("playing");
  
  	audio.currentTime=0;
  
  	audio.play();
	
}
	window.addEventListener("keydown", playSound);
//-------------------------------------------------------
// 2번 함수
 	removeTransition = e => {
        if (e.propertyName !== "transform") return;
      
        e.target.classList.remove("playing");
      };

      const keys = Array.from(document.querySelectorAll(".key"));
      
	 keys.forEach(e => e.addEventListener("transitionend", removeTransition));
</script>
  1. 먼저 playsound 함수를 보자.
    1-1. audio 변수를 보자

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

    document.querySelectoraudio 태그중 data-key가 HTML 에서 지정한 A,S,D,F,G,H,J,K,L 키를 가져온다.
    1-2. key 변수를 보자.

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

    마찬가지로 div 태그 중에서 <div data-key="76" ></div> 과 같이 data-key 가 들어간 태그들을 가져온다.
    1-3. 나머지 함수

    if(!audio) return;
    
    key.classList.add("playing");
    
    audio.currentTime=0;
    
    audio.play();
    
    window.addEventListener("keydown", playSound);

    첫째 줄 : audio 변수에 없는 키를 입력시 함수를 종료시켜 버리기 위해서 있다.
    둘째 줄 : key변수에 playing 이라는 class 를 추가한다. playing이 추가된 것을 확인하면, <div data-key="76" class="key playing">tink</div>이 된다.
    셋째 줄 : audio 변수에 소리 재생하는 시간을 0초로 한다는 것. 재생되는 시간이 0초가 아니면 소리가 다 끝나야 다음 소리를 누를 수 있는데, 0초로 설정하면 동시 입력이 가능하다는 것.
    넷째 줄 : 오디오를 재생시킨다.
    다섯째 줄 : window에 eventListner 를 추가하여, 키가 입력될 시 (keydown) playSound 함수를 실행 시킨다.

2. remove 함수를 보자.

	removeTransition = e => {
        	if (e.propertyName !== "transform") return;
      
       		e.target.classList.remove("playing");
      	};

    const keys = Array.from(document.querySelectorAll(".key"));
      
	keys.forEach(e => e.addEventListener("transitionend", removeTransition));

key 변수를 먼저 보면, class 이름이 key 인 div들을 모아서 Array에 넣는다.
그리고, 그 keys의 배열에 각각 addEventListener를 걸어준다.
(forEach를 통해 배열 각각에 이벤트를 걸어준다.) event 내용은 transitionend즉, CSS의 transition이 끝날 때, removeTransition을 시작한다는 것이다.
CSS 파일의 .key 에 적용된 부분을 보면, transition이 존재한다. .07s 후에 transition이 끝난다.
이제 removeTransition 함수를 보자.

removeTransition = e => {
        	if (e.propertyName !== "transform") return;
      
       		e.target.classList.remove("playing");
      	};

--> if 문을 보면 class 이름이 key인 div의 propertyname 이 transform 이 아니면 끝낸다는 것.
--> class 이름이 key인 div의 class 이름에서 playing이라는 이름을 지운다는 것.

class 이름이 playing 이면 transform 이 되어 scale이 커진다. 하지만 클래스 이름에서 playing 을 지운다면 다시 원래대로 돌아갈 것이다. 그래서 remove 해주는 것.


이렇게 해서 첫번째 과제를 분석해 보았다.
아직 멀고 멀었다.

profile
프론트엔드 개발자 김영준 입니다. 디테일함을 키우고 있습니다

0개의 댓글