-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
182 lines (153 loc) · 6.11 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// script.js
$(document).ready(function() {
// Character Pools
const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';
const specialCharacters = '!@#$%^&*()-_=+[]{}|;:",.<>?/`~\\\' ';
// Counters
let correctCount = 0;
let wrongCount = 0;
// Typing Time Records
let typingTimesLetters = [];
let typingTimesNumbers = [];
let typingTimesSpecial = [];
// Frequencies
let freqCharacters = parseInt($('#freq-characters').val()) || 0;
let freqNumbers = parseInt($('#freq-numbers').val()) || 0;
let freqSpecial = parseInt($('#freq-special').val()) || 0;
// Update frequency display values
function updateFrequencyDisplay() {
$('#freq-characters-value').text(freqCharacters);
$('#freq-numbers-value').text(freqNumbers);
$('#freq-special-value').text(freqSpecial);
}
updateFrequencyDisplay();
// Event listeners for sliders
$('#freq-characters').on('input', function() {
freqCharacters = parseInt($(this).val()) || 0;
$('#freq-characters-value').text(freqCharacters);
});
$('#freq-numbers').on('input', function() {
freqNumbers = parseInt($(this).val()) || 0;
$('#freq-numbers-value').text(freqNumbers);
});
$('#freq-special').on('input', function() {
freqSpecial = parseInt($(this).val()) || 0;
$('#freq-special-value').text(freqSpecial);
});
// Current Character and Timing
let currentChar = '';
let charDisplayTime = 0;
// Function to update counters display
function updateCounters() {
$('#correct-count').text(correctCount);
$('#wrong-count').text(wrongCount);
// Calculate and update median typing times
$('#median-letters').text(calculateMedian(typingTimesLetters));
$('#median-numbers').text(calculateMedian(typingTimesNumbers));
$('#median-special').text(calculateMedian(typingTimesSpecial));
}
// Function to calculate median
function calculateMedian(arr) {
if (arr.length === 0) return 'N/A';
const sorted = arr.slice().sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return Math.round((sorted[mid - 1] + sorted[mid]) / 2);
} else {
return sorted[mid];
}
}
// Function to select next character based on frequencies
function getNextCharacter() {
const total = freqCharacters + freqNumbers + freqSpecial;
if (total === 0) {
// Default to characters if total frequency is zero
return characters.charAt(Math.floor(Math.random() * characters.length));
}
const rand = Math.random() * total;
if (rand < freqCharacters) {
return characters.charAt(Math.floor(Math.random() * characters.length));
} else if (rand < freqCharacters + freqNumbers) {
return numbers.charAt(Math.floor(Math.random() * numbers.length));
} else {
return specialCharacters.charAt(Math.floor(Math.random() * specialCharacters.length));
}
}
// Function to display next character and its instruction with animations
function displayNextCharacter() {
// Animate current character out
$('#current-character').addClass('animate-out');
// After animation duration, change the character
setTimeout(function() {
currentChar = getNextCharacter();
$('#current-character')
.removeClass('animate-out text-green-600 text-red-600')
.text(currentChar)
.addClass('animate-in');
// Fetch instruction for the current character
const instruction = keyInstructions[currentChar] || 'No instruction available';
$('#instruction-text').text(instruction);
// Record the display time
charDisplayTime = Date.now();
}, 300); // Match the CSS transition duration
// Remove the animate-in class after animation
setTimeout(function() {
$('#current-character').removeClass('animate-in');
}, 600);
}
// Initial display
displayNextCharacter();
// Handle input via the input box
$('#char-input').on('input', function() {
const userInput = $(this).val();
if (userInput.length === 0) return;
// Only consider the first character
const inputChar = userInput.charAt(0);
if (inputChar === currentChar) {
// Correct input
correctCount++;
// Calculate typing time
const typingTime = Date.now() - charDisplayTime;
categorizeTypingTime(currentChar, typingTime);
updateCounters();
$('#current-character').addClass('text-green-600');
// Animate to next character
displayNextCharacter();
} else {
// Wrong input
wrongCount++;
updateCounters();
$('#current-character').addClass('text-red-600');
}
// Clear the input box
$(this).val('');
});
// Categorize typing time based on character type
function categorizeTypingTime(char, time) {
if (/[a-zA-Z]/.test(char)) {
typingTimesLetters.push(time);
} else if (/[0-9]/.test(char)) {
typingTimesNumbers.push(time);
} else if (char === ' ') {
// Optionally categorize spacebar separately or with special characters
typingTimesSpecial.push(time);
} else {
typingTimesSpecial.push(time);
}
}
// Handle frequency update button
$('#update-frequencies').on('click', function() {
displayNextCharacter();
});
// Allow pressing Enter to update frequencies
$('#freq-characters, #freq-numbers, #freq-special').on('keypress', function(e) {
if (e.which === 13) { // Enter key
$('#update-frequencies').click();
}
});
// Optional: Click anywhere on the page to focus the input box
$(document).on('click', function() {
$('#char-input').focus();
});
});