JS - Drum Kit

rachel's blogยท2021๋…„ 10์›” 18์ผ
0

JavaScript

๋ชฉ๋ก ๋ณด๊ธฐ
1/5

1. Drum Kit

HTML๊ตฌ์กฐ

  <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>
  const key = document.querySelector('.key');

  const chgBox = () => {
    key.classList.add('playing');
    key.classList.add('sound');
  }
  const removeBox = () => {
    key.classList.remove('playing');
    key.classList.remove('sound');
  }

  key.addEventListener("mouseover",chgBox);
  key.addEventListener("mouseout",removeBox);
</script>

A ๋งŒ ๊ตฌํ˜„๋˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ์ „๋ถ€ ๊ตฌํ˜„์ด ๋˜์ง€ ์•Š๋Š”๋‹ค -> this๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์€๋ฐ..๋ผ๊ณ  ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ ์•Œ๊ณ ๋ณด๋‹ˆ ๋‚ด๊ฐ€ ๋ฌธ์ œ ์ดํ•ด๋ฅผ ์ž˜๋ชปํ–ˆ๋‹ค. ๋งˆ์šฐ์Šค์—๋Œ€ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ํ‚ค๋ณด๋“œ์˜ ํ‚ค ๊ฐ’์„ ๋ฐ›์•„์„œ ํ™”๋ฉด์— ๋‚˜์˜จ ์•ŒํŒŒ๋ฒณ์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ data-key๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” audiotag์™€ ์—ฐ๋™์ด ๋˜์„œ ํ•ด๋‹น ์‚ฌ์šด๋“œ๋ผ ์šธ๋ ค์•ผ ํ•˜๊ณ , ๋™์‹œ์— CSS transitionํšจ๊ณผ๋ฅผ ์ฃผ์–ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ์˜€๋‹ค.

๐Ÿ“Œ ํฌ์ธํŠธ

  • keydown ์ด๋ฒคํŠธ ์‚ฌ์šฉ - ํ‚ค๋ณด๋“œ์˜ ๊ฐ’์ด ์ž…๋ ฅ๋˜์–ด์•ผ ํ•œ๋‹ค.
  • e.keyCode : ํ‚ค ๊ฐ’(value)์ž…๋ ฅ ๋ฐ›๊ธฐ
  • keycode.info ์‚ฌ์ดํŠธ๋ฅผ ํ†ตํ•ด ํ‚ค๋ณด๋“œ๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ์˜ ๊ฐ’์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  • audio.play() ๋ฉ”์„œ๋“œ : ์Œ์•…์žฌ์ƒ
  • transitionend() ์ด๋ฒคํŠธ : transition์ด ์™„๋ฃŒ๋œ ์ดํ›„ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ, transition์™„๋ฃŒ๋ฅผ ๊ฐ์ง€ํ•จ, transition๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค. -> addEventListener๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ ๋ชจ๋‹ˆํ„ฐ๋ง๊ฐ€๋Šฅ

๐Ÿฅ‘ ์žฌ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ

1) ์ฒซ๋ฒˆ์งธ๋กœ ์–ด๋””์— ์ด๋ฒคํŠธ๋ฅผ ์ฃผ์–ด์•ผ ํ• ๊ฒƒ์ธ๊ฐ€?

  • window์— ์ฃผ์–ด์•ผ ์ „์ฒด ํ™”๋ฉด์—์„œ! ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅด๊ธฐ๋งŒํ•˜๋ฉด ์–ด๋””์„œ๋“  ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ํ•˜๋ ค๊ณ 

2) data-key๋ผ๋Š” ์†์„ฑ๊ฐ’์€ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•ด์•ผ ํ• ๊นŒ?

  • [] ์™€ Backtick(``)ํ‘œ๊ธฐ๋ฒ• ์‚ฌ์šฉ

3) โ‘ ์—์„œ ์ฝ˜์†”์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋ฉด ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ถœ๋ ฅ์ด ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
+) ๋‚ด๊ฐ€ ์ž…๋ ฅํ•œ ๋ฐ”๋กœ ๊ทธ ํ‚ค๋ณด๋“œ์˜ ํ‚ค ๊ฐ’(value)๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•ด e.keyCode ์‚ฌ์šฉ!

