From 9c6e5f292cf000838fe592d47da11055fc91a15c Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 1 Jul 2018 20:29:31 +0100 Subject: [PATCH 001/570] min RT feature --- examples/demo-simple-rt-task.html | 1 + jspsych.js | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/demo-simple-rt-task.html b/examples/demo-simple-rt-task.html index 62a9d7ed7e..565fb80746 100644 --- a/examples/demo-simple-rt-task.html +++ b/examples/demo-simple-rt-task.html @@ -95,6 +95,7 @@ /* start the experiment */ jsPsych.init({ + minimum_valid_rt: 2000, timeline: timeline, on_finish: function() { jsPsych.data.displayData(); diff --git a/jspsych.js b/jspsych.js index 47bd96a9fa..80c239e952 100755 --- a/jspsych.js +++ b/jspsych.js @@ -96,7 +96,8 @@ window.jsPsych = (function() { 'show_preload_progress_bar': true, 'max_load_time': 60000, 'max_preload_attempts': 10, - 'default_iti': 0 + 'default_iti': 0, + 'minimum_valid_rt': 0, }; // override default options if user specifies an option @@ -1872,12 +1873,13 @@ jsPsych.pluginAPI = (function() { module.getKeyboardResponse = function(parameters) { //parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key? - parameters.rt_method = (typeof parameters.rt_method === 'undefined') ? 'date' : parameters.rt_method; if (parameters.rt_method != 'date' && parameters.rt_method != 'performance' && parameters.rt_method != 'audio') { console.log('Invalid RT method specified in getKeyboardResponse. Defaulting to "date" method.'); parameters.rt_method = 'date'; } +console.log(12222, parameters.minimum_valid_rt,22) + parameters.minimum_valid_rt = (typeof parameters.minimum_valid_rt === 'undefined') ? 0 : parameters.minimum_valid_rt; var start_time; if (parameters.rt_method == 'date') { @@ -1901,6 +1903,13 @@ jsPsych.pluginAPI = (function() { key_time = parameters.audio_context.currentTime } + var rt = key_time - start_time +console.log(rt, parameters.minimum_valid_rt, rt < parameters.minimum_valid_rt) + if(rt < parameters.minimum_valid_rt){ + + return + } + var valid_response = false; if (typeof parameters.valid_responses === 'undefined' || parameters.valid_responses == jsPsych.ALL_KEYS) { valid_response = true; @@ -1934,7 +1943,7 @@ jsPsych.pluginAPI = (function() { parameters.callback_function({ key: e.keyCode, - rt: key_time - start_time + rt: rt, }); if (keyboard_listeners.includes(listener_id)) { From cb1071df43cef01882bfd932e7d1eb8b8d530aec Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 2 Jul 2018 14:02:12 +0100 Subject: [PATCH 002/570] min RT feature, working --- examples/demo-simple-rt-task.html | 1 - jspsych.js | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/demo-simple-rt-task.html b/examples/demo-simple-rt-task.html index 565fb80746..62a9d7ed7e 100644 --- a/examples/demo-simple-rt-task.html +++ b/examples/demo-simple-rt-task.html @@ -95,7 +95,6 @@ /* start the experiment */ jsPsych.init({ - minimum_valid_rt: 2000, timeline: timeline, on_finish: function() { jsPsych.data.displayData(); diff --git a/jspsych.js b/jspsych.js index 80c239e952..14b0ad7343 100755 --- a/jspsych.js +++ b/jspsych.js @@ -1872,14 +1872,15 @@ jsPsych.pluginAPI = (function() { } module.getKeyboardResponse = function(parameters) { - //parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key? + //parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key, minimum_valid_rt? parameters.rt_method = (typeof parameters.rt_method === 'undefined') ? 'date' : parameters.rt_method; if (parameters.rt_method != 'date' && parameters.rt_method != 'performance' && parameters.rt_method != 'audio') { console.log('Invalid RT method specified in getKeyboardResponse. Defaulting to "date" method.'); parameters.rt_method = 'date'; } -console.log(12222, parameters.minimum_valid_rt,22) - parameters.minimum_valid_rt = (typeof parameters.minimum_valid_rt === 'undefined') ? 0 : parameters.minimum_valid_rt; + + var minimum_valid_rt = jsPsych.initSettings().minimum_valid_rt + parameters.minimum_valid_rt = (typeof minimum_valid_rt === 'undefined') ? 0 : minimum_valid_rt; var start_time; if (parameters.rt_method == 'date') { @@ -1904,9 +1905,8 @@ console.log(12222, parameters.minimum_valid_rt,22) } var rt = key_time - start_time -console.log(rt, parameters.minimum_valid_rt, rt < parameters.minimum_valid_rt) - if(rt < parameters.minimum_valid_rt){ + if(rt <= parameters.minimum_valid_rt){ return } From 6409d2362027d022681d2e6aaabe7e76aad786b5 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 2 Jul 2018 14:35:49 +0100 Subject: [PATCH 003/570] min RT feature, working --- jspsych.js | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/jspsych.js b/jspsych.js index 14b0ad7343..3bf19c9664 100755 --- a/jspsych.js +++ b/jspsych.js @@ -1874,20 +1874,17 @@ jsPsych.pluginAPI = (function() { module.getKeyboardResponse = function(parameters) { //parameters are: callback_function, valid_responses, rt_method, persist, audio_context, audio_context_start_time, allow_held_key, minimum_valid_rt? parameters.rt_method = (typeof parameters.rt_method === 'undefined') ? 'date' : parameters.rt_method; - if (parameters.rt_method != 'date' && parameters.rt_method != 'performance' && parameters.rt_method != 'audio') { + if (parameters.rt_method !== 'date' && parameters.rt_method !== 'performance' && parameters.rt_method !== 'audio') { console.log('Invalid RT method specified in getKeyboardResponse. Defaulting to "date" method.'); parameters.rt_method = 'date'; } - var minimum_valid_rt = jsPsych.initSettings().minimum_valid_rt - parameters.minimum_valid_rt = (typeof minimum_valid_rt === 'undefined') ? 0 : minimum_valid_rt; - var start_time; - if (parameters.rt_method == 'date') { + if (parameters.rt_method === 'date') { start_time = (new Date()).getTime(); - } else if (parameters.rt_method == 'performance') { + } else if (parameters.rt_method === 'performance') { start_time = performance.now(); - } else if (parameters.rt_method == 'audio') { + } else if (parameters.rt_method === 'audio') { start_time = parameters.audio_context_start_time; } @@ -1896,36 +1893,41 @@ jsPsych.pluginAPI = (function() { var listener_function = function(e) { var key_time; - if (parameters.rt_method == 'date') { + if (parameters.rt_method === 'date') { key_time = (new Date()).getTime(); - } else if (parameters.rt_method == 'performance') { + } else if (parameters.rt_method === 'performance') { key_time = performance.now(); - } else if (parameters.rt_method == 'audio') { + } else if (parameters.rt_method === 'audio') { key_time = parameters.audio_context.currentTime } + var rt = key_time - start_time - var rt = key_time - start_time + // overiding via parameters for testing purposes. + var minimum_valid_rt = parameters.minimum_valid_rt + if(!minimum_valid_rt){ + minimum_valid_rt = jsPsych.initSettings().minimum_valid_rt || 0; + } - if(rt <= parameters.minimum_valid_rt){ + if(rt <= minimum_valid_rt){ return } var valid_response = false; - if (typeof parameters.valid_responses === 'undefined' || parameters.valid_responses == jsPsych.ALL_KEYS) { + if (typeof parameters.valid_responses === 'undefined' || parameters.valid_responses === jsPsych.ALL_KEYS) { valid_response = true; } else { - if(parameters.valid_responses != jsPsych.NO_KEYS){ + if(parameters.valid_responses !== jsPsych.NO_KEYS){ for (var i = 0; i < parameters.valid_responses.length; i++) { - if (typeof parameters.valid_responses[i] == 'string') { + if (typeof parameters.valid_responses[i] === 'string') { var kc = jsPsych.pluginAPI.convertKeyCharacterToKeyCode(parameters.valid_responses[i]); if (typeof kc !== 'undefined') { - if (e.keyCode == kc) { + if (e.keyCode === kc) { valid_response = true; } } else { throw new Error('Invalid key string specified for getKeyboardResponse'); } - } else if (e.keyCode == parameters.valid_responses[i]) { + } else if (e.keyCode === parameters.valid_responses[i]) { valid_response = true; } } @@ -1933,8 +1935,8 @@ jsPsych.pluginAPI = (function() { } // check if key was already held down - if (((typeof parameters.allow_held_key == 'undefined') || !parameters.allow_held_key) && valid_response) { - if (typeof held_keys[e.keyCode] !== 'undefined' && held_keys[e.keyCode] == true) { + if (((typeof parameters.allow_held_key === 'undefined') || !parameters.allow_held_key) && valid_response) { + if (typeof held_keys[e.keyCode] !== 'undefined' && held_keys[e.keyCode] === true) { valid_response = false; } } From 619117391c6f1b0df1312b89a20c3dd2d4c29f91 Mon Sep 17 00:00:00 2001 From: alisdt Date: Wed, 5 Feb 2020 10:56:31 +0000 Subject: [PATCH 004/570] Input to submitToTurk must be non-empty --- docs/core_library/jspsych-turk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core_library/jspsych-turk.md b/docs/core_library/jspsych-turk.md index a4bb9f60b3..cbf3a637de 100644 --- a/docs/core_library/jspsych-turk.md +++ b/docs/core_library/jspsych-turk.md @@ -13,7 +13,7 @@ jsPsych.turk.submitToTurk(data) Parameter | Type | Description ----------|------|------------ -data | object | The `data` parameter is an object of `key: value` pairs. Any pairs in the `data` parameter will be saved by Mechanical Turk, and can be downloaded in a CSV file through the Mechanical Turk interface. +data | object | The `data` parameter is an object of `key: value` pairs. Any pairs in the `data` parameter will be saved by Mechanical Turk, and can be downloaded in a CSV file through the Mechanical Turk interface. **Important**: the `data` parameter must contain at least one `key: value` pair, even just a dummy value, or the HIT will not be submitted correctly. ### Return value From 4ddcaba30e73b1735363cc96255cb82b7bc733f4 Mon Sep 17 00:00:00 2001 From: Alexander Robertson Date: Wed, 12 Feb 2020 14:07:38 +0000 Subject: [PATCH 005/570] Update jspsych-survey-text.md The parameter "value" is incorrectly referred to as "placeholder" in the documentation here. I have changed it to reflect what the parameter names actually are. --- docs/plugins/jspsych-survey-text.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/jspsych-survey-text.md b/docs/plugins/jspsych-survey-text.md index 05d947d77a..cd339edc25 100644 --- a/docs/plugins/jspsych-survey-text.md +++ b/docs/plugins/jspsych-survey-text.md @@ -8,7 +8,7 @@ Parameters with a default value of *undefined* must be specified. Other paramete Parameter | Type | Default Value | Description ----------|------|---------------|------------ -questions | array | *undefined* | An array of objects, each object represents a question that appears on the screen. Each object contains a prompt, value, required, rows, and columns parameter that will be applied to the question. See examples below for further clarification. `prompt`: Type string, default value of *undefined*. The string is the prompt for the subject to respond to. Each question gets its own response field. `placeholder`: Type string, default value of `""`. The string will create placeholder text in the text field. `required`: Boolean; if `true` then the user must enter a response to submit. `rows`: Type integer, default value of 1. The number of rows for the response text box. `columns`: Type integer, default value of 40. The number of columns for the response text box. `name`: Name of the question. Used for storing data. If left undefined then default names (`Q0`, `Q1`, `...`) will be used for the questions. +questions | array | *undefined* | An array of objects, each object represents a question that appears on the screen. Each object contains a prompt, value, required, rows, and columns parameter that will be applied to the question. See examples below for further clarification. `prompt`: Type string, default value of *undefined*. The string is the prompt for the subject to respond to. Each question gets its own response field. `value`: Type string, default value of `""`. The string will create placeholder text in the text field. `required`: Boolean; if `true` then the user must enter a response to submit. `rows`: Type integer, default value of 1. The number of rows for the response text box. `columns`: Type integer, default value of 40. The number of columns for the response text box. `name`: Name of the question. Used for storing data. If left undefined then default names (`Q0`, `Q1`, `...`) will be used for the questions. randomize_question_order | boolean | `false` | If true, the display order of `questions` is randomly determined at the start of the trial. In the data object, `Q0` will still refer to the first question in the array, regardless of where it was presented visually. preamble | string | empty string | HTML formatted string to display at the top of the page above all the questions. button_label | string | 'Continue' | The text that appears on the button to finish the trial. From eddfac4746875f825b6cffbdee0630be69ddce34 Mon Sep 17 00:00:00 2001 From: Rui Han <31236090+hrcn@users.noreply.github.com> Date: Mon, 24 Feb 2020 14:51:44 -0500 Subject: [PATCH 006/570] initialize variable i in for loops --- plugins/jspsych-cloze.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/jspsych-cloze.js b/plugins/jspsych-cloze.js index c954f4898d..9b075ed92d 100644 --- a/plugins/jspsych-cloze.js +++ b/plugins/jspsych-cloze.js @@ -48,7 +48,7 @@ jsPsych.plugins['cloze'] = (function () { var elements = trial.text.split('%'); var solutions = []; - for (i=0; i Date: Tue, 25 Feb 2020 16:54:28 -0500 Subject: [PATCH 007/570] return checkboxes to within label elements Checkbox elements were previously child elements of their labels. 55106fe increased backwards compatibility, but seems to have inadvertently made them siblings instead, breaking some css. Fix that. --- plugins/jspsych-survey-multi-choice.js | 3 ++- plugins/jspsych-survey-multi-select.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/jspsych-survey-multi-choice.js b/plugins/jspsych-survey-multi-choice.js index eb58c9f59b..aef77b1ca0 100644 --- a/plugins/jspsych-survey-multi-choice.js +++ b/plugins/jspsych-survey-multi-choice.js @@ -140,8 +140,9 @@ jsPsych.plugins['survey-multi-choice'] = (function() { // add radio button container html += '
'; - html += ''; + html += ''; html += '
'; } diff --git a/plugins/jspsych-survey-multi-select.js b/plugins/jspsych-survey-multi-select.js index 3408f355e3..8a3352f059 100644 --- a/plugins/jspsych-survey-multi-select.js +++ b/plugins/jspsych-survey-multi-select.js @@ -146,14 +146,14 @@ jsPsych.plugins['survey-multi-select'] = (function() { label.innerHTML = question.options[j]; label.setAttribute('for', input_id) - // create checkboxes + // create checkboxes var input = document.createElement('input'); input.setAttribute('type', "checkbox"); input.setAttribute('name', input_name); input.setAttribute('id', input_id); input.setAttribute('value', question.options[j]) form.appendChild(label) - form.insertBefore(input, label) + label.insertBefore(input, label.firstChild) } } // add submit button From f9fd3fde4566ff4562f357f084baf14dac815303 Mon Sep 17 00:00:00 2001 From: akochari Date: Wed, 26 Feb 2020 20:55:17 +0100 Subject: [PATCH 008/570] Update jspsych-same-different-html.md updated the trial type name to the correct one --- docs/plugins/jspsych-same-different-html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/jspsych-same-different-html.md b/docs/plugins/jspsych-same-different-html.md index ccfe309f09..7ad1b9ef64 100644 --- a/docs/plugins/jspsych-same-different-html.md +++ b/docs/plugins/jspsych-same-different-html.md @@ -43,7 +43,7 @@ key_press_stim1 | numeric | Indicates which key the subject pressed to continue. ```javascript var trial = { - type: 'same-different', + type: 'same-different-html', stimuli: ['

Climbing

', '

Walking

'], prompt: "

Press S if the texts imply the same amount of physical exertion. Press D if the texts imply different amount of physical exertion.

", same_key: 'S', From 4057fc8d88bc1dfb897fee1539552f6d218e2b89 Mon Sep 17 00:00:00 2001 From: Vijay Marupudi Date: Thu, 9 Apr 2020 12:05:39 -0500 Subject: [PATCH 009/570] Fixed undefined type check with typo --- jspsych.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jspsych.js b/jspsych.js index 922251dad8..53c06fe5b7 100755 --- a/jspsych.js +++ b/jspsych.js @@ -309,7 +309,7 @@ window.jsPsych = (function() { core.addNodeToEndOfTimeline = function(new_timeline, preload_callback){ timeline.insert(new_timeline); - if(typeof preload_callback !== 'undefinded'){ + if(typeof preload_callback !== 'undefined'){ if(opts.auto_preload){ jsPsych.pluginAPI.autoPreload(timeline, preload_callback); } else { From 2358c10e7aa61079e554edb794042b914189999b Mon Sep 17 00:00:00 2001 From: kachergis Date: Mon, 20 Apr 2020 13:34:41 -0700 Subject: [PATCH 010/570] corrected trial type --- docs/plugins/jspsych-serial-reaction-time-mouse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/jspsych-serial-reaction-time-mouse.md b/docs/plugins/jspsych-serial-reaction-time-mouse.md index c79e5a42fb..bd67e02a3b 100644 --- a/docs/plugins/jspsych-serial-reaction-time-mouse.md +++ b/docs/plugins/jspsych-serial-reaction-time-mouse.md @@ -43,7 +43,7 @@ var trial = { #### 2x2 grid with extra space in the middle ```javascript var trial = { - type: 'serial-reaction-time', + type: 'serial-reaction-time-mouse', grid: [[1,0,1],[0,0,0],[1,0,1]], target: [0,2] } From 45f6840b6b58335314730ca053f53ee4331f5ce5 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 11:34:39 +0200 Subject: [PATCH 011/570] added original version of canvas keyboard response plugin --- plugins/jspsych-canvas-keyboard-response.js | 149 ++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 plugins/jspsych-canvas-keyboard-response.js diff --git a/plugins/jspsych-canvas-keyboard-response.js b/plugins/jspsych-canvas-keyboard-response.js new file mode 100644 index 0000000000..01281be0db --- /dev/null +++ b/plugins/jspsych-canvas-keyboard-response.js @@ -0,0 +1,149 @@ +/** + * jspsych-canvas-keyboard-response + * Chris Jungerius (modified from Josh de Leeuw) + * + * plugin for displaying a canvas stimulus and getting a keyboard response + * + * documentation: TODO + * + **/ + + +jsPsych.plugins["canvas-keyboard-response"] = (function () { + + var plugin = {}; + + plugin.info = { + name: 'canvas-keyboard-response', + description: '', + parameters: { + drawing: { + type: jsPsych.plugins.parameterType.FUNCTION, + pretty_name: 'Drawing', + default: function (c) { let ctx = c.getContext("2d"); ctx.font = "30px Arial"; ctx.textAlign = "center"; ctx.fillText("Canvas Element", c.width / 2, c.height / 2) }, + description: 'the drawing function to apply to the canvas, should take the canvas object as argument' + }, + choices: { + type: jsPsych.plugins.parameterType.KEYCODE, + array: true, + pretty_name: 'Choices', + default: jsPsych.ALL_KEYS, + description: 'The keys the subject is allowed to press to respond to the stimulus.' + }, + prompt: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Prompt', + default: null, + description: 'Any content here will be displayed below the stimulus.' + }, + stimulus_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Stimulus duration', + default: null, + description: 'How long to hide the stimulus.' + }, + trial_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Trial duration', + default: null, + description: 'How long to show trial before it ends.' + }, + response_ends_trial: { + type: jsPsych.plugins.parameterType.BOOL, + pretty_name: 'Response ends trial', + default: true, + description: 'If true, trial will end when subject makes a response.' + }, + + } + } + + plugin.trial = function (display_element, trial) { + + var new_html = '
' + '' + '
'; + // add prompt + if (trial.prompt !== null) { + new_html += trial.prompt; + } + + // draw + display_element.innerHTML = new_html; + let c = document.getElementById("myCanvas") + trial.drawing(c) + // store response + var response = { + rt: null, + key: null + }; + + // function to end trial when it is time + var end_trial = function () { + + // 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, + "stimulus": trial.drawing, + "key_press": response.key + }; + + // clear the display + display_element.innerHTML = ''; + + // move on to the next trial + jsPsych.finishTrial(trial_data); + }; + + // function to handle responses by the subject + var after_response = function (info) { + + // after a valid response, the stimulus will have the CSS class 'responded' + // which can be used to provide visual feedback that a response was recorded + display_element.querySelector('#jspsych-canvas-keyboard-response-stimulus').className += ' responded'; + + // only record the first response + if (response.key == null) { + response = info; + } + + if (trial.response_ends_trial) { + end_trial(); + } + }; + + // start the response listener + if (trial.choices != jsPsych.NO_KEYS) { + var keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({ + callback_function: after_response, + valid_responses: trial.choices, + rt_method: 'performance', + persist: false, + allow_held_key: false + }); + } + + // hide stimulus if stimulus_duration is set + if (trial.stimulus_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + display_element.querySelector('#jspsych-canvas-keyboard-response-stimulus').style.visibility = 'hidden'; + }, trial.stimulus_duration); + } + + // end trial if trial_duration is set + if (trial.trial_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + end_trial(); + }, trial.trial_duration); + } + + }; + + return plugin; +})(); From 9f864f36021d8543ca9df3e3a84ada4b78a4ba48 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 12:06:17 +0200 Subject: [PATCH 012/570] added skeleton documentation for canvas-keyboard-response --- .../jspsych-canvas-keyboard-response.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/plugins/jspsych-canvas-keyboard-response.md diff --git a/docs/plugins/jspsych-canvas-keyboard-response.md b/docs/plugins/jspsych-canvas-keyboard-response.md new file mode 100644 index 0000000000..e888578711 --- /dev/null +++ b/docs/plugins/jspsych-canvas-keyboard-response.md @@ -0,0 +1,19 @@ +# jspsych-canvas-keyboard-response + + +## Parameters + +Parameters with a default value of undefined must be specified. Other parameters can be left unspecified if the default value is acceptable. + +Parameter | Type | Default Value | Description +----------|------|---------------|------------ + +## Data Generated + +In addition to the [default data collected by all plugins](overview#datacollectedbyplugins), this plugin collects the following data for each trial. + +Name | Type | Value +-----|------|------ + + +## Examples \ No newline at end of file From d1437ea9dd6db8862726b2942c5feb53d0a3c416 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 13:21:25 +0200 Subject: [PATCH 013/570] cleaned up canvas-keyboard-response and added option to resize canvas --- plugins/jspsych-canvas-keyboard-response.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/jspsych-canvas-keyboard-response.js b/plugins/jspsych-canvas-keyboard-response.js index 01281be0db..e9dacbc1df 100644 --- a/plugins/jspsych-canvas-keyboard-response.js +++ b/plugins/jspsych-canvas-keyboard-response.js @@ -19,7 +19,7 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { parameters: { drawing: { type: jsPsych.plugins.parameterType.FUNCTION, - pretty_name: 'Drawing', + pretty_name: 'Stimulus', default: function (c) { let ctx = c.getContext("2d"); ctx.font = "30px Arial"; ctx.textAlign = "center"; ctx.fillText("Canvas Element", c.width / 2, c.height / 2) }, description: 'the drawing function to apply to the canvas, should take the canvas object as argument' }, @@ -54,13 +54,19 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { default: true, description: 'If true, trial will end when subject makes a response.' }, + canvas_size: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Canvas size', + default: [500, 500], + description: 'The height and width of the canvas element' + } } } plugin.trial = function (display_element, trial) { - var new_html = '
' + '' + '
'; + var new_html = '
' + '' + '
'; // add prompt if (trial.prompt !== null) { new_html += trial.prompt; @@ -69,7 +75,7 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { // draw display_element.innerHTML = new_html; let c = document.getElementById("myCanvas") - trial.drawing(c) + trial.stimulus(c) // store response var response = { rt: null, From 04d71b715dc36e2e9f908e4b6c3206ecf8e66725 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 13:45:51 +0200 Subject: [PATCH 014/570] added canvas-slider-response; changed canvas ID to a more fitting name --- plugins/jspsych-canvas-keyboard-response.js | 8 +- plugins/jspsych-canvas-slider-response.js | 204 ++++++++++++++++++++ 2 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 plugins/jspsych-canvas-slider-response.js diff --git a/plugins/jspsych-canvas-keyboard-response.js b/plugins/jspsych-canvas-keyboard-response.js index e9dacbc1df..388c73821b 100644 --- a/plugins/jspsych-canvas-keyboard-response.js +++ b/plugins/jspsych-canvas-keyboard-response.js @@ -17,10 +17,10 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { name: 'canvas-keyboard-response', description: '', parameters: { - drawing: { + stimulus: { type: jsPsych.plugins.parameterType.FUNCTION, pretty_name: 'Stimulus', - default: function (c) { let ctx = c.getContext("2d"); ctx.font = "30px Arial"; ctx.textAlign = "center"; ctx.fillText("Canvas Element", c.width / 2, c.height / 2) }, + default: undefined, description: 'the drawing function to apply to the canvas, should take the canvas object as argument' }, choices: { @@ -66,7 +66,7 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { plugin.trial = function (display_element, trial) { - var new_html = '
' + '' + '
'; + var new_html = '
' + '' + '
'; // add prompt if (trial.prompt !== null) { new_html += trial.prompt; @@ -74,7 +74,7 @@ jsPsych.plugins["canvas-keyboard-response"] = (function () { // draw display_element.innerHTML = new_html; - let c = document.getElementById("myCanvas") + let c = document.getElementById("stimulus-canvas") trial.stimulus(c) // store response var response = { diff --git a/plugins/jspsych-canvas-slider-response.js b/plugins/jspsych-canvas-slider-response.js new file mode 100644 index 0000000000..351ff9aec1 --- /dev/null +++ b/plugins/jspsych-canvas-slider-response.js @@ -0,0 +1,204 @@ +/** + * jspsych-canvas-slider-response + * a jspsych plugin for free response survey questions + * + * Chris jungerius (modified from Josh de Leeuw) + * + * documentation: docs.jspsych.org + * + */ + + +jsPsych.plugins['canvas-slider-response'] = (function () { + + var plugin = {}; + + plugin.info = { + name: 'canvas-slider-response', + description: '', + parameters: { + stimulus: { + type: jsPsych.plugins.parameterType.HTML_STRING, + pretty_name: 'Stimulus', + default: undefined, + description: 'the drawing function to apply to the canvas, should take the canvas object as argument' + }, + min: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Min slider', + default: 0, + description: 'Sets the minimum value of the slider.' + }, + max: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Max slider', + default: 100, + description: 'Sets the maximum value of the slider', + }, + start: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Slider starting value', + default: 50, + description: 'Sets the starting value of the slider', + }, + step: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Step', + default: 1, + description: 'Sets the step of the slider' + }, + labels: { + type: jsPsych.plugins.parameterType.HTML_STRING, + pretty_name: 'Labels', + default: [], + array: true, + description: 'Labels of the slider.', + }, + slider_width: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Slider width', + default: null, + description: 'Width of the slider in pixels.' + }, + button_label: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Button label', + default: 'Continue', + array: false, + description: 'Label of the button to advance.' + }, + require_movement: { + type: jsPsych.plugins.parameterType.BOOL, + pretty_name: 'Require movement', + default: false, + description: 'If true, the participant will have to move the slider before continuing.' + }, + prompt: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Prompt', + default: null, + description: 'Any content here will be displayed below the slider.' + }, + stimulus_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Stimulus duration', + default: null, + description: 'How long to hide the stimulus.' + }, + trial_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Trial duration', + default: null, + description: 'How long to show the trial.' + }, + response_ends_trial: { + type: jsPsych.plugins.parameterType.BOOL, + pretty_name: 'Response ends trial', + default: true, + description: 'If true, trial will end when user makes a response.' + }, + canvas_size: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Canvas size', + default: [500, 500], + description: 'The height and width of the canvas element' + } + + } + } + + plugin.trial = function (display_element, trial) { + + var html = '
'; + html += '
' + '' + '
'; + html += '
'; + html += ''; + html += '
' + for (var j = 0; j < trial.labels.length; j++) { + var width = 100 / (trial.labels.length - 1); + var left_offset = (j * (100 / (trial.labels.length - 1))) - (width / 2); + html += '
'; + html += '' + trial.labels[j] + ''; + html += '
' + } + html += '
'; + html += '
'; + html += '
'; + + if (trial.prompt !== null) { + html += trial.prompt; + } + + // add submit button + html += ''; + + display_element.innerHTML = html; + + // draw + let c = document.getElementById("stimulus-canvas") + trial.stimulus(c) + + var response = { + rt: null, + response: null + }; + + if (trial.require_movement) { + display_element.querySelector('#jspsych-canvas-slider-response-response').addEventListener('change', function () { + display_element.querySelector('#jspsych-canvas-slider-response-next').disabled = false; + }) + } + + display_element.querySelector('#jspsych-canvas-slider-response-next').addEventListener('click', function () { + // measure response time + var endTime = performance.now(); + response.rt = endTime - startTime; + response.response = display_element.querySelector('#jspsych-canvas-slider-response-response').value; + + if (trial.response_ends_trial) { + end_trial(); + } else { + display_element.querySelector('#jspsych-canvas-slider-response-next').disabled = true; + } + + }); + + function end_trial() { + + jsPsych.pluginAPI.clearAllTimeouts(); + + // save data + var trialdata = { + "rt": response.rt, + "response": response.response, + "stimulus": trial.stimulus + }; + + display_element.innerHTML = ''; + + // next trial + jsPsych.finishTrial(trialdata); + } + + if (trial.stimulus_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + display_element.querySelector('#jspsych-canvas-slider-response-stimulus').style.visibility = 'hidden'; + }, trial.stimulus_duration); + } + + // end trial if trial_duration is set + if (trial.trial_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + end_trial(); + }, trial.trial_duration); + } + + var startTime = performance.now(); + }; + + return plugin; +})(); From 3c284f35d5f84721be2e6cfd66fa580417b504d1 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 13:56:20 +0200 Subject: [PATCH 015/570] added canvas-button-response --- plugins/jspsych-canvas-button-response.js | 199 ++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 plugins/jspsych-canvas-button-response.js diff --git a/plugins/jspsych-canvas-button-response.js b/plugins/jspsych-canvas-button-response.js new file mode 100644 index 0000000000..df6f612eea --- /dev/null +++ b/plugins/jspsych-canvas-button-response.js @@ -0,0 +1,199 @@ +/** + * jspsych-canvas-button-response + * Chris Jungerius (modified from Josh de Leeuw) + * + * plugin for displaying a stimulus and getting a keyboard response + * + * documentation: docs.jspsych.org + * + **/ + +jsPsych.plugins["canvas-button-response"] = (function () { + + var plugin = {}; + + plugin.info = { + name: 'canvas-button-response', + description: '', + parameters: { + stimulus: { + type: jsPsych.plugins.parameterType.FUNCTION, + pretty_name: 'Stimulus', + default: undefined, + description: 'the drawing function to apply to the canvas, should take the canvas object as argument' + }, + choices: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Choices', + default: undefined, + array: true, + description: 'The labels for the buttons.' + }, + button_html: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Button HTML', + default: '', + array: true, + description: 'The html of the button. Can create own style.' + }, + prompt: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Prompt', + default: null, + description: 'Any content here will be displayed under the button.' + }, + stimulus_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Stimulus duration', + default: null, + description: 'How long to hide the stimulus.' + }, + trial_duration: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Trial duration', + default: null, + description: 'How long to show the trial.' + }, + margin_vertical: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Margin vertical', + default: '0px', + description: 'The vertical margin of the button.' + }, + margin_horizontal: { + type: jsPsych.plugins.parameterType.STRING, + pretty_name: 'Margin horizontal', + default: '8px', + description: 'The horizontal margin of the button.' + }, + response_ends_trial: { + type: jsPsych.plugins.parameterType.BOOL, + pretty_name: 'Response ends trial', + default: true, + description: 'If true, then trial will end when user responds.' + }, + canvas_size: { + type: jsPsych.plugins.parameterType.INT, + pretty_name: 'Canvas size', + default: [500, 500], + description: 'The height and width of the canvas element' + } + + } + } + + plugin.trial = function (display_element, trial) { + + // create canvas + var html = '
' + '' + '
'; + + //display buttons + var buttons = []; + if (Array.isArray(trial.button_html)) { + if (trial.button_html.length == trial.choices.length) { + buttons = trial.button_html; + } else { + console.error('Error in canvas-button-response plugin. The length of the button_html array does not equal the length of the choices array'); + } + } else { + for (var i = 0; i < trial.choices.length; i++) { + buttons.push(trial.button_html); + } + } + html += '
'; + for (var i = 0; i < trial.choices.length; i++) { + var str = buttons[i].replace(/%choice%/g, trial.choices[i]); + html += '
' + str + '
'; + } + html += '
'; + + //show prompt if there is one + if (trial.prompt !== null) { + html += trial.prompt; + } + display_element.innerHTML = html; + + //draw + let c = document.getElementById("stimulus-canvas") + trial.stimulus(c) + + // start time + var start_time = performance.now(); + + // add event listeners to buttons + for (var i = 0; i < trial.choices.length; i++) { + display_element.querySelector('#jspsych-canvas-button-response-button-' + i).addEventListener('click', function (e) { + var choice = e.currentTarget.getAttribute('data-choice'); // don't use dataset for jsdom compatibility + after_response(choice); + }); + } + + // store response + var response = { + rt: null, + button: null + }; + + // function to handle responses by the subject + function after_response(choice) { + + // measure rt + var end_time = performance.now(); + var rt = end_time - start_time; + response.button = choice; + response.rt = rt; + + // after a valid response, the stimulus will have the CSS class 'responded' + // which can be used to provide visual feedback that a response was recorded + display_element.querySelector('#jspsych-canvas-button-response-stimulus').className += ' responded'; + + // disable all the buttons after a response + var btns = document.querySelectorAll('.jspsych-canvas-button-response-button button'); + for (var i = 0; i < btns.length; i++) { + //btns[i].removeEventListener('click'); + btns[i].setAttribute('disabled', 'disabled'); + } + + if (trial.response_ends_trial) { + end_trial(); + } + }; + + // function to end trial when it is time + function end_trial() { + + // kill any remaining setTimeout handlers + jsPsych.pluginAPI.clearAllTimeouts(); + + // gather the data to store for the trial + var trial_data = { + "rt": response.rt, + "stimulus": trial.stimulus, + "button_pressed": response.button + }; + + // clear the display + display_element.innerHTML = ''; + + // move on to the next trial + jsPsych.finishTrial(trial_data); + }; + + // hide image if timing is set + if (trial.stimulus_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + display_element.querySelector('#jspsych-canvas-button-response-stimulus').style.visibility = 'hidden'; + }, trial.stimulus_duration); + } + + // end trial if time limit is set + if (trial.trial_duration !== null) { + jsPsych.pluginAPI.setTimeout(function () { + end_trial(); + }, trial.trial_duration); + } + + }; + + return plugin; +})(); From a996795831d875c869a16780ff1e293a537a2a30 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 14:41:19 +0200 Subject: [PATCH 016/570] created temp html file to test the three new plugin types, and fixed some bugs that emerged from first tests --- canvastest.html | 50 +++++++++++++++++++++++ plugins/jspsych-canvas-button-response.js | 2 +- plugins/jspsych-canvas-slider-response.js | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 canvastest.html diff --git a/canvastest.html b/canvastest.html new file mode 100644 index 0000000000..bcf16862ff --- /dev/null +++ b/canvastest.html @@ -0,0 +1,50 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/jspsych-canvas-button-response.js b/plugins/jspsych-canvas-button-response.js index df6f612eea..56ecb0cca2 100644 --- a/plugins/jspsych-canvas-button-response.js +++ b/plugins/jspsych-canvas-button-response.js @@ -103,7 +103,7 @@ jsPsych.plugins["canvas-button-response"] = (function () { html += '
'; for (var i = 0; i < trial.choices.length; i++) { var str = buttons[i].replace(/%choice%/g, trial.choices[i]); - html += '
' + str + '
'; + html += '
' + str + '
'; } html += '
'; diff --git a/plugins/jspsych-canvas-slider-response.js b/plugins/jspsych-canvas-slider-response.js index 351ff9aec1..3f9b16b256 100644 --- a/plugins/jspsych-canvas-slider-response.js +++ b/plugins/jspsych-canvas-slider-response.js @@ -18,7 +18,7 @@ jsPsych.plugins['canvas-slider-response'] = (function () { description: '', parameters: { stimulus: { - type: jsPsych.plugins.parameterType.HTML_STRING, + type: jsPsych.plugins.parameterType.FUNCTION, pretty_name: 'Stimulus', default: undefined, description: 'the drawing function to apply to the canvas, should take the canvas object as argument' From 24d391fb5164ef0c612e3359a6c349791e34369f Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 14:46:52 +0200 Subject: [PATCH 017/570] confirmed trials are outputting all data correctly --- canvastest.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/canvastest.html b/canvastest.html index bcf16862ff..5869fbc476 100644 --- a/canvastest.html +++ b/canvastest.html @@ -43,7 +43,8 @@ timeline.push(sliderTrial) jsPsych.init({ - timeline: timeline + timeline: timeline, + on_trial_finish: function(data){console.log(data)} }) From c813314f98073f28bb8feb35865aa0a2738ef99e Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 14:50:42 +0200 Subject: [PATCH 018/570] removed testing html --- canvastest.html | 51 ------------------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 canvastest.html diff --git a/canvastest.html b/canvastest.html deleted file mode 100644 index 5869fbc476..0000000000 --- a/canvastest.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - \ No newline at end of file From f17c0ddb6002a8bb9cf0456a966446073544e3b2 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 14:55:58 +0200 Subject: [PATCH 019/570] started button and slider response docs --- .../plugins/jspsych-canvas-button-response.md | 19 +++++++++++++++++++ .../plugins/jspsych-canvas-slider-response.md | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 docs/plugins/jspsych-canvas-button-response.md create mode 100644 docs/plugins/jspsych-canvas-slider-response.md diff --git a/docs/plugins/jspsych-canvas-button-response.md b/docs/plugins/jspsych-canvas-button-response.md new file mode 100644 index 0000000000..fda3abed8a --- /dev/null +++ b/docs/plugins/jspsych-canvas-button-response.md @@ -0,0 +1,19 @@ +# jspsych-canvas-button-response + + +## Parameters + +Parameters with a default value of undefined must be specified. Other parameters can be left unspecified if the default value is acceptable. + +Parameter | Type | Default Value | Description +----------|------|---------------|------------ + +## Data Generated + +In addition to the [default data collected by all plugins](overview#datacollectedbyplugins), this plugin collects the following data for each trial. + +Name | Type | Value +-----|------|------ + + +## Examples \ No newline at end of file diff --git a/docs/plugins/jspsych-canvas-slider-response.md b/docs/plugins/jspsych-canvas-slider-response.md new file mode 100644 index 0000000000..a350d2d3f6 --- /dev/null +++ b/docs/plugins/jspsych-canvas-slider-response.md @@ -0,0 +1,19 @@ +# jspsych-canvas-slider-response + + +## Parameters + +Parameters with a default value of undefined must be specified. Other parameters can be left unspecified if the default value is acceptable. + +Parameter | Type | Default Value | Description +----------|------|---------------|------------ + +## Data Generated + +In addition to the [default data collected by all plugins](overview#datacollectedbyplugins), this plugin collects the following data for each trial. + +Name | Type | Value +-----|------|------ + + +## Examples \ No newline at end of file From c66f74fec4a1f8f9201b1575a8af3f8a26f406d5 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 15:30:15 +0200 Subject: [PATCH 020/570] finished canvas-keyboard-response documentation --- .../jspsych-canvas-keyboard-response.md | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/docs/plugins/jspsych-canvas-keyboard-response.md b/docs/plugins/jspsych-canvas-keyboard-response.md index e888578711..464dc4d2a0 100644 --- a/docs/plugins/jspsych-canvas-keyboard-response.md +++ b/docs/plugins/jspsych-canvas-keyboard-response.md @@ -1,5 +1,6 @@ # jspsych-canvas-keyboard-response +This plugin can be used to draw an image on a JavaScript canvas element, which can be useful for displaying parametrically defined shapes, and records responses generated with the keyboard. The stimulus can be displayed until a response is given, or for a pre-determined amount of time. The trial can be ended automatically if the subject has failed to respond within a fixed length of time. ## Parameters @@ -7,6 +8,13 @@ Parameters with a default value of undefined must be specified. Other parameters Parameter | Type | Default Value | Description ----------|------|---------------|------------ +stimulus | function | *undefined* | The function to draw on the canvas. This function must take a canvas element as its only argument, e.g. `foo(c)`. Note that the function will still generally need to set the correct context itself, using a line like let `ctx = c.getContext("2d")`. +canvas_size | array | [500, 500] | The size of the canvas element in pixels. +choices | array of keycodes | `jsPsych.ALL_KEYS` | This array contains the keys that the subject is allowed to press in order to respond to the stimulus. Keys can be specified as their [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) or as characters (e.g., `'a'`, `'q'`). The default value of `jsPsych.ALL_KEYS` means that all keys will be accepted as valid responses. Specifying `jsPsych.NO_KEYS` will mean that no responses are allowed. +prompt | string | null | This string can contain HTML markup. Any content here will be displayed below the stimulus. The intention is that it can be used to provide a reminder about the action the subject is supposed to take (e.g., which key to press). +stimulus_duration | numeric | null | How long to display the stimulus in milliseconds. The visibility CSS property of the stimulus will be set to `hidden` after this time has elapsed. If this is null, then the stimulus will remain visible until the trial ends. +trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, then the trial will wait for a response indefinitely. +response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `timing_response` parameter). If false, then the trial will continue until the value for `trial_duration` is reached. You can use this parameter to force the subject to view a stimulus for a fixed amount of time, even if they respond before the time is complete. ## Data Generated @@ -14,6 +22,46 @@ In addition to the [default data collected by all plugins](overview#datacollecte Name | Type | Value -----|------|------ +key_press | numeric | Indicates which key the subject pressed. The value is the [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) corresponding to the subject's response. +rt | numeric | The response time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response. +stimulus | function | The function that was drawn. +## Examples -## Examples \ No newline at end of file +### Displaying a drawing until subject gives a response + +```javascript + +function drawRect(c){ + var ctx = c.getContext('2d'); + ctx.beginPath(); + ctx.rect(30, 30, 200, 50); + ctx.stroke(); +} + +var trial = { + type: 'canvas-keyboard-response', + stimulus: drawRect, + choices: ['e','i'], + prompt: '

