0% found this document useful (0 votes)
4 views

quran

Uploaded by

ahmedhaqqaniyyah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

quran

Uploaded by

ahmedhaqqaniyyah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Speed Typing Game

HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speed Typing Game</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="wrapper">
<input type="text" class="input-field">
<div class="content-box">
<div class="typing-text">
<p id="paragraph"></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>
</body>
</html>
CSS
@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: linear-gradient( #007acc, #6DD5FA, #FFFFFF);
}
#paragraph{
color: #646669;
}
.result-details{
color: white;
}
::selection {
color: #fff;
background: #007acc;
}
.wrapper {
width: 700px;
padding: 35px;
background: #1e1e1e;
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: 4px solid #007acc;
}
.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: #d1d0c5;
}
.typing-text p span.incorrect {
color: #ca4754;
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: #007acc;
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: 3px solid #007acc;
}
.content button {
outline: none;
border: none;
width: 105px;
color: #007acc;
padding: 8px 0;
font-size: 17px;
font-weight: 600;
cursor: pointer;
border-radius: 15px;
border: 3px solid #007acc;
background: none;
transition: transform 0.2s ease;
}
.content button:active {
transform: scale(0.89);
}
.content button:hover {
background: #FFFFFF;
}
.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: 2px solid #bfbfbf;
}
.result-details li p {
font-size: 13px;
}
.result-details li span {
display: block;
font-size: 13px;
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: 15px;
}
}
@media (max-width: 518px) {
.wrapper .content-box {
padding: 10px 15px 0;
}
.typing-text p {
font-size: 13px;
}
.result-details li {
margin-bottom: 10px;
}
.content button {
margin-top: 10px;
}
}
const paragraphs = [
"Their politician was, in this moment, a notour paperback. The
sack.",
"Authors often misinterpret the lettuce as a folklore rabbi, when in
in this moment"
];

const typingText = document.querySelector(".typing-text p")


const inpField = document.querySelector(".wrapper .input-field")
const tryAgainBtn = document.querySelector(".content button")
const timeTag = document.querySelector(".time span b")
const mistakeTag = document.querySelector(".mistake span")
const wpmTag = document.querySelector(".wpm span")
const cpmTag = document.querySelector(".cpm span")

let timer;
let maxTime = 60;
let timeLeft = maxTime;
let charIndex = mistakes = isTyping = 0;

