-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
132 lines (118 loc) · 4.15 KB
/
main.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
// static/main.js
// The main logic for our task.
"use strict";
// We follow a rule of only creating two global variables.
// `globals` is an object containing any information we want to make
// gloabally available in the task. `state` is an object containing
// information that is globally available, AND which will be sent to
// the server at the end of each trial;
// We populate both with default values now, so we can know at a
// glance what values they can store. This is better than adding new
// values on an ad-hoc basis, which often leads to bugs.
let globals = {
resp_keys: [70, 74], // F, J
fixation_time: 1000,
feedback_time: 2000,
n_trials: 12
};
let state = {
// `width` and `height` get updated every time the window is resized.
width: null,
height: null,
subject_nr: get_subject_nr(),
target_size: null, // Between-subject manipulation
trial_nr: 0,
t_start_experiment: null,
t_start_trial: null,
t_response: null,
target_right: null,
flanker_right: null,
response: null,
said_right: null,
rt: null,
accuracy: null
};
// When everything's loaded, call the `Ready` function
primate.ready(Ready);
// We break the logic of the task up into individual functions, named
// using CapsCase. Each function either calls the next one
// immmediately, calls it after a delay, or tells the page to wait for
// some user input before triggering the next function.
function Ready(){
// If you need to do any logic before begining, put it here.
// This line is necessary for running on Gorilla,
// but does nothing otherwise.
primate.populate('#gorilla', 'body', {});
// Hide everything we don't want to see yet
$('#gorilla').children().hide();
on_resize(); // Check window size now
$( window ).resize(_.debounce(on_resize, 100)); // And every time it changes
$('#gorilla').show();
state.t_start_experiment = Date.now();
// Get the manipulation if running on Gorilla. Flip a coin otherwise.
let target_size = state.target_size = primate.manipulation(
'target_size', _.sample(['2.5', '7.5']));
target_size = target_size + 'vh';
$('#target, #target > img').css('height', target_size);
$('#start').show();
bind_to_key(PrepareTrial, 32); // 32 = spacebar
};
function PrepareTrial(){
// Prepare stimuli and show fixation
$('#start').hide();
state.target_right = flip();
state.flanker_right = flip();
let inner = state.target_right ? 'right' : 'left';
let outer = state.flanker_right ? 'right' : 'left';
$('img.flanker').attr('src', primate.stimuliURL(outer+'.svg'));
$('img.target').attr('src', primate.stimuliURL(inner+'.svg'));
$('#fix').show();
// Wait, then start trial
setTimeout(StartTrial, globals.fixation_time);
};
function StartTrial(){
// Hide fixation, show target, note time, and bind next stage to
// the spacebar
$('#fix').hide();
$('#target').show();
state.t_start_trial = Date.now();
$(document).off('keydown').on('keydown', CheckResponse);
};
function CheckResponse(e){
// This is the cross-browser way of getting the key code
let k = (typeof e.which == "number") ? e.which : e.keyCode;
if(globals.resp_keys.indexOf(k) > -1){ ProcessResponse(k); };
}
function ProcessResponse(k){
$(document).off('keydown');
let t = state.t_response = Date.now();
$('#target').hide();
state.response = k;
state.rt = state.t_response - state.t_start_trial;
let said_right = state.said_right = Number(k == globals.resp_keys[1]);
let accuracy = state.accuracy = Number(state.target_right == said_right);
if(accuracy){
LogData();
} else {
ErrorFeedback();
}
}
function ErrorFeedback(){
$('#feedback').show();
setTimeout(LogData, globals.feedback_time);
}
function LogData(){
$('#feedback').hide();
primate.metric(state);
state.trial_nr +=1;
if(state.trial_nr >= globals.n_trials){
EndExperiment();
} else {
PrepareTrial();
}
}
function EndExperiment(){
$('#end').show();
// Redirect in 3 seconds (if not running on Gorilla)
setTimeout( e => primate.finish('https://imgur.com/r/puppies'), 3000);
}