is this a circle or a rectangle? press "e" for circle and "i" for rectangle

', +} +``` + +### Displaying a circle for 1 second, no response allowed + +```javascript + +function drawCirc(c){ + var ctx = c.getContext('2d'); + ctx.beginPath(); + ctx.arc(100, 75, 50, 0, 2 * Math.PI); + ctx.stroke(); +} + +var trial = { + type: 'canvas-keyboard-response', + stimulus: drawCirc, + choices: jsPsych.NO_KEYS, + trial_duration: 1000, +} +``` \ No newline at end of file From b31f5f5cd4093cdab36c0ee33693a4226fb951f8 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 16:34:43 +0200 Subject: [PATCH 021/570] finished canvas-button-response documentation --- .../plugins/jspsych-canvas-button-response.md | 40 +++++++++++++++++-- .../jspsych-canvas-keyboard-response.md | 2 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/plugins/jspsych-canvas-button-response.md b/docs/plugins/jspsych-canvas-button-response.md index fda3abed8a..b91803bd4b 100644 --- a/docs/plugins/jspsych-canvas-button-response.md +++ b/docs/plugins/jspsych-canvas-button-response.md @@ -1,5 +1,6 @@ # jspsych-canvas-button-response +This plugin can be used to draw a stimulus on a JavaScript canvas element, which can be useful for displaying parametrically defined shapes, and records responses generated by button click. The stimulus can be displayed until a response is given, or for a pre-determined amount of time. The trial can be ended automatically if the subject has failed to respond within a fixed length of time. The button itself can be customized using HTML formatting. ## Parameters @@ -7,13 +8,44 @@ Parameters with a default value of undefined must be specified. Other parameters Parameter | Type | Default Value | Description ----------|------|---------------|------------ - +stimulus | function | *undefined* | The function to draw on the canvas. This function must take a canvas element as its only argument, e.g. `foo(c)`. Note that the function will still generally need to set the correct context itself, using a line like let `ctx = c.getContext("2d")`. +canvas_size | array | [500, 500] | The size of the canvas element in pixels. +choices | array of strings | [] | Labels for the buttons. Each different string in the array will generate a different button. +button_html | HTML string | `''` | A template of HTML for generating the button elements. You can override this to create customized buttons of various kinds. The string `%choice%` will be changed to the corresponding element of the `choices` array. You may also specify an array of strings, if you need different HTML to render for each button. If you do specify an array, the `choices` array and this array must have the same length. The HTML from position 0 in the `button_html` array will be used to create the button for element 0 in the `choices` array, and so on. +prompt | string | null | This string can contain HTML markup. Any content here will be displayed below the stimulus. The intention is that it can be used to provide a reminder about the action the subject is supposed to take (e.g., which key to press). +trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, the trial will wait for a response indefinitely. +stimulus_duration | numeric | null | How long to display the stimulus in milliseconds. The visibility CSS property of the stimulus will be set to `hidden` after this time has elapsed. If this is null, then the stimulus will remain visible until the trial ends. +margin_vertical | string | '0px' | Vertical margin of the button(s). +margin_horizontal | string | '8px' | Horizontal margin of the button(s). +response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `trial_duration` parameter). If false, then the trial will continue until the value for `timing_response` is reached. You can use this parameter to force the subject to view a stimulus for a fixed amount of time, even if they respond before the time is complete. ## Data Generated In addition to the [default data collected by all plugins](overview#datacollectedbyplugins), this plugin collects the following data for each trial. Name | Type | Value -----|------|------ - - -## Examples \ No newline at end of file +rt | numeric | The response time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response. +button_pressed | numeric | Indicates which button the subject pressed. The first button in the `choices` array is 0, the second is 1, and so on +stimulus | function | The function that was drawn + + +## Examples + +### Displaying question until subject gives a response + +```javascript +function filledCirc(canvas, color){ + ctx = canvas.getContext("2d"); + ctx.beginPath(); + ctx.arc(250, 250, 100, 0, 2 * Math.PI); + ctx.fillStyle = color; + ctx.fill() +} + +var trial = { + type: 'canvas-button-response', + stimulus: function(c){ filledCirc(c, 'blue') }, + choices: ['red','green','blue'], + prompt: '