function loadParagraph() {
const ranIndex = Math.floor(Math.random() * paragraphs.length);
typingText.innerHTML = "";
paragraphs[ranIndex].split("").forEach(char => {
console.log(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);
Speech to Text
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"
/>
<link rel="stylesheet" href="style.css" />
<title>Speech to Text</title>
</head>
<body>
<div class="container">
<p class="heading">Speech to Text</p>
<div class="options">
<div class="anguage">
<p>Language</p>
<select name="input-language" id="language"></select>
</div>
</div>
<div class="line"></div>
<button class="btn record">
<div class="icon">
<ion-icon name="mic-outline"></ion-icon>
<img src="bars.svg" alt="" />
</div>
<p>Start Listening</p>
</button>
<p class="heading">Result :</p>
<div
class="result"
spellcheck="false"
placeholder="Text will be shown here"
>
<p class="interim"></p>
</div>
<div class="buttons">
<button class="btn clear">
<ion-icon name="trash-outline"></ion-icon>
<p>Clear</p>
</button>
<button class="btn download" disabled>
<ion-icon name="cloud-download-outline"></ion-icon>
<p>Download</p>
</button>
</div>
</div>
<!-- IONICONS -->
<script
type="module"

src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"
></script>
<script
nomodule
src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"
></script>

<!-- LANGUAGES -->


<script src="languages.js"></script>

<!-- SCRIPT -->


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

@import url(https://fonts.googleapis.com/css?
family=Poppins:100,100italic,200,200italic,300,300italic,regular,italic,5
00,500italic,600,600italic,700,700italic,800,800italic,900,900italic);

:root {
--primary-color: #356aff;
--bg-color: #fff;
--text-color: #000;
--light-text-color: #a5a5a5;
--body-bg-color: #f5f5f5;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--body-bg-color);
color: var(--text-color);
}
.container {
width: 400px;
padding: 20px;
border-radius: 10px;
background-color: var(--bg-color);
}
.container .heading {
font-size: 25px;
font-weight: 500;
margin-bottom: 10px;
}
.container .options select {
width: 100%;
padding: 10px;
border: 1px solid var(--light-text-color);
border-radius: 5px;
outline: none;
}
.container .options div:not(:last-child) select {
margin-bottom: 20px;
}

.container .options p {
font-size: 14px;
font-weight: 600;
margin-bottom: 5px;
color: var(--light-text-color);
}
.container .line {
position: relative;
width: 100%;
height: 1px;
background-color: var(--light-text-color);
opacity: 0.5;
margin: 30px 0;
}
.btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
height: 60px;
padding: 20px;
width: 100%;
outline: none;
border: none;
border-radius: 5px;
font-size: 20px;
font-weight: 500;
cursor: pointer;
color: #fff;
background-color: var(--primary-color);
}
.btn ion-icon {
font-size: 30px;
}
.btn:disabled {
background-color: var(--light-text-color);
cursor: not-allowed;
}
.container .record img {
width: 30px;
height: 30px;
display: none;
}
.container .record.recording img {
display: block;
}
.container .record.recording ion-icon {
display: none;
}
.container .result {
width: 100%;
min-height: 200px;
padding: 10px;
border: 1px solid var(--light-text-color);
border-radius: 5px;
font-size: 18px;
font-weight: 500;
margin-bottom: 20px;
color: var(--text-color);
}
.container .result p {
display: inline;
margin-left: 3px;
color: var(--light-text-color);
}
.buttons {
display: flex;
gap: 20px;
}

const recordBtn = document.querySelector(".record"),


result = document.querySelector(".result"),
downloadBtn = document.querySelector(".download"),
inputLanguage = document.querySelector("#language"),
clearBtn = document.querySelector(".clear");

let SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition,
recognition,
recording = false;

function populateLanguages() {
languages.forEach((lang) => {
const option = document.createElement("option");
option.value = lang.code;
option.innerHTML = lang.name;
inputLanguage.appendChild(option);
});
}

populateLanguages();

function speechToText() {
try {
recognition = new SpeechRecognition();
recognition.lang = inputLanguage.value;
recognition.interimResults = true;
recordBtn.classList.add("recording");
recordBtn.querySelector("p").innerHTML = "Listening...";
recognition.start();
recognition.onresult = (event) => {
const speechResult = event.results[0][0].transcript;
//detect when intrim results
if (event.results[0].isFinal) {
result.innerHTML += " " + speechResult;
result.querySelector("p").remove();
} else {
//creative p with class interim if not already there
if (!document.querySelector(".interim")) {
const interim = document.createElement("p");
interim.classList.add("interim");
result.appendChild(interim);
}
//update the interim p with the speech result
document.querySelector(".interim").innerHTML = " " +
speechResult;
}
downloadBtn.disabled = false;
};
recognition.onspeechend = () => {
speechToText();
};
recognition.onerror = (event) => {
stopRecording();
if (event.error === "no-speech") {
alert("No speech was detected. Stopping...");
} else if (event.error === "audio-capture") {
alert(
"No microphone was found. Ensure that a microphone is
installed."
);
} else if (event.error === "not-allowed") {
alert("Permission to use microphone is blocked.");
} else if (event.error === "aborted") {
alert("Listening Stopped.");
} else {
alert("Error occurred in recognition: " + event.error);
}
};
} catch (error) {
recording = false;

console.log(error);
}
}

recordBtn.addEventListener("click", () => {
if (!recording) {
speechToText();
recording = true;
} else {
stopRecording();
}
});

function stopRecording() {
recognition.stop();
recordBtn.querySelector("p").innerHTML = "Start Listening";
recordBtn.classList.remove("recording");
recording = false;
}

function download() {
const text = result.innerText;
const filename = "speech.txt";

const element = document.createElement("a");


element.setAttribute(
"href",
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}

downloadBtn.addEventListener("click", download);

clearBtn.addEventListener("click", () => {
result.innerHTML = "";
downloadBtn.disabled = true;
});

const languages = [
{
no: "3",
name: "Arabic",
native: "‫"عربي‬,
code: "ar",
},
];

You might also like