/** * jspsych-serial-reaction-time * Josh de Leeuw * * plugin for running a serial reaction time task * * documentation: docs.jspsych.org * **/ jsPsych.plugins["serial-reaction-time"] = (function() { var plugin = {}; plugin.trial = function(display_element, trial) { trial.grid = trial.grid || [[1,1,1,1]]; trial.choices = trial.choices || [['3','5','7','9']]; trial.grid_square_size = trial.grid_square_size || 100; trial.target_color = trial.target_color || "#999"; trial.response_ends_trial = (typeof trial.response_ends_trial === 'undefined') ? true : trial.response_ends_trial; trial.pre_target_duration = (typeof trial.pre_target_duration === 'undefined') ? 0 : trial.pre_target_duration; trial.trial_duration = trial.trial_duration || -1; // if -1, then wait for response forever trial.show_response_feedback = (typeof trial.show_response_feedback === 'undefined') ? false : trial.show_response_feedback; trial.feedback_duration = (typeof trial.feedback_duration === 'undefined') ? 200 : trial.feedback_duration; trial.fade_duration = (typeof trial.fade_duration === 'undefined') ? -1 : trial.fade_duration; trial.prompt = (typeof trial.prompt === 'undefined') ? "" : trial.prompt; // create a flattened version of the choices array var flat_choices = jsPsych.utils.flatten(trial.choices); while(flat_choices.indexOf('') > -1){ flat_choices.splice(flat_choices.indexOf(''),1); } // display stimulus var stimulus = this.stimulus(trial.grid, trial.grid_square_size); display_element.innerHTML = stimulus; if(trial.pre_target_duration <= 0){ showTarget(); } else { jsPsych.pluginAPI.setTimeout(function(){ showTarget(); }, trial.pre_target_duration); } //show prompt if there is one if (trial.prompt !== "") { display_element.innerHTML += trial.prompt; } var keyboardListener = {}; var response = { rt: -1, key: false, correct: false } function showTarget(){ if(trial.fade_duration == -1){ display_element.querySelector('#jspsych-serial-reaction-time-stimulus-cell-'+trial.target[0]+'-'+trial.target[1]).style.backgroundColor = trial.target_color; } else { display_element.querySelector('#jspsych-serial-reaction-time-stimulus-cell-'+trial.target[0]+'-'+trial.target[1]).style.transition = "background-color "+trial.fade_duration; display_element.querySelector('#jspsych-serial-reaction-time-stimulus-cell-'+trial.target[0]+'-'+trial.target[1]).style.backgroundColor = trial.target_color; } keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({ callback_function: after_response, valid_responses: flat_choices, allow_held_key: false }); if(trial.trial_duration > -1){ jsPsych.pluginAPI.setTimeout(showFeedback, trial.trial_duration); } } function showFeedback() { if(response.rt == -1 || trial.show_response_feedback == false){ endTrial(); } else { var color = response.correct ? '#0f0' : '#f00'; display_element.querySelector('#jspsych-serial-reaction-time-stimulus-cell-'+response.responseLoc[0]+'-'+response.responseLoc[1]).style.transition = ""; display_element.querySelector('#jspsych-serial-reaction-time-stimulus-cell-'+response.responseLoc[0]+'-'+response.responseLoc[1]).style.backgroundColor = color; jsPsych.pluginAPI.setTimeout(endTrial, trial.feedback_duration); } } function endTrial() { // kill any remaining setTimeout handlers jsPsych.pluginAPI.clearAllTimeouts(); // kill keyboard listeners if (typeof keyboardListener !== 'undefined') { jsPsych.pluginAPI.cancelKeyboardResponse(keyboardListener); } // gather the data to store for the trial var trial_data = { "rt": response.rt, "key_press": response.key, "correct": response.correct, "grid": JSON.stringify(trial.grid), "target": JSON.stringify(trial.target) }; // clear the display display_element.innerHTML = ''; // move on to the next trial jsPsych.finishTrial(trial_data); }; // function to handle responses by the subject function after_response(info) { // only record first response response = response.rt == -1 ? info : response; // check if the response is correct var responseLoc = []; for(var i=0; i"; for(var i=0; i