From 67d08ca21cdbc6d6716d38fe5ec4358a10ea5e7c Mon Sep 17 00:00:00 2001
From: KAmal-senpai <113301075+KAmaL-senpai@users.noreply.github.com>
Date: Tue, 14 Oct 2025 09:05:22 +0530
Subject: [PATCH] Added Project Typing Speed Test
---
projects/Typing Speed Test/index.html | 87 ++++++++
projects/Typing Speed Test/readMe.md | 104 ++++++++++
projects/Typing Speed Test/script.js | 232 +++++++++++++++++++++
projects/Typing Speed Test/style.css | 282 ++++++++++++++++++++++++++
4 files changed, 705 insertions(+)
create mode 100644 projects/Typing Speed Test/index.html
create mode 100644 projects/Typing Speed Test/readMe.md
create mode 100644 projects/Typing Speed Test/script.js
create mode 100644 projects/Typing Speed Test/style.css
diff --git a/projects/Typing Speed Test/index.html b/projects/Typing Speed Test/index.html
new file mode 100644
index 00000000..0b891bed
--- /dev/null
+++ b/projects/Typing Speed Test/index.html
@@ -0,0 +1,87 @@
+
+
+
+
+
+ Typing Speed Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🎉 Test Complete!
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/Typing Speed Test/readMe.md b/projects/Typing Speed Test/readMe.md
new file mode 100644
index 00000000..51274c49
--- /dev/null
+++ b/projects/Typing Speed Test/readMe.md
@@ -0,0 +1,104 @@
+# ⌨️ Typing Speed Test
+
+A modern, interactive typing speed test application that measures your typing speed (WPM), accuracy, and tracks errors in real-time.
+
+## 🌟 Features
+
+- **Three Difficulty Levels**
+ - Easy: Simple sentences with common words
+ - Medium: More complex sentences and vocabulary
+ - Hard: Advanced technical terms and complex concepts
+
+- **Real-time Metrics**
+ - WPM (Words Per Minute) calculation
+ - Accuracy percentage tracking
+ - Error counting
+ - 60-second countdown timer
+
+- **Visual Feedback**
+ - Color-coded text display
+ - Green for correct characters
+ - Red for incorrect characters
+ - Animated cursor on current position
+
+- **Results Summary**
+ - Detailed performance breakdown
+ - Final WPM score
+ - Overall accuracy
+ - Total errors and characters typed
+
+## 🚀 How to Use
+
+1. **Select Difficulty**: Choose between Easy, Medium, or Hard
+2. **Click Start Test**: The timer will begin and the input field will be enabled
+3. **Start Typing**: Type the displayed text as accurately and quickly as possible
+4. **Track Progress**: Watch your WPM, accuracy, and errors update in real-time
+5. **View Results**: After 60 seconds or completing the text, see your final score
+6. **Try Again**: Click "Try Again" to test with a new text sample
+
+## 🎯 Scoring
+
+- **WPM**: Based on the standard calculation of 5 characters = 1 word
+- **Accuracy**: Percentage of correctly typed characters
+- **Errors**: Total number of incorrect characters typed
+
+## 💡 Tips for Better Scores
+
+- Focus on accuracy first, then speed
+- Keep your eyes on the screen, not your keyboard
+- Maintain proper posture
+- Practice regularly to improve muscle memory
+- Use all fingers for optimal typing efficiency
+
+## 🛠️ Technologies Used
+
+- HTML5
+- CSS3 (with Flexbox and Grid)
+- Vanilla JavaScript (ES6+)
+
+## 📱 Responsive Design
+
+Works perfectly on:
+- Desktop computers
+- Laptops
+- Tablets
+- Mobile devices
+
+## 🎨 Design Features
+
+- Modern gradient UI
+- Smooth animations
+- Intuitive user interface
+- Clean and minimal design
+- Professional color scheme
+
+## 🔧 Installation
+
+1. Clone or download the repository
+2. Open `index.html` in your web browser
+3. No additional dependencies or setup required!
+
+## 📝 Learning Objectives
+
+This project demonstrates:
+- DOM manipulation
+- Event handling (keyboard events)
+- Timer management with setInterval
+- String comparison algorithms
+- Real-time calculation and updates
+- Responsive CSS design
+- User interface/experience design
+
+## 🤝 Contributing
+
+Feel free to fork this project and submit pull requests for any improvements!
+
+## 📄 License
+
+Open source - Free to use and modify
+
+---
+
+**Happy Typing! 🚀**
+
+Test your skills and improve your typing speed one word at a time!
\ No newline at end of file
diff --git a/projects/Typing Speed Test/script.js b/projects/Typing Speed Test/script.js
new file mode 100644
index 00000000..71d6cd96
--- /dev/null
+++ b/projects/Typing Speed Test/script.js
@@ -0,0 +1,232 @@
+// Text samples for different difficulty levels
+const textSamples = {
+ easy: [
+ "The quick brown fox jumps over the lazy dog. This is a simple sentence to test your typing speed. Practice makes perfect and you will get better with time.",
+ "Cats and dogs are popular pets around the world. They bring joy and happiness to many families. Taking care of pets teaches responsibility.",
+ "The sun rises in the east and sets in the west. Birds fly in the sky and fish swim in the water. Nature is beautiful and amazing.",
+ ],
+ medium: [
+ "Technology has revolutionized the way we communicate and work. Social media platforms connect billions of people across different continents. Digital transformation continues to reshape industries.",
+ "Programming languages enable developers to create software applications. Learning to code requires practice, patience, and problem-solving skills. The tech industry offers exciting career opportunities.",
+ "Climate change affects ecosystems worldwide and requires global cooperation. Renewable energy sources like solar and wind power offer sustainable alternatives to fossil fuels.",
+ ],
+ hard: [
+ "Quantum computing leverages superposition and entanglement to perform complex calculations exponentially faster than classical computers. This paradigm shift in computational capability could revolutionize cryptography, drug discovery, and artificial intelligence.",
+ "Neuroplasticity demonstrates the brain's remarkable ability to reorganize neural pathways throughout life. Cognitive neuroscience research reveals that consistent practice and learning can strengthen synaptic connections and enhance mental acuity.",
+ "Cryptocurrency blockchain technology employs cryptographic hash functions and distributed consensus mechanisms to maintain immutable ledgers. Decentralized finance protocols are disrupting traditional banking infrastructure through smart contracts.",
+ ],
+};
+
+// Global variables
+let currentDifficulty = "easy";
+let currentText = "";
+let isTestActive = false;
+let startTime = null;
+let timerInterval = null;
+let timeLeft = 60;
+let totalErrors = 0;
+
+// DOM elements
+const difficultyBtns = document.querySelectorAll(".difficulty-btn");
+const textDisplay = document.getElementById("textDisplay");
+const userInput = document.getElementById("userInput");
+const startBtn = document.getElementById("startBtn");
+const resetBtn = document.getElementById("resetBtn");
+const timerEl = document.getElementById("timer");
+const wpmEl = document.getElementById("wpm");
+const accuracyEl = document.getElementById("accuracy");
+const errorsEl = document.getElementById("errors");
+const resultsEl = document.getElementById("results");
+const tryAgainBtn = document.getElementById("tryAgainBtn");
+
+// Initialize
+function init() {
+ selectRandomText();
+ displayText();
+ setupEventListeners();
+}
+
+// Setup event listeners
+function setupEventListeners() {
+ difficultyBtns.forEach((btn) => {
+ btn.addEventListener("click", changeDifficulty);
+ });
+
+ startBtn.addEventListener("click", startTest);
+ resetBtn.addEventListener("click", resetTest);
+ tryAgainBtn.addEventListener("click", () => {
+ resultsEl.classList.add("hidden");
+ resetTest();
+ });
+
+ userInput.addEventListener("input", handleInput);
+}
+
+// Change difficulty
+function changeDifficulty(e) {
+ if (isTestActive) return;
+
+ difficultyBtns.forEach((btn) => btn.classList.remove("active"));
+ e.target.classList.add("active");
+ currentDifficulty = e.target.dataset.level;
+ selectRandomText();
+ displayText();
+}
+
+// Select random text
+function selectRandomText() {
+ const texts = textSamples[currentDifficulty];
+ currentText = texts[Math.floor(Math.random() * texts.length)];
+}
+
+// Display text with spans
+function displayText() {
+ textDisplay.innerHTML = currentText
+ .split("")
+ .map((char, index) => `${char}`)
+ .join("");
+}
+
+// Start test
+function startTest() {
+ if (isTestActive) return;
+
+ isTestActive = true;
+ startTime = Date.now();
+ timeLeft = 60;
+ totalErrors = 0;
+
+ userInput.disabled = false;
+ userInput.value = "";
+ userInput.focus();
+
+ startBtn.disabled = true;
+ difficultyBtns.forEach((btn) => (btn.disabled = true));
+
+ startTimer();
+}
+
+// Start timer
+function startTimer() {
+ timerInterval = setInterval(() => {
+ timeLeft--;
+ timerEl.textContent = `${timeLeft}s`;
+
+ if (timeLeft <= 0) {
+ endTest();
+ }
+ }, 1000);
+}
+
+// Handle input
+function handleInput(e) {
+ if (!isTestActive) return;
+
+ const typedText = userInput.value;
+ const textSpans = textDisplay.querySelectorAll("span");
+
+ let correctChars = 0;
+ let errors = 0;
+
+ textSpans.forEach((span, index) => {
+ const char = span.textContent;
+ const typedChar = typedText[index];
+
+ // Reset classes
+ span.classList.remove("correct", "incorrect", "current");
+
+ if (typedChar === undefined) {
+ // Not typed yet
+ if (index === typedText.length) {
+ span.classList.add("current");
+ }
+ } else if (typedChar === char) {
+ // Correct
+ span.classList.add("correct");
+ correctChars++;
+ } else {
+ // Incorrect
+ span.classList.add("incorrect");
+ errors++;
+ }
+ });
+
+ // Update stats
+ totalErrors = errors;
+ updateStats(correctChars, typedText.length);
+
+ // Check if finished
+ if (typedText.length >= currentText.length) {
+ endTest();
+ }
+}
+
+// Update stats
+function updateStats(correctChars, totalChars) {
+ // Calculate WPM
+ const timeElapsed = (60 - timeLeft) / 60; // in minutes
+ const wordsTyped = correctChars / 5; // standard: 5 chars = 1 word
+ const wpm = timeElapsed > 0 ? Math.round(wordsTyped / timeElapsed) : 0;
+ wpmEl.textContent = wpm;
+
+ // Calculate accuracy
+ const accuracy =
+ totalChars > 0 ? Math.round((correctChars / totalChars) * 100) : 100;
+ accuracyEl.textContent = `${accuracy}%`;
+
+ // Update errors
+ errorsEl.textContent = totalErrors;
+}
+
+// End test
+function endTest() {
+ isTestActive = false;
+ clearInterval(timerInterval);
+
+ userInput.disabled = true;
+ startBtn.disabled = false;
+ difficultyBtns.forEach((btn) => (btn.disabled = false));
+
+ showResults();
+}
+
+// Show results
+function showResults() {
+ const wpm = wpmEl.textContent;
+ const accuracy = accuracyEl.textContent;
+ const errors = errorsEl.textContent;
+ const charsTyped = userInput.value.length;
+
+ document.getElementById("finalWpm").textContent = `${wpm} WPM`;
+ document.getElementById("finalAccuracy").textContent = accuracy;
+ document.getElementById("finalErrors").textContent = errors;
+ document.getElementById("finalChars").textContent = charsTyped;
+
+ resultsEl.classList.remove("hidden");
+}
+
+// Reset test
+function resetTest() {
+ isTestActive = false;
+ clearInterval(timerInterval);
+
+ timeLeft = 60;
+ totalErrors = 0;
+
+ timerEl.textContent = "60s";
+ wpmEl.textContent = "0";
+ accuracyEl.textContent = "100%";
+ errorsEl.textContent = "0";
+
+ userInput.value = "";
+ userInput.disabled = true;
+
+ startBtn.disabled = false;
+ difficultyBtns.forEach((btn) => (btn.disabled = false));
+
+ selectRandomText();
+ displayText();
+}
+
+// Initialize on load
+init();
diff --git a/projects/Typing Speed Test/style.css b/projects/Typing Speed Test/style.css
new file mode 100644
index 00000000..be5684b5
--- /dev/null
+++ b/projects/Typing Speed Test/style.css
@@ -0,0 +1,282 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ min-height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 20px;
+}
+
+.container {
+ background: white;
+ border-radius: 20px;
+ padding: 40px;
+ max-width: 900px;
+ width: 100%;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
+}
+
+header {
+ text-align: center;
+ margin-bottom: 30px;
+}
+
+header h1 {
+ font-size: 2.5rem;
+ color: #333;
+ margin-bottom: 10px;
+}
+
+header p {
+ color: #666;
+ font-size: 1.1rem;
+}
+
+.difficulty-selector {
+ display: flex;
+ gap: 10px;
+ justify-content: center;
+ margin-bottom: 30px;
+}
+
+.difficulty-btn {
+ padding: 10px 30px;
+ border: 2px solid #667eea;
+ background: white;
+ color: #667eea;
+ border-radius: 25px;
+ cursor: pointer;
+ font-size: 1rem;
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+.difficulty-btn:hover {
+ background: #667eea;
+ color: white;
+ transform: translateY(-2px);
+}
+
+.difficulty-btn.active {
+ background: #667eea;
+ color: white;
+}
+
+.stats-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
+ gap: 15px;
+ margin-bottom: 30px;
+}
+
+.stat-card {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ padding: 20px;
+ border-radius: 15px;
+ text-align: center;
+ color: white;
+}
+
+.stat-icon {
+ font-size: 2rem;
+ margin-bottom: 10px;
+}
+
+.stat-value {
+ font-size: 2rem;
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.stat-label {
+ font-size: 0.9rem;
+ opacity: 0.9;
+}
+
+.text-display {
+ background: #f8f9fa;
+ padding: 30px;
+ border-radius: 15px;
+ font-size: 1.3rem;
+ line-height: 2;
+ letter-spacing: 1px;
+ margin-bottom: 20px;
+ min-height: 150px;
+ font-family: 'Courier New', monospace;
+ user-select: none;
+}
+
+.text-display span {
+ transition: all 0.1s ease;
+}
+
+.text-display .correct {
+ color: #28a745;
+ background: rgba(40, 167, 69, 0.1);
+}
+
+.text-display .incorrect {
+ color: #dc3545;
+ background: rgba(220, 53, 69, 0.2);
+}
+
+.text-display .current {
+ border-bottom: 3px solid #667eea;
+ animation: blink 1s infinite;
+}
+
+@keyframes blink {
+ 0%, 50%, 100% { opacity: 1; }
+ 25%, 75% { opacity: 0.5; }
+}
+
+.input-container {
+ margin-bottom: 20px;
+}
+
+#userInput {
+ width: 100%;
+ padding: 20px;
+ border: 2px solid #e0e0e0;
+ border-radius: 15px;
+ font-size: 1.2rem;
+ font-family: 'Courier New', monospace;
+ resize: none;
+ transition: all 0.3s ease;
+}
+
+#userInput:focus {
+ outline: none;
+ border-color: #667eea;
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
+}
+
+#userInput:disabled {
+ background: #f8f9fa;
+ cursor: not-allowed;
+}
+
+.controls {
+ display: flex;
+ gap: 15px;
+ justify-content: center;
+}
+
+.btn {
+ padding: 15px 40px;
+ border: none;
+ border-radius: 25px;
+ font-size: 1.1rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.btn-primary {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
+}
+
+.btn-secondary {
+ background: #6c757d;
+ color: white;
+}
+
+.btn-secondary:hover {
+ background: #5a6268;
+ transform: translateY(-2px);
+}
+
+.results {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: white;
+ padding: 40px;
+ border-radius: 20px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ max-width: 500px;
+ width: 90%;
+}
+
+.results.hidden {
+ display: none;
+}
+
+.results h2 {
+ text-align: center;
+ color: #333;
+ margin-bottom: 30px;
+ font-size: 2rem;
+}
+
+.results-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 20px;
+ margin-bottom: 30px;
+}
+
+.result-item {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ padding: 20px;
+ border-radius: 15px;
+ text-align: center;
+ color: white;
+}
+
+.result-label {
+ font-size: 0.9rem;
+ opacity: 0.9;
+ margin-bottom: 10px;
+}
+
+.result-value {
+ font-size: 1.8rem;
+ font-weight: bold;
+}
+
+#tryAgainBtn {
+ width: 100%;
+}
+
+@media (max-width: 768px) {
+ .container {
+ padding: 20px;
+ }
+
+ header h1 {
+ font-size: 2rem;
+ }
+
+ .stats-container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .text-display {
+ font-size: 1.1rem;
+ padding: 20px;
+ }
+
+ .difficulty-selector {
+ flex-wrap: wrap;
+ }
+
+ .results-grid {
+ grid-template-columns: 1fr;
+ }
+}
\ No newline at end of file