What color is the circle?

', +} +``` \ No newline at end of file diff --git a/docs/plugins/jspsych-canvas-keyboard-response.md b/docs/plugins/jspsych-canvas-keyboard-response.md index 464dc4d2a0..a7abe7a04e 100644 --- a/docs/plugins/jspsych-canvas-keyboard-response.md +++ b/docs/plugins/jspsych-canvas-keyboard-response.md @@ -1,6 +1,6 @@ # jspsych-canvas-keyboard-response -This plugin can be used to draw an image on a JavaScript canvas element, which can be useful for displaying parametrically defined shapes, and records responses generated with the keyboard. The stimulus can be displayed until a response is given, or for a pre-determined amount of time. The trial can be ended automatically if the subject has failed to respond within a fixed length of time. +This plugin can be used to draw a stimulus on a JavaScript canvas element, which can be useful for displaying parametrically defined shapes, and records responses generated with the keyboard. The stimulus can be displayed until a response is given, or for a pre-determined amount of time. The trial can be ended automatically if the subject has failed to respond within a fixed length of time. ## Parameters From 251a143adca6db6457a97b3b6951e5e70c307d06 Mon Sep 17 00:00:00 2001 From: Chris Jungerius Date: Mon, 11 May 2020 16:59:48 +0200 Subject: [PATCH 022/570] completed canvas-slider-response documentation --- .../plugins/jspsych-canvas-slider-response.md | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/plugins/jspsych-canvas-slider-response.md b/docs/plugins/jspsych-canvas-slider-response.md index a350d2d3f6..5d6eb7ab7c 100644 --- a/docs/plugins/jspsych-canvas-slider-response.md +++ b/docs/plugins/jspsych-canvas-slider-response.md @@ -1,5 +1,6 @@ # jspsych-canvas-slider-response +This plugin can be used to draw a stimulus on a JavaScript canvas element, which can be useful for displaying parametrically defined shapes, and allows the subject to respond by dragging a slider. ## Parameters @@ -7,13 +8,48 @@ Parameters with a default value of undefined must be specified. Other parameters Parameter | Type | Default Value | Description ----------|------|---------------|------------ - +stimulus | function | *undefined* | The function to draw on the canvas. This function must take a canvas element as its only argument, e.g. `foo(c)`. Note that the function will still generally need to set the correct context itself, using a line like let `ctx = c.getContext("2d")`. +canvas_size | array | [500, 500] | The size of the canvas element in pixels. +labels | array of strings | [] | Labels displayed at equidistant locations on the slider. For example, two labels will be placed at the ends of the slider. Three labels would place two at the ends and one in the middle. Four will place two at the ends, and the other two will be at 33% and 67% of the slider width. +button_label | string | 'Continue' | Label of the button to end the trial. +min | integer | 0 | Sets the minimum value of the slider. +max | integer | 100 | Sets the maximum value of the slider. +start | integer | 50 | Sets the starting value of the slider +step | integer | 1 | Sets the step of the slider. This is the smallest amount by which the slider can change. +slider_width | integer | null | Set the width of the slider in pixels. If left null, then the width will be equal to the widest element in the display. +require_movement | boolean | false | If true, the subject must move the slider before clicking the continue button. +prompt | string | null | This string can contain HTML markup. Any content here will be displayed below the stimulus. The intention is that it can be used to provide a reminder about the action the subject is supposed to take (e.g., which key to press). +stimulus_duration | numeric | null | How long to display the stimulus in milliseconds. The visibility CSS property of the stimulus will be set to `hidden` after this time has elapsed. If this is null, then the stimulus will remain visible until the trial ends. +trial_duration | numeric | null | How long to wait for the subject to make a response before ending the trial in milliseconds. If the subject fails to make a response before this timer is reached, the subject's response will be recorded as null for the trial and the trial will end. If the value of this parameter is null, then the trial will wait for a response indefinitely. +response_ends_trial | boolean | true | If true, then the trial will end whenever the subject makes a response (assuming they make their response before the cutoff specified by the `timing_response` parameter). If false, then the trial will continue until the value for `trial_duration` is reached. You can use this parameter to force the subject to view a stimulus for a fixed amount of time, even if they respond before the time is complete. ## Data Generated In addition to the [default data collected by all plugins](overview#datacollectedbyplugins), this plugin collects the following data for each trial. Name | Type | Value -----|------|------ - - -## Examples \ No newline at end of file +response | numeric | The numeric value of the slider. +rt | numeric | The time in milliseconds for the subject to make a response. The time is measured from when the stimulus first appears on the screen until the subject's response +stimulus | function | The function that was drawn. + +## Examples + +### a color evaluation scale + +```javascript +function twoSquares(c) { + let colors = ['FF3333', 'FF6A33'] + ctx = c.getcontext('2d'); + ctx.fillStyle = colors[0]; + ctx.fillRect(200, 230, 40, 40); + ctx.fillStyle = colors[1]; + ctx.fillRect(260, 230, 40, 40); +} + +var trial = { + type: canvas-slider-response, + stimulus: twoSquares, + labels: ['0','10'], + prompt: '

