From 39ddf079739b7160e375f681acbb3f67ef0d9f7e Mon Sep 17 00:00:00 2001 From: Shaheed Azaad Date: Thu, 19 Feb 2026 22:30:33 +0100 Subject: [PATCH] updated survey --- index.js | 298 +++++++++++++------------------ scripts/colours.js | 27 --- scripts/name-gen.js | 77 -------- scripts/plugin-lobby.js | 179 ------------------- scripts/plugin-object-moving.js | 302 -------------------------------- scripts/text-stimuli.js | 180 +------------------ 6 files changed, 128 insertions(+), 935 deletions(-) delete mode 100644 scripts/colours.js delete mode 100644 scripts/name-gen.js delete mode 100644 scripts/plugin-lobby.js delete mode 100644 scripts/plugin-object-moving.js diff --git a/index.js b/index.js index af3aa57..33bda1e 100644 --- a/index.js +++ b/index.js @@ -1,28 +1,20 @@ import { initJsPsych } from 'jspsych'; import 'jspsych/css/jspsych.css'; import jsPsychHtmlKeyboardResponse from '@jspsych/plugin-html-keyboard-response'; -import generateUniqueUsernames from './scripts/name-gen.js'; import jsPsychFullscreen from '@jspsych/plugin-fullscreen'; import jsPsychHtmlButtonResponse from '@jspsych/plugin-html-button-response'; -import jsPsychLobby from './scripts/plugin-lobby.js'; import jsPsychSurvey from '@jspsych/plugin-survey'; import '@jspsych/plugin-survey/css/survey.css'; import './styles.css'; import { getStimulusMap } from './scripts/text-stimuli.js'; -import jsPsychObjectMoving from './scripts/plugin-object-moving.js'; import { textStimuli } from './scripts/text-stimuli.js'; -const total_participants = import.meta.env.VITE_TOTAL_PARTICIPANTS || 2; -const uniqueUsernames = generateUniqueUsernames(total_participants); const experiment_name = import.meta.env.VITE_EXPERIMENT_NAME; - let prolific_id; -let probe_condition; // will be set to neutral or reveal based on the condition +let probe_condition; // will be set to ai or human based on the condition. let debug = false; - - -const short_version = true; // just using the short version of the task +let probe_order; // will be set to ai_first or human_first based on the condition function delayed_redirect(url) { setTimeout(() => { @@ -31,13 +23,13 @@ function delayed_redirect(url) { } const jsPsych = initJsPsych({ - on_finish: function () { + on_finish: function() { jsPsych.getDisplayElement().innerHTML = textStimuli.complete; }, - on_close: function () { + on_close: function() { delayed_redirect(import.meta.env.VITE_CLOSED_URL); }, - on_data_update: function () { + on_data_update: function() { if (debug) { console.log(jsPsych.data.get().json()); } @@ -50,43 +42,62 @@ prolific_id = jsPsych.data.getURLVariable('PROLIFIC_PID'); const COND = Number(jsPsych.data.getURLVariable('C')); -const probe_preamble = 'In this experiment, you worked together with a partner. '; -const probe_closing_text = 'Please share any suspicions you had about your partner during the experiment by indicating your agreement with the following statements.'; +const probe_preamble = `In this experiment, we told you that you would roll a die to determine the difficulty of the captcha task.\nHowever, `; +const probe_closing_text = `\n\nPlease share your thoughts and suspicions about this by indicating your agreement with the following statements.`; -const probe_text_neutral = probe_preamble + probe_closing_text; -const probe_text_reveal = probe_preamble + 'However, due to the difficulty of implementing multi-participant online studies, your partner was actually an AI agent trained to behave like a human participant. ' + probe_closing_text; - -let together_colour; +const probe_text_die = + probe_preamble + + 'the die roll was rigged, so that the number you received (and therefore the difficulty of the captcha task) was pre-determined. ' + + probe_closing_text; +const probe_text_difficulty = + probe_preamble + + 'while the die roll was random, the difficulty of the captcha task was pre-determined and unrelated to the die roll. ' + + probe_closing_text; switch (COND) { case 0: - probe_condition = 'neutral'; - together_colour = 'blue'; + probe_condition = 'die'; + probe_order = 'die_first'; break; case 1: - probe_condition = 'neutral'; - together_colour = 'red'; + probe_condition = 'die'; + probe_order = 'die_first'; break; case 2: - probe_condition = 'reveal'; - together_colour = 'blue'; + probe_condition = 'difficulty'; + probe_order = 'die_first'; break; case 3: - probe_condition = 'reveal'; - together_colour = 'red'; + probe_condition = 'difficulty'; + probe_order = 'die_first'; + break; + case 4: + probe_condition = 'die'; + probe_order = 'difficulty_first'; + break; + case 5: + probe_condition = 'die'; + probe_order = 'difficulty_first'; + break; + case 6: + probe_condition = 'difficulty'; + probe_order = 'difficulty_first'; + break; + case 7: + probe_condition = 'difficulty'; + probe_order = 'difficulty_first'; break; } - -const stimulusMap = getStimulusMap(together_colour); +const stimulusMap = getStimulusMap(); const props = { condition: probe_condition, - together_colour: together_colour, prolific_id: prolific_id, experiment_name: experiment_name, + probe_order: probe_order, cond: COND, -} +}; if (debug) { console.log(props); @@ -111,85 +122,19 @@ const consent_form = { type: jsPsychHtmlButtonResponse, stimulus: stimulusMap.get('consent'), choices: ['Exit', 'Continue'], - on_finish: function (data) { + on_finish: function(data) { if (data.response === 0) { jsPsych.abortExperiment(stimulusMap.get('no_consent')); } }, }; -const initial_lobby = { - type: jsPsychLobby, - user_names: uniqueUsernames, - end_number: total_participants, - start_text: 'Searching for a partner', - end_text: 'Partner found, the experiment will begin shortly.', - join_interval: 5000, - show_avatars: false, -}; - -const lobby_slow = { - type: jsPsychLobby, - user_names: uniqueUsernames, - end_number: total_participants, - start_text: 'Waiting for your partner', - end_text: 'Your partner is ready, the experiment will continue shortly.', - show_avatars: false, - join_interval: 7000, -}; - -const lobby_fast = { - type: jsPsychLobby, - user_names: uniqueUsernames, - end_number: total_participants, - start_text: 'Waiting for your partner', - end_text: 'Your partner is ready, the experiment will continue shortly.', - show_avatars: false, - join_interval: 500, -}; - -const multi_user_instructions = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('multi_user_instructions'), -}; - const instructions_1 = { type: jsPsychHtmlKeyboardResponse, choices: [' '], stimulus: stimulusMap.get('instructions_1'), }; -const instructions_2 = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('instructions_2'), -}; - -const instructions_3 = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('instructions_3'), -}; - -const instructions_4 = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('instructions_4'), -}; - -const pre_practice_instructions = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('pre_practice_instructions'), -}; - -const pre_task_instructions = { - type: jsPsychHtmlKeyboardResponse, - choices: [' '], - stimulus: stimulusMap.get('pre_task_instructions'), -}; - const debrief = { type: jsPsychHtmlKeyboardResponse, choices: [' '], @@ -202,14 +147,27 @@ const pre_survey_info = { stimulus: stimulusMap.get('pre_survey_info'), }; -const survey_function = (survey) => { - survey.onAfterRenderPage.add(function (sender, options) { +const die_probe_row = { + text: + 'I suspected that the die roll was not random, or the number I received was pre-determined.', + value: 'SuspicionDie', +}; + +const difficulty_probe_row = { + text: + 'I suspected that, contrary to what I was told, the captcha task difficulty was not determined by the die roll.', + value: 'SuspicionDifficulty', +}; + +const survey_function = survey => { + survey.onAfterRenderPage.add(function(sender, options) { console.log('Survey page rendered:', sender.currentPage); - if (survey.activePage.name === 'page1') { + if (survey.activePage.name === 'page2') { const nextButton = document.querySelector('#sv-nav-next > div > input'); if (nextButton) { - let seconds = 15; - const originalText = nextButton.value.replace(/\s*\(\d+\)$/, '') || 'Continue'; + let seconds = 20; + const originalText = + nextButton.value.replace(/\s*\(\d+\)$/, '') || 'Continue'; nextButton.disabled = true; nextButton.value = `${originalText} (${seconds})`; const interval = setInterval(() => { @@ -224,8 +182,7 @@ const survey_function = (survey) => { } } }); -} - +}; const survey = { type: jsPsychSurvey, @@ -242,21 +199,27 @@ const survey = { elements: [ { type: 'matrix', - name: probe_condition === 'neutral' ? probe_text_neutral : probe_text_reveal, + name: + 'Please answer the following questions about your experience in the captcha task.', alternateRows: true, isAllRowRequired: debug ? false : true, + rowOrder: 'random', rows: [ { - text: 'I believed that my partner was actually an AI agent or a bot.', - value: 'SuspicionPartner', + text: `I found the captcha task difficult.`, + value: 'Difficulty', }, { - text: `There's no question here. Select 'Disagree' to show that you're paying attention.`, - value: 'AttentionCheck', + text: `I think I solved all the captchas correctly.`, + value: 'Accuracy', }, { - text: 'I believed that my partner was another, human, participant.', - value: 'ConfidencePartner', + text: `I think I solved captchas faster than most other participants would have.`, + value: 'Relative_performance', + }, + { + text: `I think I solved captchas slower than most other participants would have.`, + value: 'Relative_performance_slow', }, ], columns: [ @@ -286,6 +249,55 @@ const survey = { }, { name: 'page2', + elements: [ + { + type: 'matrix', + name: + probe_condition === 'die' + ? probe_text_die + : probe_text_difficulty, + alternateRows: true, + isAllRowRequired: debug ? false : true, + rowOrder: 'random', + rows: [ + probe_order === 'die_first' + ? die_probe_row + : difficulty_probe_row, + { + text: `There's no question here. Select 'Disagree' to show that you're paying attention.`, + value: 'AttentionCheck', + }, + probe_order === 'die_first' + ? difficulty_probe_row + : die_probe_row, + ], + columns: [ + { + value: 5, + text: 'Strongly agree', + }, + { + value: 4, + text: 'Agree', + }, + { + value: 3, + text: 'Neutral', + }, + { + value: 2, + text: 'Disagree', + }, + { + value: 1, + text: 'Strongly disagree', + }, + ], + }, + ], + }, + { + name: 'page3', elements: [ { type: 'radiogroup', @@ -314,60 +326,13 @@ const survey = { defaultValue: 18, }, ], - } + }, ], }, }; -const factors = { - selector: ['partner', 'participant'], - together_side: ['left', 'right'], - location: short_version ? [33, 50, 66] : [32, 33, 34, 49, 50, 51, 65, 66, 67], -}; - -const practice_factors = { - selector: ['partner', 'participant'], - together_side: ['left', 'right'], - location: [50], -}; - -const trials = jsPsych.randomization.factorial(factors, 1); - if (debug) { - console.log(factors); - console.log(trials); -} - -const practice_trials = jsPsych.randomization.factorial(practice_factors, 1); - -const object_moving_trials = { - timeline: [ - { - type: jsPsychObjectMoving, - selector: jsPsych.timelineVariable('selector'), - together_side: jsPsych.timelineVariable('together_side'), - location: jsPsych.timelineVariable('location'), - together_colour: together_colour, - }, - ], - timeline_variables: trials, -}; - -const object_moving_practice = { - timeline: [ - { - type: jsPsychObjectMoving, - selector: jsPsych.timelineVariable('selector'), - together_side: jsPsych.timelineVariable('together_side'), - location: jsPsych.timelineVariable('location'), - together_colour: together_colour, - }, - ], - timeline_variables: practice_trials, -}; - -if (debug) { - timeline.push(survey) + timeline.push(survey); timeline.push(debrief); } @@ -375,18 +340,7 @@ if (!debug) { timeline.push(pre_consent_info); timeline.push(consent_form); timeline.push(enter_fullscreen); - timeline.push(multi_user_instructions); - timeline.push(initial_lobby); timeline.push(instructions_1); - timeline.push(instructions_2); - timeline.push(instructions_3); - timeline.push(instructions_4); - timeline.push(pre_practice_instructions); - timeline.push(lobby_slow); - timeline.push(object_moving_practice); - timeline.push(pre_task_instructions); - timeline.push(lobby_fast); - timeline.push(object_moving_trials); timeline.push(pre_survey_info); timeline.push(survey); timeline.push(debrief); diff --git a/scripts/colours.js b/scripts/colours.js deleted file mode 100644 index bb490e7..0000000 --- a/scripts/colours.js +++ /dev/null @@ -1,27 +0,0 @@ -export default function getColourMap(together_colour) { - const colourMap = new Map(); - // Some reduncancy here, but Tailwind wont recognise the classes otherwise - colourMap.set('go', 'text-lime-600'); - colourMap.set('warning', 'text-yellow-600'); - colourMap.set('self-username', 'text-sky-600'); - colourMap.set('success', 'text-green-600'); - colourMap.set('gobg', 'bg-lime-600'); - - colourMap.set('object-enabled', 'bg-gray-600'); - colourMap.set('object-disabled', 'bg-gray-400'); - - if (together_colour === 'blue') { - colourMap.set('alone', 'text-rose-400'); - colourMap.set('together', 'text-blue-400'); - - colourMap.set('alonebg', 'bg-rose-400'); - colourMap.set('togetherbg', 'bg-blue-400'); - } else if (together_colour === 'red') { - colourMap.set('alone', 'text-blue-400'); - colourMap.set('together', 'text-rose-400'); - - colourMap.set('alonebg', 'bg-blue-400'); - colourMap.set('togetherbg', 'bg-rose-400'); - } - return colourMap; -} diff --git a/scripts/name-gen.js b/scripts/name-gen.js deleted file mode 100644 index 9fa92da..0000000 --- a/scripts/name-gen.js +++ /dev/null @@ -1,77 +0,0 @@ -function generateRandomUsername(usedAdjectives, usedNouns) { - const adjectives = [ - 'Round', - 'Square', - 'Tall', - 'Wide', - 'Small', - 'Large', - 'Flat', - 'Smooth', - 'Long', - 'Short', - 'Straight', - 'Curved', - 'Solid', - 'Hollow', - 'Dense', - 'Light', - 'Deep', - 'Broad', - 'Thin', - 'Thick', - ]; - const nouns = [ - 'Table', - 'Chair', - 'Lamp', - 'Spoon', - 'Book', - 'Door', - 'Window', - 'Pencil', - 'Paper', - 'Bowl', - 'Plate', - 'Cup', - 'Box', - 'Shelf', - 'Frame', - 'Desk', - 'Mirror', - 'Basket', - 'Button', - 'Bottle', - ]; - - let randomAdjective; - do { - randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)]; - } while (usedAdjectives.has(randomAdjective)); - - let randomNoun; - do { - randomNoun = nouns[Math.floor(Math.random() * nouns.length)]; - } while (usedNouns.has(randomNoun)); - - usedAdjectives.add(randomAdjective); - usedNouns.add(randomNoun); - - const randomInt = Math.floor(Math.random() * 100); - - return randomAdjective + randomNoun + randomInt; -} - -function generateUniqueUsernames(count) { - const usernames = new Set(); - const usedAdjectives = new Set(); - const usedNouns = new Set(); - - while (usernames.size < count) { - usernames.add(generateRandomUsername(usedAdjectives, usedNouns)); - } - - return Array.from(usernames); -} - -export default generateUniqueUsernames; diff --git a/scripts/plugin-lobby.js b/scripts/plugin-lobby.js deleted file mode 100644 index 574895b..0000000 --- a/scripts/plugin-lobby.js +++ /dev/null @@ -1,179 +0,0 @@ -import { ParameterType } from 'jspsych'; -import { html } from './text-stimuli'; -import getColourMap from './colours'; - -const info = { - name: 'lobby', - version: "1.0", - parameters: { - user_names: { - type: ParameterType.STRING, - pretty_name: 'User names', - default: [], - array: true, - }, - start_text: { - type: ParameterType.STRING, - pretty_name: 'Start text', - }, - end_text: { - type: ParameterType.STRING, - pretty_name: 'End text', - }, - start_number: { - type: ParameterType.INT, - pretty_name: 'Start number', - default: null, - }, - end_number: { - type: ParameterType.INT, - pretty_name: 'End number', - default: 3, - }, - join_interval: { - type: ParameterType.INT, - pretty_name: 'Join interval', - default: 5000, - }, - user_object: { - type: ParameterType.OBJECT, - pretty_name: 'User object', - default: {}, - }, - show_avatars: { - type: ParameterType.BOOL, - pretty_name: 'Show avatar', - default: false, - }, - data: { - type: ParameterType.OBJECT, - pretty_name: 'Data', - default: {}, - }, - }, - // prettier-ignore - citations: '__CITATIONS__' -}; - -class jsPsychLobby { - constructor(jsPsych) { - this.jsPsych = jsPsych; - } - static { - this.info = info; - } - - trial(display_element, trial) { - let current_participants; - if (!trial.start_number) { - current_participants = Math.floor(Math.random() * trial.end_number) + 1; - } else { - current_participants = trial.start_number; - } - const colourMap = getColourMap(' '); - - display_element.innerHTML = html`
-
-
-
`; - - const search_text_div = document.getElementById('search-text'); - const participants_list_div = document.getElementById('participants-list'); - const refresh_warning_div = document.getElementById('refresh-warning'); - const loading_animation_div = document.getElementById('loading-animation'); - - search_text_div.innerHTML = - '

' + - trial.start_text + - ' (' + - current_participants + - '/' + - trial.end_number + - ') ' + - '

'; - - refresh_warning_div.innerHTML = - `

