유데미에서 Brad Traversy의 20 Web Projects With Vanilla JavaScript
를 하나씩 직접 코딩해보면서 정리하기 위한 글이다.
데모 페이지
vanillawebprojects.com/projects/typing-game/
코드 링크
github.com/rshak8912/20-Web-Projects
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css"
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ="
crossorigin="anonymous"
/>
<link rel="stylesheet" href="style.css">
<title>Speed Typer</title>
</head>
<body>
<button id="settings-btn" class="settings-btn">
<i class="fas fa-cog"></i>
</button>
<div id="settings" class="settings">
<form id="settings-form">
<div>
<label for="difficulty">Difficulty</label>
<select id="difficulty">
<option value="easy">Easy</option>
<option value="medium">Medium</option>
<option value="hard">Hard</option>
</select>
</div>
</form>
</div>
<div class="container">
<h2>👩💻 Speed Typer 👨💻</h2>
<small>Type the following:</small>
<h1 id="word"></h1>
<input type="text" id="text" autocomplete="off"
placeholder="Type the word here..." autofocus/>
<p class="time-container">Time left: <span id="time">10s</span></p>
<p class="score-container">Score: <span id="score">0</span></p>
<div id="end-game-container" class="end-game-container"></div>
</div>
<script src="script.js"></script>
</body>
</html>
style.css
* {
box-sizing: border-box;
}
body {
background-color: #2c3e50;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
button {
cursor: pointer;
font-size: 14px;
border-radius: 4px;
padding: 5px 15px;
}
select {
width: 200px;
padding: 5px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
border-radius: 0;
background-color: #a7c5e3;
}
.settings-btn {
position: absolute;
bottom: 30px;
left: 30px;
}
.settings {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.3);
height: 70px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
transform: translateY(0);
transition: transform 0.3s ease-in-out;
}
.settings.hide {
transform: translateY(-100%);
}
.container {
background-color: #34495e;
padding: 20px;
border-radius: 4px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3);
color: #fff;
position: relative;
text-align: center;
width: 500px;
}
h2 {
background-color: rgba(0, 0, 0, 0.3);
padding: 8px;
border-radius: 4px;
margin: 0 0 40px;
}
h1 {
margin: 0;
}
input {
border: 0;
border-radius: 4px;
font-size: 14px;
width: 300px;
padding: 12px 20px;
margin-top: 10px;
}
.score-container {
position: absolute;
top: 60px;
right: 20px;
}
.time-container {
position: absolute;
top: 60px;
left: 20px;
}
.end-game-container {
background-color: inherit;
display: none;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
script.js
const word = document.getElementById('word');
const text = document.getElementById('text');
const scoreEl = document.getElementById('score');
const timeEl = document.getElementById('time');
const endgameEl = document.getElementById('end-game-container');
const settingsBtn = document.getElementById('settings-btn');
const settings = document.getElementById('settings');
const settingsForm = document.getElementById('settings-form');
const difficultySelect = document.getElementById('difficulty');
const words = [
'sigh',
'tense',
'airplane',
'ball',
'pies',
'juice',
'warlike',
'bad',
'north',
'dependent',
'steer',
'silver',
'highfalutin',
'superficial',
'quince',
'eight',
'feeble',
'admit',
'drag',
'loving'
];
let randomWord;
let score = 0;
let time = 10;
let difficulty = localStorage.getItem('difficulty') !== null
? localStorage.getItem('difficulty') : 'medium';
difficultySelect.value = localStorage.getItem('difficulty') !== null
? localStorage.getItem('difficulty') : 'medium';
text.focus();
const timeInterval = setInterval(updateTime, 1000);
function getRandomWord() {
return words[Math.floor(Math.random() * words.length)];
}
function addWordToDOM() {
randomWord = getRandomWord();
word.innerHTML = randomWord;
}
function updateScore() {
score++;
scoreEl.innerHTML = score;
}
function updateTime() {
time--;
timeEl.innerHTML = time + "초";
if (time === 0) {
clearInterval(timeInterval);
gameOver();
}
}
function gameOver() {
endgameEl.innerHTML = `
<h1>Time ran out</h1>
<p>Your final score is ${score}</p>
<button onclick="location.reload()">Reload</button>`;
endgameEl.style.display = 'flex';
}
addWordToDOM();
text.addEventListener('input', e => {
const insertedText = e.target.value;
//console.log(insertedText);
if (insertedText === randomWord) {
addWordToDOM();
updateScore();
e.target.value = '';
if (difficulty === 'hard') {
time += 2;
} else if (difficulty === 'medium') {
time += 3;
} else {
time += 5;
}
updateTime();
}
});
settingsBtn.addEventListener('click', () => settings.classList.toggle('hide'));
settingsForm.addEventListener('change', e => {
difficulty = e.target.value;
localStorage.setItem('difficulty', difficulty);
});
강의를 통해 배운 점(생각, 내용 정리)
- 클릭 이벤트 뿐만 아니라, input, change 이벤트에 대해 알게 되었음.
(타이핑 할 때마다 input이 들어오니까 해당 값을 비교하여 단어가 맞는지 확인하는 로직)
'HTML&CSS&Javascript' 카테고리의 다른 글
[Udemy]20 Web Projects With Vanilla JavaScript -Project#13 (0) | 2021.01.01 |
---|---|
자바스크립트 화살표 함수 주의사항 (0) | 2020.12.30 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#11 (0) | 2020.12.30 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#10 (0) | 2020.12.30 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#9 (0) | 2020.12.29 |