How different would you say the colors of these two squares are on a scale from 0 (the same) to 10 (completely different)

', +} +``` \ No newline at end of file From 7aa6736c966cd9ea3d852fcc523cffc706b1f338 Mon Sep 17 00:00:00 2001 From: Chris Jungerius <37599089+cjungerius@users.noreply.github.com> Date: Mon, 11 May 2020 18:57:51 +0200 Subject: [PATCH 023/570] final cleanup of canvas-keyboard-response --- plugins/jspsych-canvas-keyboard-response.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/jspsych-canvas-keyboard-response.js b/plugins/jspsych-canvas-keyboard-response.js index 388c73821b..5920dfff30 100644 --- a/plugins/jspsych-canvas-keyboard-response.js +++ b/plugins/jspsych-canvas-keyboard-response.js @@ -4,7 +4,7 @@ * * plugin for displaying a canvas stimulus and getting a keyboard response * - * documentation: TODO + * documentation: docs.jspsych.org * **/ From a08d320b3c1b88570993cf2ec7a04d5e5d015cd8 Mon Sep 17 00:00:00 2001 From: Daiichiro Kuroki <32691644+kurokida@users.noreply.github.com> Date: Tue, 12 May 2020 13:25:51 +0900 Subject: [PATCH 024/570] Enable to response by clicking string directly. --- plugins/jspsych-survey-likert.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/jspsych-survey-likert.js b/plugins/jspsych-survey-likert.js index a2e5f9b294..33ca9dd9ee 100644 --- a/plugins/jspsych-survey-likert.js +++ b/plugins/jspsych-survey-likert.js @@ -120,11 +120,11 @@ jsPsych.plugins['survey-likert'] = (function() { var width = 100 / question.labels.length; var options_string = '
    '; for (var j = 0; j < question.labels.length; j++) { - options_string += '
  • '; + options_string += '>' + question.labels[j] + ''; } options_string += '