4) โ‘ข์—์„œ ์˜ค๋””์˜ค๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๊ณ  ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํŠน์ • ํ‚ค๋ณด๋“œ ์ž…๋ ฅ ๊ฐ’์— ๋”ฐ๋ผ ์˜ค๋””์˜ค๊ฐ€ ๋‚˜์˜จ๋‹ค.
โœ…๋ฌธ์ œ์  ๋ฐœ์ƒ !! : ์—ฐ์†ํ•ด์„œ ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆŒ๋ €์„๋•Œ, ์˜ค๋””์˜ค ์žฌ์ƒ์— ๋กœ๋”ฉ์ด ๊ฑธ๋ฆฐ๋‹ค.

5) ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด currentTime ์†์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.

6) ์ด์ œ css ์• ๋‹ˆ๋ฉ”์ด์…˜ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ด๋ณด์ž
class๋ช…์ด 'key'์ธ ๋ฐ•์Šค๋“ค ์•ˆ์— ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์ฐฝ์ด ์ž…๋ ฅ๋˜์–ด ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ด .key๋ฅผ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•œ๋‹ค.

โ‘ค๋ฒˆ์—์„œ const key์˜ ์ฝ˜์†”์„ ์ฐ์–ด๋ณด๋ฉด, ํ‚ค ๊ฐ’(์ˆซ์ž๊ฐ’)์ด ์ •์ƒ์ ์œผ๋กœ ๋‚˜์˜ค๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

7) ์ด key๋ผ๋Š” ๋ณ€์ˆ˜์— class๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด border๊ฐ€ ๋…ธ๋ž€์ƒ‰์ธ ๋ฐ•์Šค ํ˜•ํƒœ๊ฐ€ ๊ตฌํ˜„๋จ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

8) โœ…๋ฌธ์ œ์  ๋ฐœ์ƒ!! : removeClass๋Š” ์–ด๋–ป๊ฒŒ ์ฃผ์–ด์•ผ ํ•˜๋‚˜?
โ†’ ์กฐ๊ฑด: transitionํšจ๊ณผ๊ฐ€ ๋ชจ๋‘ ๋๋‚˜๊ณ  class๊ฐ€ ์ฆ‰, ๋…ธ๋ž€์ƒ‰ borderline์ด ์‚ฌ๋ผ์ ธ์•ผ ํ•œ๋‹ค.
โ†’ ๋”ฐ๋ผ์„œ transitionend ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๐Ÿ‘‰ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉ

window.addEventListener(e){
  //console.log(e) ........โ‘ 
  //const audio = document.querySelector('audio');
  const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
  //console.log(audio) ........โ‘ก
  
  if(!audio) return; //audio๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์—†๋Š” ํ‚ค ๊ฐ’์ด ์ถœ๋ ฅ๋œ ๊ฒฝ์šฐ ๋ฉˆ์ถฐ!
  audio.currentTIme = 0; //.......โ‘ฃ ์˜ค๋””์˜ค / ๋น„๋””์˜ค ์žฌ์ƒ์˜ ํ˜„์žฌ ์œ„์น˜ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ ๊ทธ ๋ฐ˜ํ™˜ํ•˜๋Š” ์œ„์น˜๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•œ๊ฒƒ!
  audio.play(); //............โ‘ข
  //////////////////////////////////////////
  const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
  //console.log(key);    ............โ‘ค
  key.classList.add('playing');
  
  //โ‘ฆํด๋ž˜์Šค ์ œ๊ฑฐํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ
  function removeTransition(e){
    //console.log(e); //
    if(e.propertyName !== 'transform'){
   // console.log(e.propertyName); //transform - h ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ, data-key๊ฐ€ ์žˆ๋Š” ๊ฐ’์ด๋ฏ€๋กœ ์ •์ƒ์ถœ๋ ฅ
      //console.log(this); //this = keys
      this.classList.remove('palying');
    }
    
   const keys = document.querySelectorAll('.key');
    //console.log(keys)  .......โ‘ฅ์œ ์‚ฌ๋ฐฐ์—ด๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ , ๊ทธ ์ค‘ e.propertyName์ด transition์˜ ์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ์Œ์„ ํ™•์ธ
    
    //โ‘ง
    keys.forEach((key) => key.addEventListener('transitionend', removeTransition));
}

์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค!

์ฐธ๊ณ : transitionend_Event
์ฐธ๊ณ 2: dataset

profile
๋ธ”๋กœ๊ทธ ์ด์ „ : https://rachelslab.tistory.com/

0๊ฐœ์˜ ๋Œ“๊ธ€