[TS] Typescript Drum Kit

CHAERIN ANยท2022๋…„ 4์›” 2์ผ
1
post-thumbnail

ํšŒ์‚ฌ์— ๊ณ„์‹  ๋ถ„๋“ค๊ณผ javascript 30์ผ ์ฑŒ๋ฆฐ์ง€์— ํ•จ๊ป˜ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
https://courses.wesbos.com/account/access/6246d1e6d3e09a4497112612
์ฝ”์Šค์˜ ์ฒซ๋ฒˆ์งธ ๊ณผ์ œ์ธ drum kit๋ฅผ typescipt๋กœ ๊ตฌํ˜„ํ•ด๋ณธ ์˜ˆ์ œ์ด๋‹ค. ์›๋ž˜๋Š” keyboard event๋กœ ๋™์ž‘ํ•˜๋Š” ๊ณผ์ œ๋กœ keyboardEvent์˜ keyCode๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ keyCode๋Š” deprecated ๋˜์—ˆ๋‹ค๊ณ  ํ•ด์„œ click ์ด๋ฒคํŠธ๋กœ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

์ฝ”๋“œ

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My drum sounds Du Dung Du Dung</title>
    <link rel="stylesheet" href="style.css" />
    <script defer src="./script.js"></script>
  </head>
  <body>
    <div class="keys">
      <div data-key="clap" class="key">
        <div class="code">A</div>
        <span class="sound">clap</span>
      </div>
      <div data-key="hihat" class="key">
        <div class="code">S</div>
        <span class="sound">hihat</span>
      </div>
      <div data-key="kick" class="key">
        <div class="code">D</div>
        <span class="sound">kick</span>
      </div>
      <div data-key="openhat" class="key">
        <div class="code">F</div>
        <span class="sound">openhat</span>
      </div>
      <div data-key="boom" class="key">
        <div class="code">G</div>
        <span class="sound">boom</span>
      </div>
      <div data-key="ride" class="key">
        <div class="code">H</div>
        <span class="sound">ride</span>
      </div>
      <div data-key="snare" class="key">
        <div class="code">J</div>
        <span class="sound">snare</span>
      </div>
      <div data-key="tom" class="key">
        <div class="code">K</div>
        <span class="sound">tom</span>
      </div>
      <div data-key="tink" class="key">
        <div class="code">L</div>
        <span class="sound">tink</span>
      </div>
    </div>
  </body>
</html>

๊ธฐ๋ณธ์œผ๋กœ ์ฃผ๋Š” html ์˜ˆ์ œ์—๋Š” <audio>ํƒœ๊ทธ๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ audio ํƒœ๊ทธ๋ฅผ querySelectํ•ด์„œ playํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค new Audio ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•˜๋Š”๊ฒŒ ๋” ๊น”๋”ํ•œ ์ฝ”๋“œ๋ผ๊ณ  ์ƒ๊ฐ์ด ๋ผ์„œ audio ํƒœ๊ทธ๋Š” ์‚ญ์ œํ•˜์˜€๋‹ค.

๋˜ data-key์—๋Š” keyCode์— ํ•ด๋‹นํ•˜๋Š” ์ˆซ์ž๋“ค์ด ์žˆ์—ˆ๋Š”๋ฐ, ๋‚˜์ค‘์— new Audio๋กœ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์‰ฝ๋„๋ก sound ํŒŒ์ผ๊ณผ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค.

style.css

css๋Š” ๊ฑฐ์˜ ์™„์ „ํžˆ ๋˜‘๊ฐ™์€๋ฐ ๊ธฐ์กด html์— <kbd> ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ถ€๋ถ„์„ ์‚ญ์ œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— kbd๋กœ ๋˜์–ด์žˆ๋˜ style๋งŒ .code๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค.

