Skip to content

Commit

Permalink
Feature/typing test (#124)
Browse files Browse the repository at this point in the history
* EMi calculating webapp

* rock paper scissors game

* Revert "EMi calculating webapp"

This reverts commit 8e06c0f.

* Typing Speed Test

* Added demo page

* Revert "rock paper scissors game"

This reverts commit 8e88a6b.
  • Loading branch information
AshishGupta18 committed Oct 17, 2023
1 parent d5623d5 commit 85c2b12
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Typing Speed Test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Typing Speed Test Game

**Typing Speed Test Game** is a web application that measures your typing speed in terms of characters per minute (CPM), words per minute (WPM), and the number of errors made during a one-minute typing session. This game is developed using HTML, CSS, and JavaScript.

## Table of Contents

- [Demo](#demo)
- [Features](#features)
- [Getting Started](#getting-started)
- [Usage](#usage)

## Demo
Here is the SS of the project:
![Alt text](<ss.png>)

## Features

- **Real-Time Typing Test:** Users can start a one-minute typing test, and the game provides instant feedback on CPM, WPM, and the number of errors.
- **Error Tracking:** The game accurately counts and displays the number of errors made during the test.
- **Timer:** The game includes a one-minute timer, making it a quick and engaging typing challenge.
- **Results Display:** After completing the test, users receive their CPM, WPM, and the number of errors on the screen.

## Getting Started

To start testing your typing speed, follow these steps:

### Installation

1. Clone the repository or download the ZIP file.

```bash
git clone https://github.com/Prodigy-InfoTech/Web-Development-Projects.git
```

2. Open the project folder.

```bash
cd Typing Speed Test
```

3. Run `index.html` in your preferred web browser.

## Usage

1. Open the `index.html` file in your web browser to access the Typing Speed Test Game.

2. Click the "Start" button to begin the one-minute typing test.

3. Type the displayed text as accurately and quickly as possible.

4. The game will track your typing speed (CPM and WPM) and the number of errors in real-time.

5. Once the timer reaches one minute, your results will be displayed on the screen.

Enjoy testing and improving your typing speed with the Typing Speed Test Game!
99 changes: 99 additions & 0 deletions Typing Speed Test/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const paragraphs = [
"One dollar and eighty-seven cents. That was all. And sixty cents of it was in pennies. Pennies saved one and two at a time by bulldozing the grocer and the vegetable man and the butcher until one’s cheeks burned with the silent imputation of parsimony that such close dealing implied. One dollar and eighty-seven cents. And the next day would be Christmas...",
"There was a leak in the boat. Nobody had yet noticed it, and nobody would for the next couple of hours. This was a problem since the boat was heading out to sea and while the leak was quite small at the moment, it would be much larger when it was ultimately discovered. John had planned it exactly this way.",
"The paper was blank. It shouldn't have been. There should have been writing on the paper, at least a paragraph if not more. The fact that the writing wasn't there was frustrating. Actually, it was even more than frustrating. It was downright distressing.", "The coin hovered in the air, spinning over and over again. It reached its peak and began to descend. Both boys were pleading with it to land a certain way but the coin had already made up its mind on what it was going to do.",
"I'll talk to you tomorrow in more detail at our meeting, but I think I've found a solution to our problem. It's not exactly legal, but it won't land us in jail for the rest of our lives either. Are you willing to take the chance? Monroe asked his partner over the phone.",
"There was a time when he would have embraced the change that was coming. In his youth, he sought adventure and the unknown, but that had been years ago. He wished he could go back and learn to find the excitement that came with change but it was useless. That curiosity had long left him to where he had come to loathe anything that put him out of his comfort zone."
];

const typingText = document.querySelector(".typing-text p"),
inpField = document.querySelector(".wrapper .input-field"),
tryAgainBtn = document.querySelector(".content button"),
timeTag = document.querySelector(".timeLeft span b"),
errorTag = document.querySelector(".errors span"),
wpmTag = document.querySelector(".wpm span"),
cpmTag = document.querySelector(".cpm span");

let timer,
maxTime = 60,
timeLeft = maxTime,
charIndex = errors = isTyping = 0;

function loadParagraph() {
const ranIndex = Math.floor(Math.random() * paragraphs.length);
typingText.innerHTML = "";
paragraphs[ranIndex].split("").forEach(char => {
let span = `<span>${char}</span>`
typingText.innerHTML += span;
});
typingText.querySelectorAll("span")[0].classList.add("active");
document.addEventListener("keydown", () => inpField.focus());
typingText.addEventListener("click", () => inpField.focus());
}

function initTyping() {
let characters = typingText.querySelectorAll("span");
let typedChar = inpField.value.split("")[charIndex];
if (charIndex < characters.length - 1 && timeLeft > 0) {
if (!isTyping) {
timer = setInterval(initTimer, 1000);
isTyping = true;
}
if (typedChar == null) {
if (charIndex > 0) {
charIndex--;
if (characters[charIndex].classList.contains("incorrect")) {
errors--;
}
characters[charIndex].classList.remove("correct", "incorrect");
}
} else {
if (characters[charIndex].innerText == typedChar) {
characters[charIndex].classList.add("correct");
} else {
errors++;
characters[charIndex].classList.add("incorrect");
}
charIndex++;
}
characters.forEach(span => span.classList.remove("active"));
characters[charIndex].classList.add("active");

let wpm = Math.round(((charIndex - errors) / 5) / (maxTime - timeLeft) * 60);
wpm = wpm < 0 || !wpm || wpm === Infinity ? 0 : wpm;

wpmTag.innerText = wpm;
errorTag.innerText = errors;
cpmTag.innerText = charIndex - errors;
} else {
clearInterval(timer);
inpField.value = "";
}
}

function initTimer() {
if (timeLeft > 0) {
timeLeft--;
timeTag.innerText = timeLeft;
let wpm = Math.round(((charIndex - errors) / 5) / (maxTime - timeLeft) * 60);
wpmTag.innerText = wpm;
} else {
clearInterval(timer);
}
}

function resetTest() {
loadParagraph();
clearInterval(timer);
timeLeft = maxTime;
charIndex = errors = isTyping = 0;
inpField.value = "";
timeTag.innerText = timeLeft;
wpmTag.innerText = 0;
errorTag.innerText = 3;
cpmTag.innerText = 0;
}

loadParagraph();
inpField.addEventListener("input", initTyping);
tryAgainBtn.addEventListener("click", resetTest);
49 changes: 49 additions & 0 deletions Typing Speed Test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!doctype html>
<html lang="en">

<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- CSS -->
<link rel="stylesheet" href="style.css">

<title>Typing Speed Test using JavaScript - Coding Torque</title>
</head>

<body>
<div class="wrapper">
<input type="text" class="input-field">
<div class="content-box">
<div class="typing-text">
<p></p>
</div>
<div class="content">
<ul class="result-details">
<li class="timeLeft">
<p>time Left:</p>
<span><b>60</b>s</span>
</li>
<li class="errors">
<p>Errors:</p>
<span>0</span>
</li>
<li class="wpm">
<p>WPM:</p>
<span>0</span>
</li>
<li class="cpm">
<p>CPM:</p>
<span>0</span>
</li>
</ul>
<button>Test Again</button>
</div>
</div>
</div>

<script src="app.js"></script>
</body>

</html>
Binary file added Typing Speed Test/ss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 172 additions & 0 deletions Typing Speed Test/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/* Import Google Font - Poppins */
@import url("https://fonts.googleapis.com/css2?family=Merriweather:wght@400;500;600;700&display=swap");

* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Merriweather", sans-serif;
}

body {
display: flex;
padding: 0 10px;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #0f172a;
}

::selection {
color: #fff;
background: deepskyblue;
}

.wrapper {
width: 770px;
padding: 35px;
background: #0f172a;
color: #f1f5f9;
border-radius: 10px;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.05);
}

.wrapper .input-field {
opacity: 0;
z-index: -999;
position: absolute;
}

.wrapper .content-box {
padding: 13px 20px 0;
border-radius: 10px;
border: 1px solid #bfbfbf;
}

.content-box .typing-text {
overflow: hidden;
max-height: 256px;
}

.typing-text::-webkit-scrollbar {
width: 0;
}

.typing-text p {
font-size: 25px;
text-align: justify;
letter-spacing: 1px;
}

.typing-text p span {
position: relative;
}

.typing-text p span.correct {
color: lawngreen;
}

.typing-text p span.incorrect {
color: #cb3439;
outline: 1px solid #fff;
background: #ffc0cb;
border-radius: 4px;
}

.typing-text p span.active {
color: deepskyblue;
}

.typing-text p span.active::before {
position: absolute;
content: "";
height: 2px;
width: 100%;
bottom: 0;
left: 0;
opacity: 0;
border-radius: 5px;
background: deepskyblue;
animation: blink 1s ease-in-out infinite;
}

@keyframes blink {
50% {
opacity: 1;
}
}

.content-box .content {
margin-top: 17px;
display: flex;
padding: 12px 0;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
border-top: 1px solid #bfbfbf;
line-break: auto;
}

.content button {
outline: none;
border: none;
width: 105px;
color: #fff;
padding: 8px 0;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
background: deepskyblue;
transition: transform 0.3s ease;
}

.content button:active {
transform: scale(0.97);
}

.content .result-details {
display: flex;
flex-wrap: wrap;
align-items: center;
width: calc(100% - 140px);
justify-content: space-between;
}

.result-details li {
display: flex;
height: 20px;
list-style: none;
position: relative;
align-items: center;
}

.result-details li:not(:first-child) {
padding-left: 22px;
border-left: 1px solid #bfbfbf;
}

.result-details li p {
font-size: 19px;
}

.result-details li span {
display: block;
font-size: 20px;
margin-left: 10px;
}

li span b {
font-weight: 500;
}

li:not(:first-child) span {
font-weight: 500;
}

.errors span {
color: #facc15;
}

.timeLeft span {
color: #cb3439;
}

0 comments on commit 85c2b12

Please sign in to comment.