-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanticipatory gaze.html
203 lines (182 loc) · 7.13 KB
/
anticipatory gaze.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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Anticipatory Gaze</title>
<script src="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/jspsych.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/plugins/jspsych-html-keyboard-response.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/plugins/jspsych-image-keyboard-response.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/plugins/jspsych-html-slider-response.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/plugins/jspsych-audio-button-response.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jspsych@6.3.1/css/jspsych.css">
<link rel="stylesheet" href="style.css">
<style>
.jspsych-btn1 {
background-color: #696969;
color: #696969;
border: 2px solid #696969;
cursor: none;
border-radius: 4px;
}
.jspsych-btn2 {
background-color: #696969;
color: #8FBC8F;
border: 2px solid #696969;
cursor: pointer;
border-radius: 4px;
}
</style>
</head>
<body></body>
<script>
// Define the image stimuli and probabilities
const images = [
'image1.png',
'image2.png',
'image3.png',
'image4.png',
'image5.png',
'image6.png'
];
// Define the probability levels and shuffle them
let probabilities = [0, 0.2, 0.4, 0.6, 0.8, 1]; //Hütter & Niese also include CSs which are NEVER or ALWAYS associated with pos/neg
probabilities = jsPsych.randomization.shuffle(probabilities);
// Assign the shuffled probabilities to the images
const imageProbabilities = {};
images.forEach((image, index) => {
imageProbabilities[image] = probabilities[index];
});
// Randomly determine the position of "+" for each subject
const plusPosition = Math.random() < 0.5 ? 'left' : 'right';
// Assign the position of "-" based on the position of "+"
const minusPosition = plusPosition === 'left' ? 'right' : 'left';
// Randomize the positions for each subject
const positions = jsPsych.randomization.shuffle([
{left: '50%', top: '10%'},
{left: '75%', top: '25%'},
{left: '75%', top: '75%'},
{left: '50%', top: '90%'},
{left: '25%', top: '75%'},
{left: '25%', top: '25%'}
]);
// Create fixation cross and blank screen trials
const fixation = {
type: 'html-keyboard-response',
stimulus: '<div style="font-size: 48px; color: #8FBC8F;">*</div>',
choices: jsPsych.NO_KEYS,
trial_duration: 500
};
const blank = {
type: 'html-keyboard-response',
stimulus: '',
choices: jsPsych.NO_KEYS,
trial_duration: 500
};
const instruct = {
type: 'html-keyboard-response',
stimulus: '<div style="font-size: 48px; color: #8FBC8F;">Click an image to see a new evaluation!</div>',
choices: jsPsych.NO_KEYS,
trial_duration: 1000
};
const display_images = {
type: 'html-keyboard-response',
stimulus: '<div id="images-container"></div>',
choices: jsPsych.NO_KEYS,
on_start: function(trial) {
let html = '';
for (let i = 0; i < images.length; i++) {
const style = `position: absolute; left: ${positions[i].left}; top: ${positions[i].top}; width: 100px; height: 100px; cursor: pointer;`;
html += `<img src="${images[i]}" style="${style}" id="img-${i}" data-image="${images[i]}" onclick="handleImageClick(event)" />`;
}
trial.stimulus = html;
},
on_finish: function(data) {
data.clicked_image = window.clicked_image;
const prob = imageProbabilities[window.clicked_image];
const symbol = Math.random() < prob ? 'pos.png' : 'neg.png';
data.symbol = symbol;
window.last_symbol = symbol;
console.log(`Symbol chosen: ${symbol}`);
}
};
// Function to handle image click
function handleImageClick(event) {
const clicked_image = event.target.dataset.image;
const prob = imageProbabilities[clicked_image];
console.log(`Clicked image: ${clicked_image}, Probability: ${prob}`);
window.clicked_image = clicked_image;
jsPsych.finishTrial();
}
const followup_image = {
type: 'audio-button-response',
css_classes: ['jspsych-btn1'],
stimulus: function() {
const symbol = window.last_symbol;
return symbol === 'pos.png' ? 'pos.m4a' : 'neg.m4a';
},
prompt: function() {
const symbol = window.last_symbol;
const symbolPosition = symbol === 'pos.png' ? plusPosition : minusPosition;
const symbolPositionStyle = symbolPosition === 'left' ? 'left: 20%;' : 'right: 20%;';
const transformStyle = symbolPosition === 'left' ? '' : 'transform: translateX(-100%);';
return `
<img src="${symbol}" style="position: absolute; top: 50%; ${symbolPositionStyle} transform: translateY(-50%); width: 50px; height: 50px;">
<img src="cover.png" style="position: absolute; top:45%; left: 45%;">
`;
},
choices: [' '],
trial_duration: 2000,
on_start: function(trial) {
const symbol = window.last_symbol;
console.log(`Follow-up image displayed: ${symbol}`);
},
on_finish: function(trial) {
console.log('Follow-up image finished');
}
};
// Create evaluation trials for each image
const evaluation_trials = images.map((image) => {
return {
type: 'html-slider-response',
stimulus: `<img src="${image}" style="width: 200px; height: 200px;">`,
labels: ['Negative', 'Positive'],
min: 0,
max: 100,
start: 50,
prompt: '<p>How do you feel about this square?</p>',
require_movement: true,
css_classes: ['jspsych-btn2'],
};
});
// Define the main procedure
const main_procedure = {
timeline: []
};
// Add the phases to the main procedure
for (let i = 0; i < 20; i++) { // Change to desired trial limit, 60 in Hütter an Niese
main_procedure.timeline.push(instruct);
main_procedure.timeline.push(fixation);
main_procedure.timeline.push(blank);
main_procedure.timeline.push(display_images);
main_procedure.timeline.push(blank);
main_procedure.timeline.push(fixation);
main_procedure.timeline.push(followup_image);
main_procedure.timeline.push(blank);
}
// Initialize jsPsych
jsPsych.init({
timeline: [...evaluation_trials, main_procedure, ...evaluation_trials],
on_finish: function() {
jsPsych.data.displayData();
},
on_trial_start: function(trial) {
// Monitor for "q" press
document.addEventListener('keydown', function(event) {
if (event.key === 'q') {
jsPsych.endExperiment();
}
});
}
});
</script>
</html>