Skip to content

Commit

Permalink
Merge pull request #229 from prasad-chavan1/master
Browse files Browse the repository at this point in the history
Created typing speed check extension
  • Loading branch information
Sulagna-Dutta-Roy authored May 16, 2024
2 parents 58b082a + 87b29a3 commit cfdc560
Show file tree
Hide file tree
Showing 5 changed files with 359 additions and 0 deletions.
43 changes: 43 additions & 0 deletions Typing Speed Check/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Typing Speed Test</title>
<link rel="stylesheet" href="src/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</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="time">
<p>Time Left:</p>
<span><b>60</b>s</span>
</li>
<li class="mistake">
<p>Mistakes:</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>Try Again</button>
</div>
</div>
</div>
<script src="scripts/paragraphs.js"></script>
<script src="scripts/script.js"></script>

</body>
</html>
19 changes: 19 additions & 0 deletions Typing Speed Check/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"manifest_version": 3,
"name": "QR Reader",
"version": "1.0",
"description": "Simple QR Reader",
"permissions": [
"storage"
],
"action": {
"default_popup": "index.html"
},
"web_accessible_resources": [
{
"resources": ["index.html"],
"matches": ["<all_urls>"]
}
]
}

22 changes: 22 additions & 0 deletions Typing Speed Check/scripts/paragraphs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions Typing Speed Check/scripts/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const typingText = document.querySelector(".typing-text p"),
inpField = document.querySelector(".wrapper .input-field"),
tryAgainBtn = document.querySelector(".content button"),
timeTag = document.querySelector(".time span b"),
mistakeTag = document.querySelector(".mistake span"),
wpmTag = document.querySelector(".wpm span"),
cpmTag = document.querySelector(".cpm span");

let timer,
maxTime = 60,
timeLeft = maxTime,
charIndex = mistakes = 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")) {
mistakes--;
}
characters[charIndex].classList.remove("correct", "incorrect");
}
} else {
if(characters[charIndex].innerText == typedChar) {
characters[charIndex].classList.add("correct");
} else {
mistakes++;
characters[charIndex].classList.add("incorrect");
}
charIndex++;
}
characters.forEach(span => span.classList.remove("active"));
characters[charIndex].classList.add("active");

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

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

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

function resetGame() {
loadParagraph();
clearInterval(timer);
timeLeft = maxTime;
charIndex = mistakes = isTyping = 0;
inpField.value = "";
timeTag.innerText = timeLeft;
wpmTag.innerText = 0;
mistakeTag.innerText = 0;
cpmTag.innerText = 0;
}

loadParagraph();
inpField.addEventListener("input", initTyping);
tryAgainBtn.addEventListener("click", resetGame);
184 changes: 184 additions & 0 deletions Typing Speed Check/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/* Import Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
display: flex;
padding: 0 10px;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #17A2B8;
}
::selection{
color: #fff;
background: #17A2B8;
}
.wrapper{
width: 770px;
padding: 35px;
background: #fff;
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: 21px;
text-align: justify;
letter-spacing: 1px;
word-break: break-all;
}
.typing-text p span{
position: relative;
}
.typing-text p span.correct{
color: #56964f;
}
.typing-text p span.incorrect{
color: #cb3439;
outline: 1px solid #fff;
background: #ffc0cb;
border-radius: 4px;
}
.typing-text p span.active{
color: #17A2B8;
}
.typing-text p span.active::before{
position: absolute;
content: "";
height: 2px;
width: 100%;
bottom: 0;
left: 0;
opacity: 0;
border-radius: 5px;
background: #17A2B8;
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;
}
.content button{
outline: none;
border: none;
width: 105px;
color: #fff;
padding: 8px 0;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
background: #17A2B8;
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;
}
@media (max-width: 745px) {
.wrapper{
padding: 20px;
}
.content-box .content{
padding: 20px 0;
}
.content-box .typing-text{
max-height: 100%;
}
.typing-text p{
font-size: 19px;
text-align: left;
}
.content button{
width: 100%;
font-size: 15px;
padding: 10px 0;
margin-top: 20px;
}
.content .result-details{
width: 100%;
}
.result-details li:not(:first-child){
border-left: 0;
padding: 0;
}
.result-details li p,
.result-details li span{
font-size: 17px;
}
}
@media (max-width: 518px) {
.wrapper .content-box{
padding: 10px 15px 0;
}
.typing-text p{
font-size: 18px;
}
.result-details li{
margin-bottom: 10px;
}
.content button{
margin-top: 10px;
}
}

0 comments on commit cfdc560

Please sign in to comment.