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 + + + +
+
+

⌨️ Typing Speed Test

+

Test your typing speed and accuracy!

+
+ +
+ + + +
+ +
+
+
⏱️
+
60s
+
Time Left
+
+
+
+
0
+
WPM
+
+
+
🎯
+
100%
+
Accuracy
+
+
+
+
0
+
Errors
+
+
+ +
+ +
+ +
+ +
+ + +
+ + +
+ + + + \ 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