'; html += options_string; From 0c33c8277e95506591a70826a1f695c78bace033 Mon Sep 17 00:00:00 2001 From: Vijay Marupudi Date: Tue, 19 May 2020 07:28:39 -0500 Subject: [PATCH 025/570] Updated to reflect that video preload is supported --- docs/core_library/jspsych-pluginAPI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core_library/jspsych-pluginAPI.md b/docs/core_library/jspsych-pluginAPI.md index 805b829406..074b1f817b 100644 --- a/docs/core_library/jspsych-pluginAPI.md +++ b/docs/core_library/jspsych-pluginAPI.md @@ -458,7 +458,7 @@ Parameter | Type | Description ----------|------|------------ plugin_name | string | The name of the plugin. e.g., 'image-keyboard-response'. parameter | string | The name of the parameter that is a media file. e.g., 'stimulus' -media_type | string | The type of media, either 'image' or 'audio'. +media_type | string | The type of media, either 'image', 'audio' or 'video'. conditional_function | function | Only run the preload for a trial if this function returns true, or if this function does not exist. ### Return value From 752d34e08f33e990780846e7b96d36ac39a7a15d Mon Sep 17 00:00:00 2001 From: Vijay Marupudi Date: Tue, 19 May 2020 07:28:39 -0500 Subject: [PATCH 026/570] Updated to reflect that video preload is supported --- docs/core_library/jspsych-pluginAPI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core_library/jspsych-pluginAPI.md b/docs/core_library/jspsych-pluginAPI.md index 805b829406..074b1f817b 100644 --- a/docs/core_library/jspsych-pluginAPI.md +++ b/docs/core_library/jspsych-pluginAPI.md @@ -458,7 +458,7 @@ Parameter | Type | Description ----------|------|------------ plugin_name | string | The name of the plugin. e.g., 'image-keyboard-response'. parameter | string | The name of the parameter that is a media file. e.g., 'stimulus' -media_type | string | The type of media, either 'image' or 'audio'. +media_type | string | The type of media, either 'image', 'audio' or 'video'. conditional_function | function | Only run the preload for a trial if this function returns true, or if this function does not exist. ### Return value From afbcaa4f3d0583f7ed182cbf79d2db5764d5a2f7 Mon Sep 17 00:00:00 2001 From: Vijay Marupudi Date: Fri, 22 May 2020 22:30:27 -0500 Subject: [PATCH 027/570] slider_start and video duplicate id fixes. --- plugins/jspsych-video-slider-response.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/jspsych-video-slider-response.js b/plugins/jspsych-video-slider-response.js index 067251d5e2..29c5a3aa21 100644 --- a/plugins/jspsych-video-slider-response.js +++ b/plugins/jspsych-video-slider-response.js @@ -146,7 +146,7 @@ jsPsych.plugins["video-slider-response"] = (function() { plugin.trial = function(display_element, trial) { // setup stimulus - var video_html = '