ํ์ฌ์ ๊ณ์ ๋ถ๋ค๊ณผ javascript 30์ผ ์ฑ๋ฆฐ์ง์ ํจ๊ป ํ๊ฒ ๋์๋ค.
https://courses.wesbos.com/account/access/6246d1e6d3e09a4497112612
์ฝ์ค์ ์ฒซ๋ฒ์งธ ๊ณผ์ ์ธ drum kit๋ฅผ typescipt๋ก ๊ตฌํํด๋ณธ ์์ ์ด๋ค. ์๋๋ keyboard event๋ก ๋์ํ๋ ๊ณผ์ ๋ก keyboardEvent์ keyCode๋ฅผ ์ฌ์ฉํ๋๋ฐ keyCode๋ deprecated ๋์๋ค๊ณ ํด์ click ์ด๋ฒคํธ๋ก ๋ง๋ค์ด๋ณด์๋ค.
<!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 ํ์ผ๊ณผ ๊ฐ์ ์ด๋ฆ์ผ๋ก ์์ ํ๋ค.
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;
}
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",
}
}
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);
});
Du-dung Du-dung ์๋๋ค์! ๐