Please do not refresh or close this page unless you are not connected to your partner within 5 minutes

`; - - const current_participants_span = document.getElementById('current-participants'); - - let participants_list = trial.user_names.slice(1, current_participants); - - let ended = false; - - const avatar_svg_template = colour => html` - - - - `; - - const createParticipantsHtml = () => { - let html = ''; - for (let i = 0; i < participants_list.length; i++) { -/* if (trial.show_avatars) { - html += `
${avatar_svg_template( - trial.user_object[participants_list[i]] - )}
`; - } */ - if (participants_list[i] === trial.user_names[0]) { - html += `

` + participants_list[i] + ` (you)

`; - } else { - html += `

` + participants_list[i] + `

`; - } - } - return (html); - }; - - - participants_list_div.innerHTML = createParticipantsHtml(); - - setTimeout(() => { - participants_list.push(trial.user_names[0]); - participants_list_div.innerHTML = createParticipantsHtml(); - }, 100); - - const updateParticipants = () => { - if (current_participants >= trial.end_number && !ended) { - ended = true; - clearInterval(participants_interval); - setTimeout(this.foundParticipants, 1500); - } else { - participants_list.push(trial.user_names[current_participants]); - participants_list_div.innerHTML = createParticipantsHtml(); - current_participants++; - if (current_participants <= trial.end_number && !ended) { - current_participants_span.innerHTML = current_participants; - } - } - }; - - this.foundParticipants = () => { - participants_list_div.innerHTML = html`${trial.end_text}`; - loading_animation_div.classList.remove('loading'); - setTimeout(() => { - this.jsPsych.finishTrial(); - }, 2000); - }; - - const participants_interval = setInterval( - updateParticipants, - trial.join_interval - ); - } -} - -export default jsPsychLobby; - - - \ No newline at end of file diff --git a/scripts/plugin-object-moving.js b/scripts/plugin-object-moving.js deleted file mode 100644 index 293fc3e..0000000 --- a/scripts/plugin-object-moving.js +++ /dev/null @@ -1,302 +0,0 @@ -import { ParameterType } from 'jspsych'; -import { html } from './text-stimuli'; -import getColourMap from './colours'; - -const info = { - name: 'object-moving', - version: "1.1", - parameters: { - selector: { - type: ParameterType.STRING, - pretty_name: 'Selector', - }, - together_side: { - type: ParameterType.STRING, - pretty_name: 'together side', - }, - location: { - type: ParameterType.INT, - pretty_name: 'Location', - }, - together_colour: { - type: ParameterType.STRING, - pretty_name: 'Together colour', - }, - }, - // prettier-ignore - citations: '__CITATIONS__' -}; - -class jsPsychObjectMoving { - constructor(jsPsych) { - this.jsPsych = jsPsych; - } - static { - this.info = info; - } - - trial(display_element, trial) { - - const colourMap = getColourMap(trial.together_colour); - - const left_goal = trial.together_side === 'left' ? 'together' : 'alone'; - const right_goal = trial.together_side === 'left' ? 'alone' : 'together'; - - const left_colour = trial.together_side === 'left' ? colourMap.get('togetherbg') : colourMap.get('alonebg'); - const right_colour = trial.together_side === 'left' ? colourMap.get('alonebg') : colourMap.get('togetherbg'); - - display_element.innerHTML = html` -
-
-
-
-
-
- `; - - const workspace = document.getElementById('workspace'); - const info_box = document.getElementById('info-box'); - const workspace_width = workspace.clientWidth; - const viewport_width = window.visualViewport.width; - const goal_offset = viewport_width * (1/12); - const box_width = viewport_width * (3/100); - const workspace_offset = workspace_width * trial.location/100; - - const offset_left = workspace_offset + goal_offset - box_width/2; - - const viewport_height = window.visualViewport.height; - const top_offset = viewport_height * .5; - const separation = box_width * 1.5; - - const objects = html` -
-
- `; - - workspace.innerHTML = objects; - - const object_partner = document.getElementById('object-partner'); - const object_participant = document.getElementById('object-participant'); - - object_partner.addEventListener('click', () => issue_alert('partner_click')); - object_participant.addEventListener('click', () => issue_alert('early_click_choice')); - - const partner_turn = html`Awaiting your partner's selection -
` - - let choice; - let go_clicked = false; - let partner_finished = false; - let participant_finished = false; - let partner_choice_made = false; - - const jsPsych = this.jsPsych; - - let start_time = 0; - let response_time = 0; - - if (trial.selector === 'participant') { - display_choices(); - - } else { - info_box.innerHTML = partner_turn; - - const partner_choice_delay = jsPsych.randomization.sampleExGaussian(2000, 250, 1/100, true); - - let random = Math.random(); - - - //These probabilities are based on Azaad and Sebanz (2025) - - if (trial.location > 48 && trial.location < 52) { - choice = random < 0.64 ? 'together' : 'alone'; - } else if (trial.location > 31 && trial.location < 35) { - choice = random < 0.58 ? 'together' : 'alone'; - } else if (trial.location > 64 && trial.location < 68) { - choice = random < 0.67 ? 'together' : 'alone'; - } - - setTimeout(() => { - info_box.innerHTML = ''; - clear_boxes(); - display_go(); - initiate_partner_action(); - }, partner_choice_delay); - } - - function display_choices(){ - info_box.innerHTML = html`
-
${left_goal.charAt(0).toUpperCase() + left_goal.slice(1)}
-
${right_goal.charAt(0).toUpperCase() + right_goal.slice(1)}
-
`; - - const left_goal_button = document.getElementById(`${left_goal}-button`); - const right_goal_button = document.getElementById(`${right_goal}-button`); - - start_time = Date.now(); - - left_goal_button.addEventListener('click', () => { - choice = left_goal; - handle_choice_made(left_goal_button,right_goal_button); - }); - - right_goal_button.addEventListener('click', () => { - choice = right_goal; - handle_choice_made(left_goal_button,right_goal_button); - }); - } - - function handle_choice_made(left_goal_button,right_goal_button){ - left_goal_button.removeEventListener('click', handle_choice_made); - right_goal_button.removeEventListener('click', handle_choice_made); - left_goal_button.remove(); - right_goal_button.remove(); - clear_boxes(); - display_go(); - response_time = Date.now() - start_time; - if (choice === 'together') { - initiate_partner_action(); - } - } - - function initiate_partner_action(){ - const go_delay = trial.selector === 'participant' ? 1400 : 1000 - const partner_go_delay = jsPsych.randomization.sampleExGaussian(go_delay, 500, 1/100, true); - const partner_teleport_delay = jsPsych.randomization.sampleExGaussian(1400, 300, 1/100, true); - - setTimeout(() => { - change_object_colour(object_partner); - partner_choice_made = true; - }, partner_go_delay); - - setTimeout(() => { - teleport_object(object_partner); - partner_finished = true; - check_finished(); - }, partner_teleport_delay + partner_go_delay); - } - - function clear_boxes() { - if (choice === 'together') { - return; - } - if (trial.selector === 'participant') { - object_partner.remove(); - } else { - object_participant.remove(); - } - } - - let go_button; - - function display_go() { - if (choice === 'alone' && trial.selector === 'partner') { - return; - } - info_box.innerHTML = html`
Go
`; - go_button = document.getElementById('go-button'); - object_participant.addEventListener('click', () => issue_alert('early_click_go')); - go_button.addEventListener('click', () => handle_go_click(go_button)); - } - - function handle_go_click() { - go_button.removeEventListener('click', handle_go_click); - go_button.removeEventListener('click', () => issue_alert('early_click_go')); - go_clicked = true; - go_button.remove(); - change_object_colour(object_participant); - object_participant.addEventListener('click', () => handle_teleport_click()); - - } - - function handle_teleport_click(){ - teleport_object(object_participant); - participant_finished = true; - check_finished(); - } - - - function change_object_colour(object){ - object.classList.remove(colourMap.get('object-disabled')); - object.classList.add(colourMap.get('object-enabled')); - } - - function teleport_object(object){ - let goal_side = 'left'; - if (choice === 'together' && trial.together_side === 'right') { - goal_side = 'right'; - } - if (choice === 'alone' && trial.together_side === 'left') { - goal_side = 'right'; - } - const mid_goal_offset = viewport_width * (1/24); - const new_left_offset = goal_side === 'left' ? mid_goal_offset - box_width/2 : viewport_width - mid_goal_offset - box_width/2; - object.style.transition = 'left 0.35s'; - object.style.left = `${new_left_offset}px`; - } - - function check_finished(){ - let finished = false; - if (choice === 'together') { - if (partner_finished && participant_finished) { - finished = true; - } - } - if (choice === 'alone') { - if (partner_finished || participant_finished) { - finished = true; - } - } - if (finished) { - object_partner.removeEventListener('click', () => issue_alert('partner_click')); - object_participant.removeEventListener('click', () => issue_alert('early_click_choice')); - - const save_data = { - choice: choice, - selector: trial.selector, - together_side: trial.together_side, - response_time: response_time, - } - - - setTimeout(() => { - jsPsych.finishTrial(save_data); - }, 500); - } - } - - async function show_alert(message) { - const dialog = document.createElement("dialog"); - document.body.appendChild(dialog); - dialog.className = "z-20 fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 p-4 bg-slate-100 text-red-700 rounded-lg shadow-lg"; - dialog.innerText = message; - dialog.show(); - setTimeout(function () { - dialog.close(); - }, 2000); - } - - function issue_alert(issue){ - if (issue === 'partner_click'){ - show_alert(`That is your partner's object. Please click the lower object.`) - } - if (issue === 'early_click_go' && !go_clicked){ - show_alert(`You need to click 'Go' before clicking your object.`) - } - if (issue === 'early_click_choice'){ - if (!partner_choice_made && trial.selector === 'partner'){ - show_alert(`Please wait for your partner to make a choice.`) - } - if (!choice && trial.selector === 'participant'){ - show_alert(`Please make a choice using the buttons below before clicking your object.`) - } - } - } - - } -} - -export default jsPsychObjectMoving; - - - \ No newline at end of file diff --git a/scripts/text-stimuli.js b/scripts/text-stimuli.js index 64d50b0..f8ef0e4 100644 --- a/scripts/text-stimuli.js +++ b/scripts/text-stimuli.js @@ -1,20 +1,3 @@ -import getColourMap from './colours.js'; - -// Define image URLs -const blueImages = { - instructions_1: '/images/blue/instructions_1.png', - instructions_2: '/images/blue/instructions_2.png', - instructions_3: '/images/blue/instructions_3.png', - instructions_4: '/images/blue/instructions_4.png', -}; - -const redImages = { - instructions_1: '/images/red/instructions_1.png', - instructions_2: '/images/red/instructions_2.png', - instructions_3: '/images/red/instructions_3.png', - instructions_4: '/images/red/instructions_4.png', -}; - import html from '../utils/html.js'; export const textStimuli = { @@ -25,14 +8,10 @@ export const textStimuli = { `, }; -function getStimulusMap(together_colour) { - const colourMap = getColourMap(together_colour); +function getStimulusMap() { const stimulusMap = new Map(); - // Select the appropriate image map based on the color - const imageMap = together_colour === 'blue' ? blueImages : redImages; - stimulusMap.set('pre_survey_info', html`

