Typing game
๐ ์๋ ํ์ธ์! ์ ๊ฐ ๋ง๋ r4k0nb4k0n/typing-game ํ๋ก์ ํธ๋ฅผ ์๊ฐํ๊ฒ ์ต๋๋ค. r4k0nb4k0n.github.io/typing-game ์์ ์ฌ์ฉํด๋ณด์ค ์ ์์ต๋๋ค!
๐ง ์ด๊ฑด ๋๋์ฒด ๋ฌด์์ธ๊ฐ์?
์ฃผ์ด์ง ๋ฌธ์์ด๋ค์ ๋น ๋ฅด๊ณ ์ ํํ๊ฒ ์ ๋ ฅํ๋ ๊ฒ์ ๋ชฉํ๋ก ์๊ฐ์ ์ฌ์ด ์์ ์ ์ค๋ ฅ์ ํ์ ํ๊ณ ๊ธฐ๋ฅผ ์ ์๋ ์น ์ฌ์ดํธ์ ๋๋ค.
๐ ์ด์ฉ๋ค๊ฐ ๋ง๋ค์๋์?
์ ๋ 2021-spring-web-beginner
ํ์์ microsoft/Web-Devs-For-Beginner
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์น ๊ธฐ์ด ์ง์์ ํ์ตํ๊ณ , ํ๋ก์ ํธ๋ฅผ ํตํด ์ด๋ฅผ ์์ฉํด๋ณด๊ณ ์์ต๋๋ค.
Event-Driven Programming - Build a Typing Game ํํธ์์ ์์ ๊ฐ์ ๋ฐ๋ชจ๋ฅผ ๋ดค์ต๋๋ค. ์ด๊ฑธ ์ ๊ฐ ์ํ๋ ํํ์ ๋ฐฉ์์ผ๋ก ๋ง๋ค์ด๋ณด๊ณ ์ถ์์ต๋๋ค.
๐งโ๐ง ์ด๋ป๊ฒ ๋ง๋ค์๋์?
microsoft/Web-Devs-For-Beginner ๋ฅผ ํตํด HTML/CSS/JS ๊ธฐ์ด๋ฅผ ํ์ตํ๊ณ DOM ์กฐ์์ ์ค์ตํ์ต๋๋ค. Typing game๋ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์์ต๋๋ค. ์ฌ๊ธฐ์ ์ ๊ฐ ์ํ๋ ํํ์ ์์ง์์ ๋ฃ๊ธฐ ์ํด CSS ์ ๋๋ฉ์ด์ ์ ๋ฐ๋ก ์ฐพ์ ๊ตฌํํ์ต๋๋ค. Github Pages๋ฅผ ํตํด ๋ฐฐํฌํ์ต๋๋ค.
์๋๋ directory listing์ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
๐ r4k0nb4k0n/typing-game
๐ assets/
๐ GitHub-Mark-32px.png
๐ Typing_dark_01_Videvo.mov
๐ Typing_dark_02_Videvo.mov
๐ Typing_dark_03_Videvo.mov
๐ README.md
๐ index.html
๐ quotes.js # ํ์ดํํ ๋ฌธ์์ด๋ค์ ๋ฐฐ์ด๋ก ์ ์ฅํ๋ ์คํฌ๋ฆฝํธ
๐ script.js # DOM ์กฐ์ ๋ฑ์ ์คํฌ๋ฆฝํธ
๐ style.css # ์คํ์ผ๊ณผ ์ ๋๋ฉ์ด์
์ ์
๐ง ์ด๋์ ์ฝ์ง์ ํ๋์?
1. Multiple videos on background
๋ฐฐ๊ฒฝ์ 3๊ฐ์ ๋์์์ด ์ฐจ๋ก๋๋ก ๋์์ ๋ฐ๋ณต์ฌ์ ํ๋ ๊ฒ์ ๊ตฌํํ์ต๋๋ค.
์ฒ์์๋ ํ๋์ <video>
element๋ฅผ ๋๊ณ ,
onended
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํตํด ํด๋น element DOM์ src
์์ฑ์ ์ง์ ๊ต์ฒดํ๋ ์์ผ๋ก ๊ตฌํํ๋๋ฐ,
์ด๋ Flickering์ด ๋ฐ์ํ์ฌ ๋๋ฆฌ๊ณ ์ค๋ฅ๊ฐ ๊ฑธ๋ฆฐ ๊ฒ์ฒ๋ผ ๋ณด์์ต๋๋ค.
๋ฐ๋ผ์ ๋์์ ๊ฐ์๋งํผ <video>
element๋ค์ ๋ง๋ค๊ณ ,
๊ฐ๊ฐ style.visibility
๋ฅผ ๋จน์ฌ์ ๋จ ํ๋์ <video>
๋ง ๋ณด์ด๊ฒ ํ๋ค๊ฐ
ended ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์ ๋์์๋ง ๋ณด์ด๊ฒ ํ๊ณ ๋๋จธ์ง <video>
element๋ค์ ์๋ณด์ด๊ฒ ๊ฐ๋ ธ์ต๋๋ค.
์๋๋ ํด๋น ์ฝ๋์ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<video
playsinline
muted
id="bgvid1"
src="./assets/Typing_dark_01_Videvo.mov"
onended="bgvid_onended()"
style="visibility: visible;"
></video>
<video
playsinline
muted
id="bgvid2"
src="./assets/Typing_dark_02_Videvo.mov"
onended="bgvid_onended()"
style="visibility: hidden;"
></video>
<video
playsinline
muted
id="bgvid3"
src="./assets/Typing_dark_03_Videvo.mov"
onended="bgvid_onended()"
style="visibility: hidden;"
></video>
<html>
<head></head>
<body></body>
</html>
<script type="text/javascript">
const bgvids = document.querySelectorAll("video");
function bgvid_onended() {
bgvids[bgvid_index].style.visibility = "hidden";
bgvids[bgvid_index].currentTime = 0;
bgvid_index = (bgvid_index + 1) % bgvids.length;
bgvids[bgvid_index].play();
bgvids[bgvid_index].style.visibility = "visible";
}
let bgvid_index = 0;
bgvids[bgvid_index].play();
</script>
2. Fake caret
ํฌ๋ช ํ input์ ๋ง๋ค๊ณ , ๊ทธ ์์ caret๋ ์ ๊ฐ ์ํ๋ ๋ชจ์์ธ ๊ฐ๋๋ก์ผ๋ก ๊ตฌํํ์ต๋๋ค.
<input>
element์ css(border, background)๋ฅผ ์์ ํ์ฌ ํฌ๋ช
ํ๊ฒ ๋ง๋ค์ด๋ณด๋ ค ํ์ผ๋ ์ ์ ์ฉ๋์ง ์์์ต๋๋ค.
์ด๋ <h1>
element์ contenteditable="true"
attribute๋ฅผ ์ถ๊ฐํ์ฌ ์
๋ ฅ์ด ๊ฐ๋ฅํ๋๋ก ๋ง๋ค์์ต๋๋ค.
์ด๋ฅผ ํตํด ์์ฐ์ค๋ฝ๊ฒ ํฌ๋ช
ํ๊ฒ ๋ง๋ค์์ต๋๋ค.
์ด ์์ caret์ ๋ด๊ฐ ์ํ๋ ๋ชจ์์ธ ๋๊บผ์ด ํฐ์ ๋ง๋๊ธฐ ๋ชจ์์ผ๋ก ๋ฐ๊พธ๋ ค๊ณ ๊ด๋ จ attribute๋ฅผ ์ฐพ์๋ดค์ผ๋
caret-color
๋ง ์ฐพ์์ ์ฌ์ฉํ์ต๋๋ค.
๋๋ค๋ฅธ <h1>
element๋ฅผ ๋๊บผ์ด ํฐ์ ๋ง๋๊ธฐ ๋ชจ์์ ๊น๋นก์ด๋ ์ ๋๋ฉ์ด์
์ ์ถ๊ฐํ css๋ฅผ ์ ์ฉํ์ฌ fake caret์ ๋ง๋ค์์ต๋๋ค.
์ค์ caret์ caret-color
๋ฅผ transparent๋ก ์ ์ฉํ์ฌ ๊ฐ๋ฆฌ๊ณ ,
fake caret์ด ๋งจ ๋์ ์๋ ๊ฒฝ์ฐ ๊ฐ์ง caret์ด ๊ทธ๋ด๋ฏํ๊ฒ ๋ณด์ด๊ฒ ๋ง๋ค์์ต๋๋ค.
@Taehee Lee ๋์ ๊ธฐ๋ฅ ์ ์์ผ๋ก Fake input์ ํตํด Fake caret๋ ํ์ดํ ํค๋ฅผ ํตํด ์์ง์ด๋ ๊ฒ์ ๊ตฌํํ ์์ ์ ๋๋ค. ๊ด๋ จ PR
๐งโ๐ป ๋ง์น๋ฉฐ
๋ง์ ๋ถ๋ค์ด ํผ๋๋ฐฑ์ ํด์ฃผ์ จ์ต๋๋ค. ๐โโ๏ธ ์ ๋ณด๋ ๋ฒ๊ทธ๋ค๊ณผ ๊ธฐ๋ฅ ์ ์์ด ์ด๋งํผ ์์ฌ์์ผ๋ ์๊ฐ ๋ ๋๋ง๋ค ํด์น์ฐ๊ฒ ์ต๋๋ค.
์ฌ๋ฌ๋ถ๋ค๋ ์๊ฒ๋๋ง ์ํ๋ ๊ฒ์ ๋ง๋๋ ํ๋ก์ ํธ๋ฅผ ํด๋ณด์ จ์ผ๋ฉด ํฉ๋๋ค. ๐