forked from joshgerdes/jekyll-uno
/
SimpleRT_Aurora.html
407 lines (336 loc) · 14.6 KB
/
SimpleRT_Aurora.html
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 8]>
<script type="text/javascript">
alert("The content of this web page may not work as intended in " +
"the current browser. " +
"Internet Explorer 8 or newer is required for full functionality.");
</script>
<![endif]-->
<!-- © 2020 The Many Brains Project, Inc. and McLean Hospital
This code is made available under a Creative Commons Attribution-Share Alike
4.0 International license (CC BY-SA 4.0).
https://creativecommons.org/licenses/by-sa/4.0/ This script may be shared,
with appropriate credit, and reasonable indication of any changes that were
made. If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
Production version: saves data to server.
Revision 01.26.16 by PM & LG
- Updated library (v. 01.26.16)
- Added outcome variables
- Added synch to frame via requestAnimationFrame to improve
timing accuracy
- We now have 4 versions: full spec, standalone, demo and production
-->
<head>
<!-- Metadata ************************************************************** -->
<meta charset="UTF-8">
<meta name="description" content="Simple Reaction Time Test">
<meta name="copyright" content="2020 The Many Brains Project, Inc. and McLean Hospital">
<meta name="author" content="Paolo Martini">
<meta name="keywords" content="reaction time, cognitive test, brain test">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- End of metadata ******************************************************* -->
<!-- Title ***************************************************************** -->
<title>Fast Reactions Test</title>
<!-- End of Title ********************************************************** -->
<!-- css Style declarations ************************************************ -->
<style type="text/css">
body
{
height: 97vh;
background: #ffffff;
color: #000000;
font-family: Palatino Linotype, Bookman Antiqua, Palatino, serif;
font-size:13pt;
}
.inst
{
margin: 0 auto;
display: block;
text-align: center;
background: #ffffff;
color: #000000;
font-size:25pt;
font-family: Palatino Linotype, Bookman Antiqua, Palatino, serif;
}
.button
{
font-size:18px;
line-height:2em;
text-align:center;
font-family: Palatino Linotype, Bookman Antiqua, Palatino, serif;
}
.stim
{
width: 200px;
height: 160px;
clear: both;
border: 1px solid #000000;
position: absolute;
left: 50%;
top: 50%;
margin-top: -80px;
margin-left: -100px;
text-align:center;
font-size:50px;
font-family: Palatino Linotype, Bookman Antiqua, Palatino, serif;
}
</style>
<!-- end of css declarations *********************************************** -->
<!-- js libraries ********************************************************** -->
<script type="text/javascript" src="TestMyBrain.01.26.16.min.js"></script>
<!-- end of js libraries *************************************************** -->
<!-- SimpleRT script ******************************************************* -->
<script type="text/javascript">
var rts = []; // rt array
var dwells = []; // dwell times array
var score = 0; // score variable
var timeouts = 0; // number of timeouts
var outcomes = {}; // object containing outcome variables
var results = []; // array to store trials details and responses
var frameSequence = []; // object containing the sequence of frames and their properties
var ch; // chain of timeouts for stimulus presentation
var frame; // single frame object
// output a message and execute an action
function showAlert(alertMessage,alertButtonText,action,timeout)
{
// set the message to display
getID('alertText').innerHTML = alertMessage;
// if args contain button text,
// show the button and set the required action for it,
// otherwise hide the button
if(alertButtonText && !timeout)
{
getID('alertButton').style.width='300px';
getID('alertButton').style.margin='0 auto';
getID('alertButton').style.display='block';
getID('alertButton').innerHTML = alertButtonText;
getID('alertButton').onclick = action;
showCursor("document.body");
}
else getID('alertButton').style.display='none';
// if args contain a timeout,
// trigger the action automatically when timeout expires
if(timeout) setTimeout(action,timeout);
showFrame('alertBox');
}
// specify actions to take on user input
tmbUI.onreadyUI = function()
{
// clear the stimulus chain, in case it's still running
clearChainTimeouts(ch);
// store the results
results.push(
{
type: frame.type, // one of practice or test
foreperiod: frame.delay, // go! foreperiod
response: tmbUI.response, // the key or button pressed
rt: tmbUI.rt, // delay b/w onset of go! and response
dwell: tmbUI.dwell, // keyup - keydown
state: tmbUI.status // state of the response handler
});
// if the input event returns a timeout,
// stop the sequence and advise the participant
if(tmbUI.status == "timeout")
{
// rewind the frame sequence by one frame,
// so that the same frame is displayed again
frameSequence.unshift(frame);
// count timeouts
if(frame.type == "test") timeouts++;
showAlert("<br>Please respond within 2 seconds.<br><br>" +
"When you see <b>GO!</b>,<br>" +
(hasTouch ? "<b>TAP</b> as quickly as you can.<br><br>"
: "press the <b>SPACE BAR</b> " +
"as quickly as you can.<br><br>"),
"Click here to retry",
function()
{
hideCursor("document.body");
showFrame("null");
setTimeout(function(){nextTrial();},1000);
});
}
// else all is good, advance to the next trial
else
{
if(frame.type == "test")
{
rts.push(tmbUI.rt);
dwells.push(tmbUI.dwell);
}
nextTrial();
}
};
// iterate through the frameSequence object,
// implementing stimulus presentation,
// response collection and data management
function nextTrial()
{
// read the frame sequence one frame at a time
if(frame = frameSequence.shift())
{
// check if it's the startup frame
if(frame.type=="begin") showAlert(frame.message,
"Click here for instructions",
function() {nextTrial();});
// else if it's a message frame, show it
else if(frame.type=="message") showAlert(frame.message,
"Click here to continue",
function ()
{
hideCursor("document.body");
showFrame("null");
setTimeout(function(){nextTrial();},1000);
});
// else show the go signal
else
{
hideCursor("document.body");
// chain the stimulus presentation
ch = chainTimeouts(
function()
{
requestAnimationFrame(function()
{
showFrame(null);
});
},
700,
function()
{
requestAnimationFrame(function()
{
showFrame("hold");
});
},
frame.delay,
function()
{
requestAnimationFrame(function()
{
showFrame("go");
tmbUI.getInput();
});
}
);
}
}
// else if the sequence is empty, we are done!
else
{
showCursor("document.body");
// compute score and outcome variables
if(rts.length)
{
// score is 10000/avgRT, capped at 100 for avgRT<=100ms
score = rts.average();
score = score < 100 ? 100 : 10000 / score;
score = score.round(2);
outcomes.sRT_meanRT = rts.average().round(2);
outcomes.sRT_medianRT = rts.median().round(2);
outcomes.sRT_sdRT = rts.sd().round(2);
}
tmbSubmitToServer(results,score,outcomes);
}
}
// generate the frameSequence object,
// where each object's element codes the parameters
// for a single trial/frame
function setFrameSequence ()
{
var testMessage;
// messages
testMessage =
{
"begin": ("<br><h2>Fast Reactions Test</h2><br>" +
"How fast can you react?<br><br>"),
"practice": ("<br><h3>Practice:</h3><br>" +
"When you see <b>GO!</b><br>" +
(hasTouch ? "<b>TAP</b> "
: "press the <b>SPACE BAR</b> ") +
"as quickly as you can.<br><br>" +
"Use a finger on your writing hand.<br><br>"),
"test": ("<br>Excellent!<br>" +
"You have completed the practice.<br><br>" +
"Now let's do 30 more.<br><br>") +
"When you see <b>GO!</b><br>" +
(hasTouch ? "<b>TAP</b> "
: "press the <b>SPACE BAR</b> ") +
"as quickly as you can.<br><br>"
};
// Practice sequence
// type of frame to display
var frameType = ["begin","message","practice","practice","practice","message"];
// message to display
var frameMessage = [testMessage.begin,testMessage.practice,
"","","",testMessage.test];
// push all components into the frames chain
for(var i=0; i<frameType.length; i++)
{
frameSequence.push(
{
type: frameType[i],
message: frameMessage[i],
delay: 1000
});
}
// Test sequence
var frameDelay = [1300,700,700,700,700,1100,700,1100,900,900,
700,700,1300,1100,1300,700,900,700,1500,700,
1500,900,900,700,1100,900,700,900,700,900];
for(i=0; i<30; i++)
{
frameSequence.push(
{
type: "test",
message: "",
delay: frameDelay[i]
});
}
}
// on page load completion, set up initial parameters,
// call the frameSequence generator
// and start the trials sequence
window.onload = function()
{
// determine events to listen to
if(hasTouch) tmbUI.UIevents = ['taps','clicks'];
else tmbUI.UIevents = ['keys'];
// set response timeout to 2 seconds
tmbUI.timeout = 2000;
// disable spurious user interaction
disableSelect();
disableRightClick();
disableDrag();
// create the trials chain and start the testing sequence
setFrameSequence();
nextTrial();
}
</script>
<!-- end of SimpleRT script ************************************************ -->
</head>
<body>
<!-- this DIV is used to show a message and continue the test sequence-->
<div id="alertBox" class="inst" style="display: none">
<span class="instSpan" id="alertText">This is a placeholder.</span>
<button type="button" class="button" id="alertButton">Click here</button>
<br>
</div>
<!-- this DIV shows the hold signal -->
<div id="hold" class="stim" style="display: none; background-color: #ff0000">
<br>WAIT
</div>
<!-- this DIV shows the go signal -->
<div id="go" class="stim" style="display: none; background-color: #00FF00">
<br>GO!
</div>
<!-- if Javascript is disabled, we instruct the user to enable it------->
<noscript>
For full functionality of this site it is necessary to enable JavaScript.<br>
Here are the <a href="http://www.enable-javascript.com/" target="_blank">
instructions</a> how to enable JavaScript in your web browser.
</noscript>
</body>
</html>