@@ -180,169 +159,14 @@ function getStimulusMap(together_colour) { ` ); - stimulusMap.set( - 'multi_user_instructions', - html` -

- In this experiment, you will connect and work with a partner. -

-

- It is - critical - that you only continue if you are able to complete the entire experiment - without interruption and with a stable internet connection. -

-

- Press - SPACE - once you are ready to be paired with a partner. -

- ` - ); stimulusMap.set( 'instructions_1', html` -

- In this study, you will work with your partner to complete a task - involving moving objects to one of two goals. -

-

- In each round, one of you will be assigned the role of the - Selector. - The Selector will choose to which goal the object(s) will be moved. -

- instructions_1 -

- Press - SPACE - to continue. -

+ TEST ` ); - stimulusMap.set( - 'instructions_2', - // prettier-ignore - html` -

- One of the goals (labelled - - Together) - will require both of you to move an object each. The other goal - (labelled - - Alone) - will - only - require the Selector to move an object. -

-

- When you are the Selector, you will see two buttons at the bottom of your - screen. The buttons colours correspond to the colour of the goal location - (e.g., red button for the red goal). -

- instructions_2 -

- Press - SPACE - to continue. -

- ` - ); - - stimulusMap.set( - 'instructions_3', - html` -

- If you are not the Selector, you will need to wait until your partner - makes a decision. -

-

- Once a decision is made, you will first need to click the - Go - button to make your object movable. Then, once you click an object, it - will teleport to the goal location. -

- instructions_3 -

- Press - SPACE - to continue. -

- ` - ); - - stimulusMap.set( - 'instructions_4', - html` -

- If the Selector chooses the - Alone - goal, one object will disappear, and the Selector will move the - remaining object. -

-

- Otherwise, if the Selector chooses - - Together - - , each of you will need to click an object - only click the object that - is lower on your screen. The other is for your partner. -

- instructions_4 -

- Press - SPACE - to continue. -

- ` - ); - - stimulusMap.set( - 'pre_practice_instructions', - html` -

- You will now complete a short practice task with your partner. -

-

- Press - SPACE - to continue. -

- ` - ); - - stimulusMap.set( - 'pre_task_instructions', - html` -

- Practice complete. You will now complete the main task. This will take - around five minutes. -

-

- Press - SPACE - to continue. -

- ` - ); stimulusMap.set( 'debrief',