HTMLcopy
1
<div id="wrapper">
2
<div id="display">
3
<textarea type="text" type="text" placeholder="Enter up to 125 symbols" id="displayInputField" ></textarea>
4
<h2 id="resultText">_SCORE_</h2>
5
<button id="restartTest">Test again!</button>
6
</div>
7
<div id="container"></div>
8
</div>
CSScopy
33
1
html, body, #container {
2
width: 100%;
3
height: 100%;
4
margin: 0;
5
padding: 0;
6
}
7
#wrapper{
8
width: 100vw;
9
height:100vh;
10
display: grid;
11
grid-template-rows: 2fr 1fr;
12
}
13
#display{
14
width: 100%;
15
height: 100%;
16
display: grid;
17
text-align: center;
18
place-items: center;
19
}
20
#displayInputField{
21
width: 50%;
22
height: 50%;
23
min-width: 200px;
24
min-height: 100px;
25
text-align: center;
26
font-size: 22px;
27
resize: none;
28
border-radius: 10px;
29
}
30
#resultText, #restartTest{
31
display: none;
32
font-family: "courier new";
33
}
JavaScriptcopy
x
1
// create a symbol counter
2
var numberOfSymbolsEntered = 0;
3
4
// create a typing speed test
5
var speedTypingTest = function(gauge){
6
7
// get dom elements
8
var inputFieldElement = document.getElementById("displayInputField");
9
inputFieldElement.focus();
10
var restartButton = document.getElementById("restartTest");
11
var scoreHeader = document.getElementById("resultText");
12
13
// instantiate app variables
14
var symbolsPerSecond = 0;
15
var iterationCounter = 0;
16
var isCounterOn = false;
17
18
// calculate symbols per second rate
19
var getSymbolsPerSecond = function(){
20
if(isCounterOn){
21
symbolsPerSecond = (numberOfSymbolsEntered/(iterationCounter / 10)).toFixed(2);
22
gauge.data().set(0,"value", symbolsPerSecond);
23
}
24
}
25
26
// instantiate a timeout id
27
var timeoutID;
28
29
// create a timer counter function
30
var startTimerCounter = function(){
31
iterationCounter++;
32
timeoutID = setTimeout(startTimerCounter, 100);
33
if(!isCounterOn){
34
clearTimeout(timeoutID);
35
}
36
}
37
38
// start a new session of the typing speed test
39
var startSpeedTypingTest = function(){
40
41
// turn on the timer
42
if(!isCounterOn){
43
isCounterOn = true;
44
startTimerCounter();
45
}
46
47
// turn off the timer, hide input field, and show results
48
if(numberOfSymbolsEntered >= 125){
49
50
// switch the counter boolean
51
isCounterOn = false;
52
53
// show a reset button and set it in focus
54
restartButton.style.display = "block";
55
restartButton.focus();
56
57
// show a deadline text and add a final value
58
scoreHeader.style.display = "inline-block";
59
scoreHeader.textContent = `You are typing ${symbolsPerSecond} symbols per second`;
60
61
// hide the text area dom element and disable its functionality
62
inputFieldElement.style.display = "none";
63
inputFieldElement.removeEventListener("input", startSpeedTypingTest);
64
65
}
66
67
// update the counter of entered symbols and calculate the rate per second
68
numberOfSymbolsEntered++;
69
getSymbolsPerSecond();
70
71
}
72
73
// start the typing speed test by typing in the text field
74
inputFieldElement.addEventListener("input", startSpeedTypingTest)
75
76
// restart the test by clicking the button
77
restartButton.addEventListener("click", function(){
78
79
// reset the variables to the initial values
80
iterationCounter = 0;
81
symbolsPerSecond = 0;
82
numberOfSymbolsEntered = 0;
83
84
// reset the apperance and values of the dom elements
85
inputFieldElement.value = "";
86
restartButton.style.display = "none";
87
scoreHeader.style.display = "none";
88
inputFieldElement.style.display = "block";
89
90
// set the input in focus and add functionality
91
inputFieldElement.focus();
92
inputFieldElement.addEventListener("input", startSpeedTypingTest)
93
94
// reset the gauge's marker to the initial value
95
gauge.data().set(0,"value", 0);
96
97
})
98
99
}
100
101
anychart.onDocumentReady(function () {
102
103
// create a linear gauge
104
var gauge = anychart.gauges.linear();
105
106
// set the horizontal layout
107
gauge.layout("horizontal");
108
109
// add data
110
gauge.data([numberOfSymbolsEntered]);
111
112
// configure the scale
113
var scale = gauge.scale();
114
scale.minimum(-2);
115
scale.maximum(30);
116
scale.ticks().interval(2);
117
118
// configure the axis
119
var axis = gauge.axis(0);
120
axis.offset("5%");
121
axis.orientation("bottom");
122
123
// configure the scale bar
124
var scaleBar = gauge.scaleBar(0);
125
scaleBar.width("5%");
126
127
// create a color scale
128
var scaleBarColorScale = anychart.scales.ordinalColor().ranges([
129
{from: -2, to: 0, color: ["grey 0.9"]},
130
{from: 0, to: 10, color: ["green 0.9"]},
131
{from: 10, to: 20, color: ["yellow 0.9"]},
132
{from: 20, to: 27, color: ["red 0.9"]},
133
{from: 27, to: 30, color: ["darkRed 0.9"]}
134
]);
135
136
// apply the color scale
137
scaleBar.colorScale(scaleBarColorScale);
138
139
// remove the background color
140
gauge.background("transparent");
141
142
// configure the marker pointer
143
var pointer = gauge.marker(0);
144
pointer.color("black");
145
pointer.zIndex(1);
146
pointer.type("triangle-down");
147
pointer.offset("-5%");
148
149
// get labels
150
var labels = pointer.labels();
151
labels.enabled(true);
152
labels.fontColor("#black");
153
labels.offsetY("-10%");
154
labels.useHtml(true);
155
labels.format(function(){
156
return `<b>${this.value}</b><br>symbols/sec`
157
});
158
159
// set the container id
160
gauge.container("container");
161
162
// initiate the drawing of the linear gauge
163
gauge.draw();
164
165
// initialize typing speed test
166
speedTypingTest(gauge);
167
168
});