added timer to survey
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
VITE_DEBUG=true
|
|
||||||
VITE_COMPLETE_URL=
|
|
||||||
VITE_CLOSED_URL=
|
|
||||||
VITE_EXPERIMENT_TITLE=
|
|
||||||
VITE_EXPERIMENT_NAME=
|
|
||||||
VITE_DEPLOY_URL=
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
VITE_DEBUG=false
|
|
||||||
VITE_COMPLETE_URL=
|
|
||||||
VITE_CLOSED_URL=
|
|
||||||
VITE_EXPERIMENT_TITLE=
|
|
||||||
VITE_EXPERIMENT_NAME=
|
|
||||||
VITE_DEPLOY_URL=
|
|
||||||
180
index.js
180
index.js
@@ -10,16 +10,18 @@ import '@jspsych/plugin-survey/css/survey.css';
|
|||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { getStimulusMap } from './scripts/text-stimuli.js';
|
import { getStimulusMap } from './scripts/text-stimuli.js';
|
||||||
import jsPsychObjectMoving from './scripts/plugin-object-moving.js';
|
import jsPsychObjectMoving from './scripts/plugin-object-moving.js';
|
||||||
|
import { textStimuli } from './scripts/text-stimuli.js';
|
||||||
|
|
||||||
const debug = import.meta.env.VITE_DEBUG === 'true';
|
const total_participants = import.meta.env.VITE_TOTAL_PARTICIPANTS || 2;
|
||||||
const total_participants = import.meta.env.VITE_TOTAL_PARTICIPANTS;
|
|
||||||
const uniqueUsernames = generateUniqueUsernames(total_participants);
|
const uniqueUsernames = generateUniqueUsernames(total_participants);
|
||||||
const experiment_name = import.meta.env.VITE_EXPERIMENT_NAME;
|
const experiment_name = import.meta.env.VITE_EXPERIMENT_NAME;
|
||||||
|
|
||||||
|
|
||||||
let prolific_id;
|
let prolific_id;
|
||||||
let probe_condition; // P in the params, O = open, S = suspicion mentioned
|
let probe_condition; // P in the params, O = open, S = suspicion mentioned
|
||||||
let mapping; // M in the params, TB = together blue, AB = alone blue
|
let debug = false;
|
||||||
let short_version = false;
|
|
||||||
|
const short_version = true; // just using the short version of the task
|
||||||
|
|
||||||
function delayed_redirect(url) {
|
function delayed_redirect(url) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -28,51 +30,68 @@ function delayed_redirect(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const jsPsych = initJsPsych({
|
const jsPsych = initJsPsych({
|
||||||
on_finish: function() {
|
on_finish: function () {
|
||||||
jsPsych.getDisplayElement().innerHTML = textStimuli.complete;
|
jsPsych.getDisplayElement().innerHTML = textStimuli.complete;
|
||||||
},
|
},
|
||||||
on_close: function() {
|
on_close: function () {
|
||||||
delayed_redirect(import.meta.env.VITE_CLOSED_URL);
|
delayed_redirect(import.meta.env.VITE_CLOSED_URL);
|
||||||
},
|
},
|
||||||
on_data_update: function() {
|
on_data_update: function () {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log(jsPsych.data.get().json());
|
console.log(jsPsych.data.get().json());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
prolific_id = jsPsych.data.getURLVariable('PROLIFIC_PID');
|
debug = jsPsych.data.getURLVariable('debug') === 'true';
|
||||||
mapping = jsPsych.data.getURLVariable('M');
|
|
||||||
short_version = jsPsych.data.getURLVariable('S') === 'true';
|
|
||||||
const together_colour = mapping === 'TB' ? 'blue' : 'red';
|
|
||||||
const stimulusMap = getStimulusMap(together_colour);
|
|
||||||
|
|
||||||
probe_condition = jsPsych.data.getURLVariable('P');
|
prolific_id = jsPsych.data.getURLVariable('PROLIFIC_PID');
|
||||||
|
|
||||||
|
const COND = Number(jsPsych.data.getURLVariable('C'));
|
||||||
|
|
||||||
|
const probe_text_direct = 'Did you have any thoughts, observations, or suspicions about the experiment?'
|
||||||
|
const probe_text_indirect = 'Did you have any thoughts or observations about the experiment?';
|
||||||
|
|
||||||
|
let together_colour;
|
||||||
let probe_text;
|
let probe_text;
|
||||||
if (probe_condition === 'O') {
|
|
||||||
probe_text =
|
|
||||||
'Did you have any thoughts or observations about the experiment?';
|
switch (COND) {
|
||||||
} else if (probe_condition === 'S') {
|
case 0:
|
||||||
probe_text =
|
probe_condition = 'direct';
|
||||||
'Did you have any thoughts, observations, or suspicions about the experiment?';
|
together_colour = 'blue';
|
||||||
} else if (probe_condition === 'D') {
|
break;
|
||||||
probe_text =
|
case 1:
|
||||||
'Many studies use deception to create the appearance that you are interacting with a real person. Did you suspect that you were not interacting with a real person?';
|
probe_condition = 'direct';
|
||||||
} else if (probe_condition === 'R') {
|
together_colour = 'red';
|
||||||
probe_text =
|
break;
|
||||||
'Our study used deception to create the appearance that you are interacting with a real person. Did you suspect that you were not interacting with a real person?';
|
case 2:
|
||||||
} else {
|
probe_condition = 'indirect';
|
||||||
probe_text =
|
together_colour = 'blue';
|
||||||
'Did you have any thoughts or observations about the experiment?';
|
break;
|
||||||
|
case 3:
|
||||||
|
probe_condition = 'indirect';
|
||||||
|
together_colour = 'red';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsPsych.data.addProperties({
|
probe_text = probe_condition === 'direct' ? probe_text_direct : probe_text_indirect;
|
||||||
|
|
||||||
|
const stimulusMap = getStimulusMap(together_colour);
|
||||||
|
|
||||||
|
const props = {
|
||||||
condition: probe_condition,
|
condition: probe_condition,
|
||||||
together_colour: together_colour,
|
together_colour: together_colour,
|
||||||
prolific_id: prolific_id,
|
prolific_id: prolific_id,
|
||||||
experiment_name: experiment_name,
|
experiment_name: experiment_name,
|
||||||
probe_text: probe_text,
|
probe_text: probe_text,
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
console.log(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsPsych.data.addProperties(props);
|
||||||
|
|
||||||
const timeline = [];
|
const timeline = [];
|
||||||
|
|
||||||
@@ -91,7 +110,7 @@ const consent_form = {
|
|||||||
type: jsPsychHtmlButtonResponse,
|
type: jsPsychHtmlButtonResponse,
|
||||||
stimulus: stimulusMap.get('consent'),
|
stimulus: stimulusMap.get('consent'),
|
||||||
choices: ['Exit', 'Continue'],
|
choices: ['Exit', 'Continue'],
|
||||||
on_finish: function(data) {
|
on_finish: function (data) {
|
||||||
if (data.response === 0) {
|
if (data.response === 0) {
|
||||||
jsPsych.abortExperiment(stimulusMap.get('no_consent'));
|
jsPsych.abortExperiment(stimulusMap.get('no_consent'));
|
||||||
}
|
}
|
||||||
@@ -176,8 +195,39 @@ const debrief = {
|
|||||||
stimulus: stimulusMap.get('debrief'),
|
stimulus: stimulusMap.get('debrief'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pre_survey_info = {
|
||||||
|
type: jsPsychHtmlKeyboardResponse,
|
||||||
|
choices: [' '],
|
||||||
|
stimulus: stimulusMap.get('pre_survey_info'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const survey_function = (survey) => {
|
||||||
|
survey.onAfterRenderPage.add(function (sender, options) {
|
||||||
|
if (survey.activePage.name === 'page1') {
|
||||||
|
const nextButton = document.querySelector('#sv-nav-next > div > input');
|
||||||
|
if (nextButton) {
|
||||||
|
let seconds = 30;
|
||||||
|
const originalText = nextButton.value.replace(/\s*\(\d+\)$/, '') || 'Continue';
|
||||||
|
nextButton.disabled = true;
|
||||||
|
nextButton.value = `${originalText} (${seconds})`;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
seconds--;
|
||||||
|
nextButton.value = `${originalText} (${seconds})`;
|
||||||
|
if (seconds <= 0) {
|
||||||
|
clearInterval(interval);
|
||||||
|
nextButton.disabled = false;
|
||||||
|
nextButton.value = originalText;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
console.log('Survey page rendered:', sender.currentPage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const survey = {
|
const survey = {
|
||||||
type: jsPsychSurvey,
|
type: jsPsychSurvey,
|
||||||
|
survey_function: survey_function,
|
||||||
survey_json: {
|
survey_json: {
|
||||||
showQuestionNumbers: false,
|
showQuestionNumbers: false,
|
||||||
completeText: 'Done!',
|
completeText: 'Done!',
|
||||||
@@ -187,48 +237,18 @@ const survey = {
|
|||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
name: 'page1',
|
name: 'page1',
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
type: 'radiogroup',
|
|
||||||
title: 'Please indicate your gender',
|
|
||||||
choices: ['Male', 'Female', 'Other'],
|
|
||||||
isRequired: debug ? false : true,
|
|
||||||
colCount: 0,
|
|
||||||
name: 'gender',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'radiogroup',
|
|
||||||
title: 'Please indicate your handedness',
|
|
||||||
choices: ['Right', 'Left', 'Ambidextrous/Other'],
|
|
||||||
isRequired: debug ? false : true,
|
|
||||||
colCount: 0,
|
|
||||||
name: 'handedness',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
title: 'How old are you?',
|
|
||||||
name: 'age',
|
|
||||||
isRequired: debug ? false : false,
|
|
||||||
inputType: 'number',
|
|
||||||
min: 18,
|
|
||||||
max: 100,
|
|
||||||
defaultValue: 18,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'page2',
|
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: 'comment',
|
type: 'comment',
|
||||||
title: probe_text,
|
title: probe_text,
|
||||||
|
description: 'You may continue to the next page after 30 seconds.',
|
||||||
name: 'probe',
|
name: 'probe',
|
||||||
isRequired: debug ? false : true,
|
isRequired: debug ? false : true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'page3',
|
name: 'page2',
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
type: 'matrix',
|
type: 'matrix',
|
||||||
@@ -271,6 +291,37 @@ const survey = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'page1',
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: 'radiogroup',
|
||||||
|
title: 'Please indicate your gender',
|
||||||
|
choices: ['Male', 'Female', 'Other'],
|
||||||
|
isRequired: debug ? false : true,
|
||||||
|
colCount: 0,
|
||||||
|
name: 'gender',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'radiogroup',
|
||||||
|
title: 'Please indicate your handedness',
|
||||||
|
choices: ['Right', 'Left', 'Ambidextrous/Other'],
|
||||||
|
isRequired: debug ? false : true,
|
||||||
|
colCount: 0,
|
||||||
|
name: 'handedness',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
title: 'How old are you?',
|
||||||
|
name: 'age',
|
||||||
|
isRequired: debug ? false : false,
|
||||||
|
inputType: 'number',
|
||||||
|
min: 18,
|
||||||
|
max: 100,
|
||||||
|
defaultValue: 18,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -323,8 +374,8 @@ const object_moving_practice = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
timeline.push(survey);
|
|
||||||
timeline.push(debrief);
|
timeline.push(debrief);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
@@ -343,6 +394,7 @@ if (!debug) {
|
|||||||
timeline.push(pre_task_instructions);
|
timeline.push(pre_task_instructions);
|
||||||
timeline.push(lobby_fast);
|
timeline.push(lobby_fast);
|
||||||
timeline.push(object_moving_trials);
|
timeline.push(object_moving_trials);
|
||||||
|
timeline.push(pre_survey_info);
|
||||||
timeline.push(survey);
|
timeline.push(survey);
|
||||||
timeline.push(debrief);
|
timeline.push(debrief);
|
||||||
}
|
}
|
||||||
|
|||||||
961
package-lock.json
generated
961
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,13 @@
|
|||||||
"vite": "^6.3.1"
|
"vite": "^6.3.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@jspsych/plugin-fullscreen": "^2.1.0",
|
||||||
|
"@jspsych/plugin-html-button-response": "^2.1.0",
|
||||||
"@jspsych/plugin-html-keyboard-response": "^2.1.0",
|
"@jspsych/plugin-html-keyboard-response": "^2.1.0",
|
||||||
|
"@jspsych/plugin-survey": "^2.1.0",
|
||||||
"@tailwindcss/vite": "^4.1.4",
|
"@tailwindcss/vite": "^4.1.4",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
|
"dotenv": "^17.0.1",
|
||||||
"jspsych": "^8.2.1",
|
"jspsych": "^8.2.1",
|
||||||
"prettier-plugin-html-template-literals": "^1.0.5",
|
"prettier-plugin-html-template-literals": "^1.0.5",
|
||||||
"tailwindcss": "^4.1.4",
|
"tailwindcss": "^4.1.4",
|
||||||
|
|||||||
@@ -160,9 +160,9 @@ class jsPsychObjectMoving {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initiate_partner_action(){
|
function initiate_partner_action(){
|
||||||
const go_delay = trial.selector === 'participant' ? 1200 : 800
|
const go_delay = trial.selector === 'participant' ? 1400 : 1000
|
||||||
const partner_go_delay = jsPsych.randomization.sampleExGaussian(go_delay, 300, 1/100, true);
|
const partner_go_delay = jsPsych.randomization.sampleExGaussian(go_delay, 500, 1/100, true);
|
||||||
const partner_teleport_delay = jsPsych.randomization.sampleExGaussian(1200, 200, 1/100, true);
|
const partner_teleport_delay = jsPsych.randomization.sampleExGaussian(1400, 300, 1/100, true);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
change_object_colour(object_partner);
|
change_object_colour(object_partner);
|
||||||
|
|||||||
@@ -15,10 +15,15 @@ const redImages = {
|
|||||||
instructions_4: '/images/red/instructions_4.png',
|
instructions_4: '/images/red/instructions_4.png',
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = (strings, ...values) =>
|
import html from '../utils/html.js';
|
||||||
strings
|
|
||||||
.reduce((result, str, i) => result + str + (values[i] || ''), '')
|
export const textStimuli = {
|
||||||
.trim();
|
complete: html`Experiment complete. Please paste the following link into your browser to confirm completion on Prolific:
|
||||||
|
<span class="text-blue-500">
|
||||||
|
${import.meta.env.VITE_COMPLETE_URL}
|
||||||
|
</a>
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
function getStimulusMap(together_colour) {
|
function getStimulusMap(together_colour) {
|
||||||
const colourMap = getColourMap(together_colour);
|
const colourMap = getColourMap(together_colour);
|
||||||
@@ -28,6 +33,23 @@ function getStimulusMap(together_colour) {
|
|||||||
// Select the appropriate image map based on the color
|
// Select the appropriate image map based on the color
|
||||||
const imageMap = together_colour === 'blue' ? blueImages : redImages;
|
const imageMap = together_colour === 'blue' ? blueImages : redImages;
|
||||||
|
|
||||||
|
|
||||||
|
stimulusMap.set('pre_survey_info', html`
|
||||||
|
<p class="leading-relaxed">
|
||||||
|
You will now answer a few questions about your experience in the experiment. It is important that you read the questions carefully and answer them honestly.
|
||||||
|
</p>
|
||||||
|
<p class ="leading-relaxed mt-2">
|
||||||
|
Nonsense or random answers may lead to your submission being rejected.
|
||||||
|
</p>
|
||||||
|
<p class="mt-6">
|
||||||
|
Press
|
||||||
|
<strong>SPACE</strong>
|
||||||
|
to continue.
|
||||||
|
</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
stimulusMap.set(
|
stimulusMap.set(
|
||||||
'pre_consent_info',
|
'pre_consent_info',
|
||||||
html`
|
html`
|
||||||
|
|||||||
Reference in New Issue
Block a user