html {
  font-size: 10px;
  background: url('./background.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;
}

.code {
  display: block;
  font-size: 4rem;
}

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

script.ts

const removeTransition = (e: MouseEvent) => {
  const target = e.target as HTMLDivElement;
  target.classList.remove("playing");
};

const playSound = (e: MouseEvent) => {
  const target = e.currentTarget as HTMLDivElement;
  target.classList.add("playing");
  const sound = target.dataset.key;
  const audio = new Audio(`./sounds/${sound}.wav`);
  audio.play();
};

const drumKeys: NodeListOf<Element> = document.querySelectorAll(".key");

drumKeys.forEach(drumKey => {
  drumKey.addEventListener("transitionend", removeTransition);
  drumKey.addEventListener("click", playSound);
});

tsํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜์˜€๋‹ค. React์˜ MouseEvent ํƒ€์ž…์€ ์ œ๋„ค๋ฆญ์œผ๋กœ MouseEvent<HTMLDivElement> ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋ƒฅ ts๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— target์˜ ํƒ€์ž…์„ e.currentTarget as HTMLDivElement ์ด๋ ‡๊ฒŒ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

React์ฒ˜๋Ÿผ MouseEvent ํƒ€์ž…์„ ์ง€์ •ํ•ด๋ณด๊ณ  ์‹ถ์–ด์„œ React์˜ MouseEvent ํƒ€์ž…์„ ์—ด์–ด๋ณด๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์•„์ฃผ ๋ณต์žกํ•˜๊ฒŒ ์„ ์–ธ๋˜์–ด์žˆ์–ด์„œ ๊ทธ๋ƒฅ as๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค...๐Ÿฅฒ

interface MouseEvent<T = Element, E = NativeMouseEvent> extends UIEvent<T, E> {
        altKey: boolean;
        button: number;
        buttons: number;
        clientX: number;
        clientY: number;
        ctrlKey: boolean;
        /**
         * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.
         */
        getModifierState(key: string): boolean;
        metaKey: boolean;
        movementX: number;
        movementY: number;
        pageX: number;
        pageY: number;
        relatedTarget: EventTarget | null;
        screenX: number;
        screenY: number;
        shiftKey: boolean;
    }

์‹คํ–‰๊ฒฐ๊ณผ

์ปดํŒŒ์ผ๋œ ํ›„์— es6 ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋„๋ก tsconfig.json์„ ์„ค์ •ํ•ด์ฃผ๊ณ  tsc ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด script.js ๋กœ ์ปดํŒŒ์ผ ํ•ด์ฃผ์—ˆ๋‹ค.

{
  "compilerOptions": {
    "target": "ES2016",                      
    "module": "commonjs",       
   }
}

์ปดํŒŒ์ผ ๊ฒฐ๊ณผ - script.js

const removeTransition = (e) => {
    const target = e.target;
    target.classList.remove("playing");
};
const playSound = (e) => {
    const target = e.currentTarget;
    target.classList.add("playing");
    const sound = target.dataset.key;
    const audio = new Audio(`./sounds/${sound}.wav`);
    audio.play();
};
const drumKeys = document.querySelectorAll(".key");
drumKeys.forEach(drumKey => {
    drumKey.addEventListener("transitionend", removeTransition);
    drumKey.addEventListener("click", playSound);
});


์ด๋ฒˆ ์˜ˆ์ œ๋Š” ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ ธ์ง€๋งŒ ๋‹ค์Œ์—” ๋” ํ›„๋‹ค๋‹ฅ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค...!!๐Ÿ˜†
profile
๋ฐฐ์šด ๊ฑด ์•ˆ ๊นŒ๋จน๊ณ  ๋˜‘๊ฐ™์€ ์‹ค์ˆ˜๋Š” ๋ฐ˜๋ณตํ•˜์ง€ ์•Š์œผ๋ ค๊ณ  ์“ฐ๋Š” ๋ธ”๋กœ๊ทธ ๐Ÿ“

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

comment-user-thumbnail
2022๋…„ 4์›” 2์ผ

Du-dung Du-dung ์”๋‚˜๋„ค์š”! ๐Ÿ˜†

1๊ฐœ์˜ ๋‹ต๊ธ€