Skip to content

Commit 7a01d1d

Browse files
authored
Add files via upload
Updated with Typing Game files.
1 parent dd4d5be commit 7a01d1d

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!-- inside index.html -->
2+
<html>
3+
<head>
4+
<title>Typing game</title>
5+
<link rel="stylesheet" href="style.css" />
6+
</head>
7+
8+
<body>
9+
<h1>Typing game!</h1>
10+
<p>
11+
Practice your typing skills with a quote from Sherlock Holmes. Click
12+
**start** to begin!
13+
</p>
14+
<p id="quote"></p>
15+
<!-- This will display our quote -->
16+
<p id="message"></p>
17+
<!-- This will display any status messages -->
18+
<div>
19+
<input type="text" aria-label="current word" id="typed-value" />
20+
<!-- The textbox for typing -->
21+
<button type="button" id="start">Start</button>
22+
<!-- To start the game -->
23+
</div>
24+
<script src="script.js"></script>
25+
</body>
26+
</html>
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// inside script.js
2+
// all of our quotes
3+
4+
5+
const quotes = [
6+
'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.',
7+
'There is nothing more deceptive than an obvious fact.',
8+
'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.',
9+
'I never make exceptions. An exception disproves the rule.',
10+
'What one man can invent another can discover.',
11+
'Nothing clears up a case so much as stating it to another person.',
12+
'Education never ends, Watson. It is a series of lessons, with the greatest for the last.',
13+
];
14+
15+
16+
// store the list of words and the index of the word the player is currently typing
17+
let words = [];
18+
let wordIndex = 0;
19+
20+
// the starting time
21+
let startTime = Date.now();
22+
23+
// page elements
24+
const quoteElement = document.getElementById('quote');
25+
const messageElement = document.getElementById('message');
26+
const typedValueElement = document.getElementById('typed-value');
27+
28+
// at the end of script.js
29+
document.getElementById('start').addEventListener('click', () => {
30+
// get a quote
31+
const quoteIndex = Math.floor(Math.random() * quotes.length);
32+
const quote = quotes[quoteIndex];
33+
// Put the quote into an array of words
34+
words = quote.split(' ');
35+
// reset the word index for tracking
36+
wordIndex = 0;
37+
38+
// UI updates
39+
// Create an array of span elements so we can set a class
40+
const spanWords = words.map(function(word) { return `<span>${word} </span>`});
41+
// Convert into string and set as innerHTML on quote display
42+
quoteElement.innerHTML = spanWords.join('');
43+
// Highlight the first word
44+
quoteElement.childNodes[0].className = 'highlight';
45+
// Clear any prior messages
46+
messageElement.innerText = '';
47+
48+
// Setup the textbox
49+
// Clear the textbox
50+
typedValueElement.value = '';
51+
// set focus
52+
typedValueElement.focus();
53+
// set the event handler
54+
55+
// Start the timer
56+
startTime = new Date().getTime();
57+
});
58+
59+
// at the end of script.js
60+
typedValueElement.addEventListener('input', () => {
61+
// Get the current word
62+
const currentWord = words[wordIndex];
63+
// get the current value
64+
const typedValue = typedValueElement.value;
65+
66+
if (typedValue === currentWord && wordIndex === words.length - 1) {
67+
// end of sentence
68+
// Display success
69+
const elapsedTime = new Date().getTime() - startTime;
70+
const message = `CONGRATULATIONS! You finished in ${elapsedTime / 1000} seconds.`;
71+
messageElement.innerText = message;
72+
} else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) {
73+
// end of word
74+
// clear the typedValueElement for the new word
75+
typedValueElement.value = '';
76+
// move to the next word
77+
wordIndex++;
78+
// reset the class name for all elements in quote
79+
for (const wordElement of quoteElement.childNodes) {
80+
wordElement.className = '';
81+
}
82+
// highlight the new word
83+
quoteElement.childNodes[wordIndex].className = 'highlight';
84+
} else if (currentWord.startsWith(typedValue)) {
85+
// currently correct
86+
// highlight the next word
87+
typedValueElement.className = '';
88+
} else {
89+
// error state
90+
typedValueElement.className = 'error';
91+
}
92+
});
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* inside style.css */
2+
.highlight {
3+
background-color: yellow;
4+
}
5+
/* Define the error class with styling */
6+
.error {
7+
border: 2px solid red;
8+
background-color: #ffe6e6;
9+
animation: shake 0.5s;
10+
animation-iteration-count: 3;
11+
}
12+
13+
/* Define the shake animation */
14+
@keyframes shake {
15+
0% {
16+
transform: translateX(0);
17+
}
18+
19+
25% {
20+
transform: translateX(-5px);
21+
}
22+
23+
50% {
24+
transform: translateX(5px);
25+
}
26+
27+
75% {
28+
transform: translateX(-5px);
29+
}
30+
31+
100% {
32+
transform: translateX(0);
33+
}
34+
}

0 commit comments

Comments
 (0)