Merge remote-tracking branch 'jodeleeuw/master'

This commit is contained in:
LOG67 2016-07-27 11:02:45 -04:00
commit 8ac8ca964a
67 changed files with 3069 additions and 355 deletions

View File

@ -1,30 +1,43 @@
![logo](jspsych-logo-readme.jpg)
jsPsych is a JavaScript library for creating and running behavioral experiments in a web browser. jsPsych simplifies the process of coding browser-based experiments by providing a set of flexibile plugins that define different kinds of tasks a subject could complete during an experiment. By assembling different plugins together and customizing the parameters of each, it is possible to create many different types of experiments.
jsPsych is a JavaScript library for creating and running behavioral experiments in a web browser. jsPsych simplifies the process of coding browser-based experiments by providing a set of flexible plugins that define different kinds of tasks a subject could complete during an experiment. By assembling different plugins together and customizing the parameters of each, it is possible to create many different types of experiments.
Documentation
-------------
Documentation is available at [docs.jspsych.org](http://docs.jspsych.org).
Need help?
----------
For questions about using the library, please post to the [jsPsych e-mail list](https://groups.google.com/forum/#!forum/jspsych). This creates a public archive of questions and solutions.
Contributing
------------
Contributions to the code are welcome. Please use the [Issue tracker system](https://github.com/jodeleeuw/jsPsych/issues) to report bugs or discuss suggestions for new features and improvements. If you would like to contribute code, [submit a Pull request](https://help.github.com/articles/using-pull-requests).
Need help?
----------
For questions about using the library, please post to the [jsPsych e-mail list](https://groups.google.com/forum/#!forum/jspsych). This creates a publically available archive of questions and solutions.
Contact
-------
jsPsych was created by Josh de Leeuw ([@jodeleeuw](https://github.com/jodeleeuw)) at Indiana University.
Citation
--------
If you use this library in academic work, please cite the [paper that describes jsPsych](http://link.springer.com/article/10.3758%2Fs13428-014-0458-y)
de Leeuw, J.R. (2015). jsPsych: A JavaScript library for creating behavioral experiments in a Web browser. *Behavior Research Methods*, _47_(1), 1-12. doi:10.3758/s13428-014-0458-y
Response times
--------------
Wondering if jsPsych can be used for research that depends on accurate response time measurement? In general, the answer is yes. Response time measurements in jsPsych (and JavaScript in general) are comparable in noise to those taken in standard lab software like Psychophysics Toolbox and E-Prime. Response times measured in JavaScript tend to be a little bit longer (10-40ms). See the following references for extensive work on this topic.
* [de Leeuw, J. R., & Motz, B. A. (2016). Psychophysics in a Web browser? Comparing response times collected with JavaScript and Psychophysics Toolbox in a visual search task. *Behavior Research Methods*, *48*(1), 1-12.](http://link.springer.com/article/10.3758%2Fs13428-015-0567-2)
* [Hilbig, B. E. (in press). Reaction time effects in lab- versus web-based research: Experimental evidence. *Behavior Research Methods*.](http://dx.doi.org/10.3758/s13428-015-0678-9)
* [Pinet, S., Zielinski, C., Mathôt, S. et al. (in press). Measuring sequences of keystrokes with jsPsych: Reliability of response times and interkeystroke intervals. *Behavior Research Methods*.](http://link.springer.com/article/10.3758/s13428-016-0776-3)
* [Reimers, S., & Stewart, N. (2014). Presentation and response time accuracy in Adobe Flash and HTML5/JavaScript Web experiments. *Behavior Research Methods*, *47*(2), 309-327.](http://link.springer.com/article/10.3758%2Fs13428-014-0471-1)
Credits
-------
jsPsych was created by Josh de Leeuw ([@jodeleeuw](https://github.com/jodeleeuw)).
There have been many [contributors](https://github.com/jodeleeuw/jsPsych/blob/master/contributors.md) to the library. Thank you!

View File

@ -1,6 +1,7 @@
The following people have contributed to the development of jsPsych by writing code, documentation, and/or suggesting major improvements (in alphabetical order):
* Jason Carpenter
* Josh de Leeuw - https://github.com/jodeleeuw
* Jana Klaus - https://github.com/janakl4us
* Jonas Lambers
* Shane Martin - https://github.com/shamrt
* Adrian Oesch - https://github.com/adrianoesch

View File

@ -13,10 +13,12 @@ html {
font-family: 'Open Sans', 'Arial', sans-serif;
font-size: 18px;
line-height: 1.6em;
height: 100%;
}
body {
margin: 0;
padding: 0;
height: 100%;
}
p {
clear: both;
@ -86,8 +88,30 @@ input[type="text"] {
/* Container holding jsPsych content */
.jspsych-display-element {
width: 800px;
margin: 50px auto 50px auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
.jspsych-top {
align-items: flex-start;
}
.jspsych-middle {
align-items: center;
}
.jspsych-content {
margin: 50px;
}
.jspsych-content-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
}
/* jsPsych progress bar */
@ -99,6 +123,7 @@ input[type="text"] {
margin-bottom: 1em;
text-align: center;
padding: 10px 0px;
width:100%;
}
#jspsych-progressbar-container s {}
#jspsych-progressbar-outer {

View File

@ -1,5 +1,40 @@
# The jsPsych core library
---
## jsPsych.addNodeToEndOfTimeline
```
jsPsych.addNodeToEndOfTimeline(node_parameters)
```
### Parameters
Parameter | Type | Description
--------- | ---- | -----------
node_parameters | object | An object defining a timeline. It must have, at a minimum, a `timeline` parameter with a valid timeline array as the value for that parameter.
### Return value
None.
### Description
Adds the timeline to the end of the experiment.
### Example
```javascript
var trial = {
type: 'text',
text: 'This is a new trial.'
}
var new_timeline = {
timeline: [trial]
}
jsPsych.addNodeToEndOfTimeline(new_timeline)
```
---
## jsPsych.currentTimelineNodeID
@ -267,8 +302,7 @@ on_trial_start | function | Function to execute when a new trial begins.
on_trial_finish | function | Function to execute when a trial ends.
on_data_update | function | Function to execute every time data is stored using the `jsPsych.data.write` method. All plugins use this method to save data (via a call to `jsPsych.finishTrial`, so this function runs every time a plugin stores new data.
show_progress_bar | boolean | If true, then [a progress bar](../features/progress-bar.md) is shown at the top of the page.
max_load_time | numeric | The maximum number of milliseconds to wait for audio content to preload. If the wait time is exceeded, then an error message is logged and the experiment stops. The default value is 30 seconds.
skip_load_check | boolean | If true, then the experiment will not wait for audio content to load before starting. The default value is false.
max_load_time | numeric | The maximum number of milliseconds to wait for audio content to preload. If the wait time is exceeded an error message is displayed and the experiment stops. The default value is 60 seconds.
fullscreen | boolean | If true, the experiment will run in fullscreen mode. See the [feature page](../features/fullscreen.md) for more details.
default_iti | numeric | The default inter-trial interval in ms. The default value if none is specified is 1,000ms.
@ -313,6 +347,41 @@ var settings = jsPsych.initSettings();
console.log(JSON.stringify(settings.timeline));
```
---
## jsPsych.pauseExperiment
```
jsPsych.pauseExperiment()
```
### Parameters
None.
### Return value
None.
### Description
Pauses the experiment. The experiment will finish the current trial, but will not execute any additional trials until `jsPsych.resumeExperiment()` is called.
### Example
```javascript
var trial = {
type: 'single-stim',
stimulus: 'Press p to take a 30 second break. Otherwise, press c to continue immediately.',
is_html: true,
choices: ['p','c'],
on_finish: function(data){
if(data.key_press == 80) { // 80 = p
jsPsych.pauseExperiment();
setTimeout(jsPsych.resumeExperiment, 30000);
}
}
}
```
---
## jsPsych.progress
@ -348,6 +417,41 @@ var progress = jsPsych.progress();
alert('You have completed approximately '+progress.percent_complete+'% of the experiment');
```
---
## jsPsych.resumeExperiment
```
jsPsych.resumeExperiment()
```
### Parameters
None.
### Return value
None.
### Description
Resumes the experiment after a call to `jsPsych.pauseExperiment()`. If the post trial delay (`timing_post_trial`) has not yet been reached, then the experiment will not continue until the delay is finished. For example, if `timing_post_trial` was 10,000ms and `jsPsych.resumeExperiment()` was called 6,000ms after the previous trial finished, then the experiment would not continue for another 4,000ms.
### Example
```javascript
var trial = {
type: 'single-stim',
stimulus: 'Press p to take a 30 second break. Otherwise, press c to continue immediately.',
is_html: true,
choices: ['p','c'],
on_finish: function(data){
if(data.key_press == 80) { // 80 = p
jsPsych.pauseExperiment();
setTimeout(jsPsych.resumeExperiment, 30000);
}
}
}
```
---
## jsPsych.startTime

View File

@ -178,6 +178,7 @@ Gets all of the data generated by the experiment.
var alldata = jsPsych.data.getData();
```
---
## jsPsych.data.getDataByTimelineNode
@ -238,6 +239,39 @@ Gets all the data generated from a specific trial.
var first_trial_data = jsPsych.data.getDataByTrialIndex(0);
var second_trial_data = jsPsych.data.getDataByTrialIndex(1);
```
---
## jsPsych.data.getInteractionData
```
jsPsych.data.getInteractionData()
```
### Parameters
None.
### Return value
Returns an array containing events where the participant selected another window other than the experiment (blur), reselected the experiment window (focus), entered full screen mode, or exited full screen mode.
### Description
Gets a list of interaction events. Useful for tracking whether the participant completed the task without diverting attention to other windows. Events are in the form:
```javascript
{
type: 'focus' or 'blur' or 'fullscreenenter' or 'fullscreenexit',
trial: 10, // the trial number when the event happened
time: 13042 // total time elapsed since the start of the experiment
}
```
### Example
```javascript
var interactiondata = jsPsych.data.getInteractionData();
```
---
## jsPsych.data.getLastTimelineData
@ -374,6 +408,40 @@ console.log(jsPsych.data.getURLVariable('condition')) // logs "test"
```
---
## jsPsych.data.ignore
```
jsPsych.data.ignore(properties)
```
### Parameters
Parameter | Type | Description
----------|------|------------
properties | array | Array of properties to ignore.
### Return value
Returns nothing.
### Description
This method will **permanently** delete all instances of a particular property in the data. For example, if you do not want to record the `stimulus` parameter when using the single-stim plugin, you can use this method to delete all instances of `stimulus` from the data. You can call this method at any time during the experiment. All previous instances of the property will be deleted, and no future instances will be recorded.
If you need access to a property *during* the experiment, but do not want to record it in the data file, then call this method immediately before saving the data at the end of the experiment.
*Note*: If you use this method to remove `internal_node_id` from the data, some methods in `jsPsych.data` will no longer work properly.
### Examples
#### Remove all instances of 'stimulus' and 'time_elapsed'
```javascript
jsPsych.data.ignore(['stimulus', 'time_elapsed']);
```
---
## jsPsych.data.localSave

View File

@ -292,7 +292,7 @@ The `callback_load` function can be used to indicate progress. See example below
var sounds = ['file1.mp3', 'file2.mp3', 'file3.mp3'];
jsPsych.preloadAudioFiles(sounds, function(){ startExperiment(); });
jsPsych.pluginAPI.preloadAudioFiles(sounds, function(){ startExperiment(); });
function startExperiment(){
jsPsych.init({
@ -307,7 +307,7 @@ function startExperiment(){
```javascript
var sounds = ['file1.mp3', 'file2.mp3', 'file3.mp3'];
jsPsych.preloadAudioFiles(sounds, function(){ startExperiment(); }, function(nLoaded) { updateLoadedCount(nLoaded); });
jsPsych.pluginAPI.preloadAudioFiles(sounds, function(){ startExperiment(); }, function(nLoaded) { updateLoadedCount(nLoaded); });
function updateLoadedCount(nLoaded){
var percentcomplete = nLoaded / sounds.length * 100;
@ -359,7 +359,7 @@ The `callback_load` function can be used to indicate progress, if the number of
var images = ['img/file1.png', 'img/file2.png', 'img/file3.png'];
jsPsych.preloadImages(images, function(){ startExperiment(); });
jsPsych.pluginAPI.preloadImages(images, function(){ startExperiment(); });
function startExperiment(){
jsPsych.init({
@ -374,7 +374,7 @@ function startExperiment(){
```javascript
var images = ['img/file1.png', 'img/file2.png', 'img/file3.png'];
jsPsych.preloadImages(images, function(){ startExperiment(); }, function(nLoaded) { updateLoadedCount(nLoaded); });
jsPsych.pluginAPI.preloadImages(images, function(){ startExperiment(); }, function(nLoaded) { updateLoadedCount(nLoaded); });
function updateLoadedCount(nLoaded){
var percentcomplete = nLoaded / images.length * 100;
@ -395,7 +395,7 @@ function startExperiment(){
## jsPsych.pluginAPI.registerPreload
```
jsPsych.pluginAPI.registerPreload(plugin_name, parameter, media_type)
jsPsych.pluginAPI.registerPreload(plugin_name, parameter, media_type, conditional_function)
```
### Parameters
@ -405,6 +405,7 @@ Parameter | Type | Description
plugin_name | string | The name of the plugin. e.g., 'single-stim'.
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'.
conditional_function | function | Only run the preload for a trial if this function returns true, or if this function does not exist.
### Return value
@ -414,6 +415,8 @@ Nothing.
Use this method in a plugin file to mark a parameter as containing an element that should be preloaded. The method should be called in the plugin file such that it gets called when the file is loaded.
The `conditional_function` function is passed a single argument containing the trial object.
### Example
For an example, see the [single-stim](https://github.com/jodeleeuw/jsPsych/blob/master/plugins/jspsych-single-stim.js) and [single-audio](https://github.com/jodeleeuw/jsPsych/blob/master/plugins/jspsych-single-audio.js) plugins.

View File

@ -6,6 +6,7 @@ Every jsPsych experiment utilizes the core library (contained in the `jspsych.js
### [Core](jspsych-core.md)
* [jsPsych.addNodeToEndOfTimeline](jspsych-core.md#jspsychaddnodetoendoftimeline)
* [jsPsych.currentTimelineNodeID](jspsych-core.md#jspsychcurrenttimelinenodeid)
* [jsPsych.currentTrial](jspsych-core.md#jspsychcurrenttrial)
* [jsPsych.endCurrentTimeline](jspsych-core.md#jspsychendcurrenttimeline)
@ -13,8 +14,10 @@ Every jsPsych experiment utilizes the core library (contained in the `jspsych.js
* [jsPsych.finishTrial](jspsych-core.md#jspsychfinishtrial)
* [jsPsych.getDisplayElement](jspsych-core.md#jspsychgetdisplayelement)
* [jsPsych.init](jspsych-core.md#jspsychinit)
* [jsPsych.initSettings](jspsych-core.md#jspsychinitSettings)
* [jsPsych.initSettings](jspsych-core.md#jspsychinitsettings)
* [jsPsych.pauseExperiment](jspsych-core.md#jspsychpauseexperiment)
* [jsPsych.progress](jspsych-core.md#jspsychprogress)
* [jsPsych.resumeExperiment](jspsych-core.md#jspsychresumeexperiment)
* [jsPsych.startTime](jspsych-core.md#jspsychstarttime)
* [jsPsych.totalTime](jspsych-core.md#jspsychtotaltime)
@ -28,11 +31,12 @@ Every jsPsych experiment utilizes the core library (contained in the `jspsych.js
* [jsPsych.data.getData](jspsych-data.md#jspsychdatagetdata)
* [jsPsych.data.getDataByTimelineNode](jspsych-data.md#jspsychdatagetdatabytimelinenode)
* [jsPsych.data.getDataByTrialIndex](jspsych-data.md#jspsychdatagetdatabytrialindex)
* [jsPsych.data.getInteractionData](jspsych-data.md#jspsychdatagetinteractiondata)
* [jsPsych.data.getLastTimelineData](jspsych-data.md#jspsychdatagetlasttimelinedata)
* [jsPsych.data.getLastTrialData](jspsych-data.md#jspsychdatagetlasttrialdata)
* [jsPsych.data.getTrialsOfType](jspsych-data.md#jspsychdatagettrialsoftype)
* [jsPsych.data.getURLVariable](jspsych-data.md#jspsychdatageturlvariable)
* [jsPsych.data.ignore](jspsych-data.md#jspsychdataignore)
* [jsPsych.data.localSave](jspsych-data.md#jspsychdatalocalsave)
* [jsPsych.data.write](jspsych-data.md#jspsychdatawrite)
* [jsPsych.data.urlVariables](jspsych-data.md#jspsychdataurlvariables)

View File

@ -39,7 +39,7 @@ var trial = {
// an array of paths to images that need to be loaded
var images = ['img/file1.png'];
jsPsych.preloadImages(images, function(){ startExperiment(); });
jsPsych.pluginAPI.preloadImages(images, function(){ startExperiment(); });
function startExperiment(){
jsPsych.init({

View File

@ -12,7 +12,7 @@ stimuli | array | *undefined* | Each element of the array is a path to an image
frame_time | numeric | 250 | How long to display each image (in milliseconds).
frame_isi | numeric | 0 | If greater than 0, then a gap will be shown between each image in the sequence. This parameter specifies the length of the gap.
sequence_reps | numeric | 1 | How many times to show the entire sequence. There will be no gap (other than the gap specified by `frame_isi`) between repetitions.
choices | array | [ ] | 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 an empty array means that all keys will be accepted as valid responses.
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 | "" | 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).

View File

@ -16,7 +16,7 @@ choices | array | [ ] | This array contains the labels for the buttons.
button_html | string or array | `'<button class="jspsych-btn">%choice%</button>'` | 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 | "" | 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).
timing_stim | numeric | -1 | How long to show the stimulus for in milliseconds. If the value is -1, then the stimulus will be shown until the subject makes a response.
timing_response | numeric | -1 | 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 the subject's response will be recorded as -1 for the trial and the trial will end. If the value of this parameter is -1, then the trial will wait for a response indefinitely.
timing_response | numeric | -1 | 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 -1 for the trial and the trial will end. If the value of this parameter is -1, 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 `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

View File

@ -10,7 +10,7 @@ Parameter | Type | Default Value | Description
----------|------|---------------|------------
stimuli | array | *undefined* | Each element of the array is a path to an image file.
key_answer | numeric | *undefined* | A [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) indicating the correct response.
choices | array | *undefined* | 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'`).
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.
text_answer | string | "" | A text label that describes the correct answer. Used in conjunction with the `correct_text` and `incorrect_text` parameters.
correct_text | string | "Correct." | String to show when the correct answer is given. Can contain HTML formatting. The special string `%ANS%` can be used within the string. If present, the plugin will put the `text_answer` for the trial in place of the %ANS% string (see example below).
incorrect_text | string | "Wrong." | String to show when the wrong answer is given. Can contain HTML formatting. The special string `%ANS%` can be used within the string. If present, the plugin will put the `text_answer` for the trial in place of the %ANS% string (see example below).

View File

@ -10,9 +10,9 @@ Parameter | Type | Default Value | Description
----------|------|---------------|------------
stimulus | string | *undefined* | The stimulus to display. Either HTML-formatted, or the path to an image.
is_html | boolean | false | If `stimulus` is an HTML-formatted string, this parameter needs to be set to `true`.
key_answer | array | *undefined* | Each element of the array is a [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) indicating the correct response for the corresponding trial. The length of this array should match the `stimuli` array.
choices | array | *undefined* | 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'`).
text_answer | array | "" | Array of strings representing a label that is associated with each correct answer. Used in conjunction with the `correct_text` and `incorrect_text` parameters.
key_answer | numeric | *undefined* | The [numeric key code](http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes) indicating the correct response.
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.
text_answer | string | "" | A label that is associated with the correct answer. Used in conjunction with the `correct_text` and `incorrect_text` parameters.
correct_text | string | "Correct." | String to show when the correct answer is given. Can contain HTML formatting. The special string `%ANS%` can be used within the string. If present, the plugin will put the `text_answer` for the trial in place of the %ANS% string (see example below).
incorrect_text | string | "Wrong." | String to show when the wrong answer is given. Can contain HTML formatting. The special string `%ANS%` can be used within the string. If present, the plugin will put the `text_answer` for the trial in place of the %ANS% string (see example below).
prompt | string | "" | 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).

View File

@ -2,6 +2,10 @@
The free-sort plugin displays a collection of images on the screen that the subject can interact with by clicking and dragging. All of the moves that the subject performs are recorded.
## Dependency
This plugin requires the jQuery UI library, available at [https://jqueryui.com/](https://jqueryui.com/). You must include the library in the `<head>` section of your experiment page. You can use the [Google-hosted version of the library](https://developers.google.com/speed/libraries/#jquery-ui).
## Parameters
This table lists the parameters associated with this plugin. Parameters with a default value of *undefined* must be specified. Other parameters can be left unspecified if the default value is acceptable.

View File

@ -13,10 +13,11 @@ This table lists the parameters associated with this plugin. Parameters with a d
Parameter | Type | Default Value | Description
----------|------|---------------|------------
stimulus | string | *undefined* | Path to an audio file.
choices | array | [ ] | 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 an empty array means that all keys will be accepted as valid responses.
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 | "" | This string can contain HTML markup. Any content here will be displayed on the screen. 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).
timing_response | numeric | -1 | 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 the subject's response will be recorded as -1 for the trial and the trial will end. If the value of this parameter is -1, 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 `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.
trial_ends_after_audio | boolean | false | If true, then the trial will end as soon as the audio file finishes playing.
## Data Generated

View File

@ -12,7 +12,7 @@ Parameter | Type | Default Value | Description
----------|------|---------------|------------
stimulus | string | *undefined* | The stimulus to display. Either HTML-formatted, or the path to an image.
is_html | boolean | false | If `stimulus` is an HTML-formatted string, this parameter needs to be set to `true`.
choices | array | [ ] | 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 an empty array means that all keys will be accepted as valid responses.
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 | "" | 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).
timing_stim | numeric | -1 | How long to show the stimulus for in milliseconds. If the value is -1, then the stimulus will be shown until the subject makes a response.
timing_response | numeric | -1 | 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 the subject's response will be recorded as -1 for the trial and the trial will end. If the value of this parameter is -1, then the trial will wait for a response indefinitely.

View File

@ -12,7 +12,7 @@ questions | array | *undefined* | An array of strings. The strings are the promp
options | array | *undefined* | An array of arrays. The innermost arrays contain a set of options to display for an individual question. The length of the outer array should be the same as the number of questions.
required | array | null | An array of boolean values. Each boolean indicates if a question is required (`true`) or not (`false`), using the HTML5 `required` attribute. The length of this array should correspond to the length of the questions array. If this parameter is undefined, all questions will be optional. Note: The HTML5 `required` attribute is [not currently supported by the Safari browser][1].
horizontal | boolean | false | If true, then questions are centered and options are displayed horizontally.
preamble | array | empty string | Array of HTML formatted strings to display at the top of each page above all the questions. Each element of the array corresponds to a trial/page of questions.
preamble | string | empty string | HTML formatted string to display at the top of the page above all the questions.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Browser_compatibility

View File

@ -0,0 +1,33 @@
# jspsych-video plugin
This plugin is for showing a video. No responses are recorded. The trial concludes when the video finishes.
## Parameters
This table lists the parameters associated with this plugin. 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
----------|------|---------------|------------
sources | array | *undefined* | An array of file paths to the video. You can specify multiple formats of the same video (e.g., .mp4, .ogg, .webm) to maximize the [cross-browser compatibility](https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats). Usually .mp4 is a safe option. The player will use the first source file in the array that is compatible with the browser, so specify the files in order of preference.
width | numeric | width of the video file | The width of the video display in pixels.
height | numeric | heigh of the video file | The height of the video display in pixels.
prompt | string | empty string | A message (any valid HTML) to display beneath the video element.
autoplay | boolean | true | If true, the video will begin playing as soon as it has loaded.
controls | boolean | false | If true, controls for the video player will be available to the subject. They will be able to pause the video or move the playback to any point in the video.
## 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
-----|------|------
stimulus | string | JSON encoding of the `sources` array.
## Example
```javascript
var trial = {
type: 'video',
sources: ['video/sample_video.mp4']
}
```

View File

@ -19,7 +19,7 @@ canvas_size | array | `[400, 400]` | Array specifying the width and height of th
image_size | array | `[100, 100]` | Array specifying the width and height of the images to show. The occluding rectangle will have a width equal to the width of image_size.
initial_direction | string | "left" | Which direction the stimulus should move first (subsequent directions will alternate). Choices are "left" or "right".
occlude_center | boolean | true | If true, display a rectangle in the center of the screen that is just wide enough to occlude the image completely as it passes behind.
choices | array | [ ] | 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 an empty array means that all keys will be accepted as valid responses.
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.
timing_cycle | numeric | 1000 | How long it takes for a stimulus in the sequence to make a complete cycle (move to the edge and back to the center) in milliseconds.
timing_pre_movement | numeric | 500 | How long to wait before the stimuli starts moving from behind the center rectangle.

View File

@ -84,6 +84,7 @@ This table is a description of all plugins that are currently bundled with jsPsy
[jspsych&#8209;survey&#8209;multi&#8209;choice](jspsych-survey-multi-choice) | Displays multiple choice questions.
[jspsych&#8209;survey&#8209;text](jspsych-survey-text) | Shows a prompt with a text box. The subject writes a response and then submits by clicking a button.
[jspsych&#8209;text](jspsych-text) | Shows HTML-formatted text on the screen.
[jspsych&#8209;video](jspsych-video) | Displays a video file and autoadvances to the next trial when the video is complete.
[jspsych&#8209;visual&#8209;search&#8209;circle](jspsych-visual-search-circle) | A customizable visual-search task modelled after [Wang, Cavanagh, & Green (1994)](http://dx.doi.org/10.3758/BF03206946). The subject indicates whether or not a target is present among a set of distractors. The stimuli are displayed in a circle, evenly-spaced, equidistant from a fixation point.
[jspsych&#8209;vsl&#8209;animate&#8209;occlusion](jspsych-vsl-animate-occlusion) | A visual statistical learning paradigm based on [Fiser & Aslin (2002)](http://dx.doi.org/10.1037//0278-7393.28.3.458). A sequence of stimuli are shown in an oscillatory motion. An occluding rectangle is in the center of the display, and the stimuli change when they are behind the rectangle.
[jspsych&#8209;vsl&#8209;grid&#8209;scene](jspsych-vsl-grid-scene) | A visual statistical learning paradigm based on [Fiser & Aslin (2001)](http://dx.doi.org/10.1111/1467-9280.00392). A scene made up of individual stimuli arranged in a grid is shown. This plugin can also generate the HTML code to render the stimuli for use in other plugins.

View File

@ -0,0 +1,502 @@
#Eriksen Flanker Task
The flanker task is a popular task to measure response inhibition. In the variant presented here, participants are
required to judge whether an arrow presented between four other arrows is pointing in the same or the opposite
direction by pressing a key on the keyboard. We will create a 100-trial long version of this task which provides
feedback on the participant's performance at the end of the experiment.
##Part 1: Setting up the HTML file
As always, we need to create an HTML file which references the Javascript plugins and CSS required. For this experiment,
we will only use the [jspsych-text](https://github.com/jodeleeuw/jsPsych/blob/master/plugins/jspsych-text.js) and [jspsych-single-stim](https://github.com/jodeleeuw/jsPsych/blob/master/plugins/jspsych-single-stim.js)
plugins which can be specified in the `<head>` of the file.
```html
<!doctype html>
<html>
<head>
<title>Flanker Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych.js"></script>
<script src="plugins/jspsych-text.js"></script>
<script src="plugins/jspsych-single-stim.js"></script>
<link href="css/jspsych.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
</html>
```
##Part 2: Adding welcome and instructions block and starting the experiment
This is also very straightforward. We present a welcome message as well as the instructions in two separate blocks. Of
course, this text can be adapted according to what you want to focus on. Here, we're just saying that the task is to
press one of two buttons in response to the middle arrow displayed on the screen. Note that after the participants read
the instructions, they can start the experiment by pressing the <em>ENTER</em> key (defined as key 13). The first trial then
starts 3000 ms after that button press. These options obviously can be changed as well.
```javascript
var welcome = {
type: "text",
text: "<p style='margin:20%'>Welcome to the experiment. Press any key to begin.</p>"
};
var instructions = {
type: "text",
text: "<p style='margin-top:20%; margin-right:10%'>In this task you are required to respond to " +
"stimuli displayed on the screen. In the following, you will see five arrows. Your task " +
"is to decide as quickly as possible if the arrow in the middle is pointing in the same " +
"direction as the others or not. If this is the case ('<strong><<<<<</strong>' or " +
"'<strong>>>>>></strong>'), please press the left arrow button on the keyboard. If the " +
"middle arrow is pointing in the opposite direction ('<strong><<><<</strong>' or " +
"'<strong>>><>></strong>'), please press the right arrow button on the keyboard. You can " +
"start the experiment by pressing ENTER.</p>",
timing_post_trial: 3000
};
```
Both blocks need to be added to the timeline of the experiment.
```javascript
var timeline = [];
timeline.push(welcome);
timeline.push(instructions);
```
Finally, we need to initiate the experiment by adding this piece of code at the bottom:
```javascript
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
);
```
If you are unsure about any of this, go back to the [tutorial for running a simple reaction time task]
(http://docs.jspsych.org/tutorials/rt-task/).
###The code so far:
```html
<!doctype html>
<html>
<head>
<title>Flanker Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych.js"></script>
<script src="plugins/jspsych-text.js"></script>
<script src="plugins/jspsych-single-stim.js"></script>
<link href="css/jspsych.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
<script>
/*set up welcome block*/
var welcome = {
type: "text",
text: "<p style='margin:20%'>Welcome to the experiment. Press any key to begin.</p>"
};
/*set up instructions block*/
var instructions = {
type: "text",
text: "<p style='margin-top:20%; margin-right:10%'>In this task you are required to respond to " +
"stimuli displayed on the screen. In the following, you will see five arrows. Your task " +
"is to decide as quickly as possible if the arrow in the middle is pointing in the same " +
"direction as the others or not. If this is the case ('<strong><<<<<</strong>' or " +
"'<strong>>>>>></strong>'), please press the left arrow button on the keyboard. If the " +
"middle arrow is pointing in the opposite direction ('<strong><<><<</strong>' or " +
"'<strong>>><>></strong>'), please press the right arrow button on the keyboard. You can " +
"start the experiment by pressing ENTER.</p>",
timing_post_trial: 3000
};
/*set up experiment structure*/
var timeline = [];
timeline.push(welcome);
timeline.push(instructions);
/*start experiment*/
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
);
</script>
</html>
```
If you run this code in your browser, you should see the welcome message as well as the instructions. Next, we need to
define which stimuli we are going to use for the experiment.
##Part 3: Defining the stimuli
For this experiment we are using four image files which are stored in the `img` folder. First, we need to define them
as being the `test_stimuli` we want to use. At the same time, we can also define specific attributes per stimulus. For
instance, we might want to keep track of the congruency of the stimuli, regardless of the direction in which they are
pointing. To do this, we don't just define the location of the stimulus image in the `stimulus`, but also an additional
attribute in the `data` line. Note that this information will automatically be stored in your result file. You can add
whatever extra information you might need here.
```javascript
var test_stimuli = [
{
stimulus: "img/con1.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/con2.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/inc1.png",
data: { phase: 'incongruent'}
},
{
stimulus: "img/inc2.png",
data: { phase: 'incongruent'}
}
];
```
Now that we have defined our stimuli, we want them to be displayed and repeated in a random order. This can easily be
done by using the randomisation code implemented in jsPsych. We simply create a variable which we call `all_trials`
that is going to display each stimulus <em>x</em> times, <em>x</em> being the number you define. Let's say we want a
100-trial experiment:
```javascript
var all_trials = jsPsych.randomization.repeat(test_stimuli, 25);
```
We also want the inter-stimulus interval to be variable, so we define a `post_trial_gap`. This will use a random value
between 1000 and 2000 ms, with uniform sampling from the range. Again, you can modify these parameters as you please.
```javascript
var post_trial_gap = function() {
return Math.floor(Math.random() * 1500) + 500;
};
```
##Part 4: Creating an experimental block
So far, we have set up a welcome message, an instructions block, and the stimuli for our experiment. Now comes the most
important part, that is, creating our `test_block`. It is supported by the `single-stim` plugin, so this information
needs to go in first. Then, we defined the left and right arrow of the keyboard as our response keys, so their keycodes
(37 and 39; look up your required keycodes [here](http://www.asquare.net/javascript/tests/KeyCode.html)) need to be
defined in the `choices` tag. We want each stimulus to be presented for 1500 ms at most, which should be defined in
`timing_response`. Finally, we need to state which stimuli we need to add the information we created in the previous
steps, i.e., defining `all_trials` as our stimulus variable and `post_trial_gap` as our inter-stimulus interval.
```javascript
var test_block = {
type: 'single-stim',
choices: [37, 39],
timing_response: 1500,
timeline: all_trials,
timing_post_trial: post_trial_gap
};
```
Of course, this block also needs to be added to the experiment's timeline:
```javascript
timeline.push(test_block);
```
###The code so far:
```html
<!doctype html>
<html>
<head>
<title>Flanker Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych.js"></script>
<script src="plugins/jspsych-text.js"></script>
<script src="plugins/jspsych-single-stim.js"></script>
<link href="css/jspsych.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
<script>
/*set up welcome block*/
var welcome = {
type: "text",
text: "<p style='margin:20%'>Welcome to the experiment. Press any key to begin.</p>"
};
/*set up instructions block*/
var instructions = {
type: "text",
text: "<p style='margin-top:20%; margin-right:10%'>In this task you are required to respond to " +
"stimuli displayed on the screen. In the following, you will see five arrows. Your task " +
"is to decide as quickly as possible if the arrow in the middle is pointing in the same " +
"direction as the others or not. If this is the case ('<strong><<<<<</strong>' or " +
"'<strong>>>>>></strong>'), please press the left arrow button on the keyboard. If the " +
"middle arrow is pointing in the opposite direction ('<strong><<><<</strong>' or " +
"'<strong>>><>></strong>'), please press the right arrow button on the keyboard. You can " +
"start the experiment by pressing ENTER.</p>",
timing_post_trial: 3000
};
/*defining stimuli*/
var test_stimuli = [
{
stimulus: "img/con1.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/con2.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/inc1.png",
data: { phase: 'incongruent'}
},
{
stimulus: "img/inc2.png",
data: { phase: 'incongruent'}
}
];
/*randomising stimuli*/
var all_trials = jsPsych.randomization.repeat(test_stimuli, 25);
/*creating random ISI*/
var post_trial_gap = function() {
return Math.floor(Math.random() * 1500) + 500;
};
/*defining experimental block*/
var test_block = {
type: 'single-stim',
choices: [37, 39],
timing_response: 1500,
timeline: all_trials,
timing_post_trial: post_trial_gap
};
/*set up experiment structure*/
var timeline = [];
timeline.push(welcome);
timeline.push(instructions);
timeline.push(test_block);
/*start experiment*/
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
);
</script>
</html>
```
##Part 5: Presenting feedback to the participants
Running the experiment now will provide you with a welcome message, instructions, and 100 trials. We would like to give
the participants feedback about their performance at the end of the experiment. (Note: This was already part of the
[basic tutorial](http://docs.jspsych.org/tutorials/rt-task/#part-13-displaying-data-to-the-subject)). We first need to
modify our `test_block` a bit to define what a correct trial is.
```javascript
var test_block = {
type: 'single-stim',
choices: [37, 39],
timing_response: 1500,
on_finish: function(data){
var correct = false;
if(data.phase == 'congruent' && data.key_press == '37' && data.rt > -1){
correct = true;
} else if(data.phase == 'incongruent' && data.key_press == '39' && data.rt > -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
},
timeline: all_trials,
timing_post_trial: post_trial_gap
};
```
Essentially, what we're doing here is saying that whenever a congruent stimulus was displayed and the left arrow key
was pressed <em>or</em> an incongruent stimulus was displayed and the right arrow key was pressed (and neither of those
reactions was later than the 1500 ms limit we defined earlier), the program returns the information that these are
correct trials.
We want to display both the percentage of correct responses as well as the mean reaction time. For this, we need to add
the following function to the code:
```javascript
function getSubjectData() {
var trials = jsPsych.data.getTrialsOfType('single-stim');
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt / correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
};
```
Finally, we add a debriefing block which is displayed after the last trial of the experiment. Don't forget to add this
block to the timeline as well!
```javascript
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return "<p style='margin:20%'>You responded correctly on "+subject_data.accuracy+"% of the trials. " +
"Your average response time was <strong>" + subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
}
};
```
###The final code:
```html
<!doctype html>
<html>
<head>
<title>Flanker Task</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych.js"></script>
<script src="plugins/jspsych-text.js"></script>
<script src="plugins/jspsych-single-stim.js"></script>
<link href="css/jspsych.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
<script>
/*set up welcome block*/
var welcome = {
type: "text",
text: "<p style='margin:20%'>Welcome to the experiment. Press any key to begin.</p>"
};
/*set up instructions block*/
var instructions = {
type: "text",
text: "<p style='margin-top:20%; margin-right:10%'>In this task you are required to respond to " +
"stimuli displayed on the screen. In the following, you will see five arrows. Your task " +
"is to decide as quickly as possible if the arrow in the middle is pointing in the same " +
"direction as the others or not. If this is the case ('<strong><<<<<</strong>' or " +
"'<strong>>>>>></strong>'), please press the left arrow button on the keyboard. If the " +
"middle arrow is pointing in the opposite direction ('<strong><<><<</strong>' or " +
"'<strong>>><>></strong>'), please press the right arrow button on the keyboard. You can " +
"start the experiment by pressing ENTER.</p>",
timing_post_trial: 3000
};
/*defining stimuli*/
var test_stimuli = [
{
stimulus: "img/con1.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/con2.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/inc1.png",
data: { phase: 'incongruent'}
},
{
stimulus: "img/inc2.png",
data: { phase: 'incongruent'}
}
];
/*randomising stimuli*/
var all_trials = jsPsych.randomization.repeat(test_stimuli, 25);
/*creating random ISI*/
var post_trial_gap = function() {
return Math.floor(Math.random() * 1500) + 500;
};
/*defining experimental block*/
var test_block = {
type: 'single-stim',
choices: [37, 39],
timing_response: 1500,
on_finish: function(data){
var correct = false;
if(data.phase == 'congruent' && data.key_press == '37' && data.rt > -1){
correct = true;
} else if(data.phase == 'incongruent' && data.key_press == '39' && data.rt > -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
},
timeline: all_trials,
timing_post_trial: post_trial_gap
};
/*function for getting mean RTs and error rates*/
function getSubjectData() {
var trials = jsPsych.data.getTrialsOfType('single-stim');
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt / correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
};
/*defining debriefing block*/
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return "<p style='margin:20%'>You responded correctly on "+subject_data.accuracy+"% of the trials. " +
"Your average response time was <strong>" + subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
}
};
/*set up experiment structure*/
var timeline = [];
timeline.push(welcome);
timeline.push(instructions);
timeline.push(test_block);
timeline.push(debrief_block);
/*start experiment*/
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
);
</script>
</html>
```

View File

@ -246,8 +246,7 @@ timeline.push(blue_trial, orange_trial);
"<p class='small'><strong>Press the F key</strong></p></div>" +
"<div class='right center-content'><img src='img/orange.png'></img>" +
"<p class='small'><strong>Do not press a key</strong></p></div>" +
"<p>Press any key to begin.</p>",
timing_post_trial: 2000
"<p>Press any key to begin.</p>"
};
/* define test trials */
@ -387,7 +386,7 @@ We need the `displayData` function to execute when the experiment ends. One way
```javascript
jsPsych.init({
experiment_structure: experiment,
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
@ -520,7 +519,7 @@ var debrief_block = {
We need to add the debrief block to the experiment definition array.
```javascript
experiment.push(debrief_block);
timeline.push(debrief_block);
```
## The final code

View File

@ -15,6 +15,7 @@ pages:
- Tutorials:
- 'The Basics: Hello World': 'tutorials/hello-world.md'
- 'Demo Experiment: Simple Reaction Time Task': 'tutorials/rt-task.md'
- 'Flanker Task': 'tutorials/flanker.md'
- Features:
- 'Creating an Experiment: The Timeline': 'features/timeline.md'
- 'Data Storage': 'features/data.md'

File diff suppressed because it is too large Load Diff

View File

@ -11,12 +11,57 @@ jsPsych.plugins.animation = (function() {
jsPsych.pluginAPI.registerPreload('animation', 'stimuli', 'image');
plugin.info = {
name: 'animation',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
array: true,
description: ''
},
frame_time: {
type: [jsPsych.plugins.parameterType.INT],
default: 250,
no_function: false,
description: ''
},
frame_isi: {
type: [jsPsych.plugins.parameterType.INT],
default: 0,
no_function: false,
description: ''
},
sequence_reps: {
type: [jsPsych.plugins.parameterType.INT],
default: 1,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: jsPsych.ALL_KEYS,
no_function: false,
array: true,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
trial.frame_time = trial.frame_time || 250;
trial.frame_isi = trial.frame_isi || 0;
trial.sequence_reps = trial.sequence_reps || 1;
trial.choices = trial.choices || [];
trial.choices = trial.choices || jsPsych.ALL_KEYS;
trial.prompt = (typeof trial.prompt === 'undefined') ? "" : trial.prompt;
// if any trial variables are functions

View File

@ -12,6 +12,65 @@ jsPsych.plugins["button-response"] = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('button-response', 'stimulus', 'image', function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'button-response',
description: '',
parameters: {
stimulus: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: [],
array: true,
no_function: false,
description: ''
},
button_html: {
type: [jsPsych.plugins.parameterType.STRING],
default: '<button class="jspsych-btn">%choice%</button>',
no_function: false,
array: true,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
timing_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
response_ends_trial: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
}
}
plugin.trial = function(display_element, trial) {
// default trial parameters

View File

@ -11,6 +11,19 @@ jsPsych.plugins['call-function'] = (function() {
var plugin = {};
plugin.info = {
name: 'call-function',
description: '',
parameters: {
func: {
type: [jsPsych.plugins.parameterType.FUNCTION],
default: undefined,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// one of the only plugins where we override the default experiment level
@ -23,7 +36,6 @@ jsPsych.plugins['call-function'] = (function() {
value: return_val
};
jsPsych.finishTrial(trial_data);
};

View File

@ -12,9 +12,84 @@ jsPsych.plugins["categorize-animation"] = (function() {
jsPsych.pluginAPI.registerPreload('categorize-animation', 'stimuli', 'image');
plugin.info = {
name: 'categorize-animation',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.ARRAY],
default: undefined,
no_function: false,
description: ''
},
key_answer: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: undefined,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: jsPsych.ALL_KEYS,
no_function: false,
array: true,
description: ''
},
text_answer: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
correct_text: {
type: [jsPsych.plugins.parameterType.STRING],
default: 'Correct.',
no_function: false,
description: ''
},
incorrect_text: {
type: [jsPsych.plugins.parameterType.STRING],
default: 'Wrong.',
no_function: false,
description: ''
},
frame_time: {
type: [jsPsych.plugins.parameterType.INT],
default: 250,
no_function: false,
description: ''
},
sequence_reps: {
type: [jsPsych.plugins.parameterType.INT],
default: 1,
no_function: false,
description: ''
},
allow_response_before_complete: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
timing_feedback_duration: {
type: [jsPsych.plugins.parameterType.INT],
default: 2000,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
}
}
plugin.trial = function(display_element, trial) {
// set default values
trial.choices = trial.choices || jsPsych.ALL_KEYS;
trial.sequence_reps = trial.sequence_reps || 1;
trial.key_answer = trial.key_answer;
trial.text_answer = (typeof trial.text_answer === 'undefined') ? "" : trial.text_answer;

View File

@ -10,11 +10,110 @@ jsPsych.plugins.categorize = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('animation', 'stimulus', 'image');
jsPsych.pluginAPI.registerPreload('categorize', 'stimulus', 'image',function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'categorize',
description: '',
parameters: {
stimulus: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: undefined,
no_function: false,
description: ''
},
key_answer: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: undefined,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: jsPsych.ALL_KEYS,
array: true,
no_function: false,
description: ''
},
text_answer: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
correct_text: {
type: [jsPsych.plugins.parameterType.STRING],
default: 'Correct.',
no_function: false,
description: ''
},
incorrect_text: {
type: [jsPsych.plugins.parameterType.STRING],
default: 'Wrong.',
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
force_correct_button_press: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
show_stim_with_feedback: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
show_feedback_on_timeout: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
timeout_message: {
type: [jsPsych.plugins.parameterType.STRING],
default: 'Please respond faster.',
no_function: false,
description: ''
},
timing_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_feedback_duration: {
type: [jsPsych.plugins.parameterType.INT],
default: 2000,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default parameters
trial.choices = triaul.choices || jsPsych.ALL_KEYS;
trial.text_answer = (typeof trial.text_answer === 'undefined') ? "" : trial.text_answer;
trial.correct_text = (typeof trial.correct_text === 'undefined') ? "<p class='feedback'>Correct</p>" : trial.correct_text;
trial.incorrect_text = (typeof trial.incorrect_text === 'undefined') ? "<p class='feedback'>Incorrect</p>" : trial.incorrect_text;

View File

@ -13,6 +13,57 @@ jsPsych.plugins['free-sort'] = (function() {
jsPsych.pluginAPI.registerPreload('free-sort', 'stimuli', 'image');
plugin.info = {
name: 'free-sort',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
stim_height: {
type: [jsPsych.plugins.parameterType.INT],
default: 100,
no_function: false,
description: ''
},
stim_width: {
type: [jsPsych.plugins.parameterType.INT],
default: 100,
no_function: false,
description: ''
},
sort_area_height: {
type: [jsPsych.plugins.parameterType.INT],
default: 800,
no_function: false,
description: ''
},
sort_area_width: {
type: [jsPsych.plugins.parameterType.INT],
default: 800,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
prompt_location: {
type: [jsPsych.plugins.parameterType.SELECT],
options: ['above','below'],
default: 'above',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default values

View File

@ -10,6 +10,43 @@ jsPsych.plugins.html = (function() {
var plugin = {};
plugin.info = {
name: 'html',
description: '',
parameters: {
url: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
cont_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: null,
no_function: false,
description: ''
},
cont_btn: {
type: [jsPsych.plugins.parameterType.STRING],
default: null,
no_function: false,
description: ''
},
check_fn: {
type: [jsPsych.plugins.parameterType.FUNCTION],
default: 'function() { return true; }',
no_function: false,
description: ''
},
force_refresh: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default parameters

View File

@ -13,6 +13,50 @@ jsPsych.plugins.instructions = (function() {
var plugin = {};
plugin.info = {
name: 'instructions',
description: '',
parameters: {
pages: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
key_forward: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'rightarrow',
no_function: false,
description: ''
},
key_backward: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'leftarrow',
no_function: false,
description: ''
},
allow_backward: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
allow_keys: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
show_clickable_nav: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
trial.key_forward = trial.key_forward || 'rightarrow';

View File

@ -14,7 +14,59 @@ jsPsych.plugins["multi-stim-multi-response"] = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('multi-stim-multi-response', 'stimuli', 'image');
jsPsych.pluginAPI.registerPreload('multi-stim-multi-response', 'stimuli', 'image',function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'multi-stim-multi-response',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: undefined,
array: true,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
timing_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
array: true,
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
response_ends_trial: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {

View File

@ -20,6 +20,55 @@ jsPsych.plugins.palmer = (function() {
var plugin = {};
plugin.info = {
name: 'palmer',
description: '',
parameters: {
configuration: {
type: [jsPsych.plugins.parameterType.INT],
default: undefined,
array: true,
no_function: false,
description: ''
},
show_feedback: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
grid_spacing: {
type: [jsPsych.plugins.parameterType.INT],
default: 75,
no_function: false,
description: ''
},
circle_radius: {
type: [jsPsych.plugins.parameterType.INT],
default: 20,
no_function: false,
description: ''
},
square_size: {
type: [jsPsych.plugins.parameterType.INT],
default: 3,
no_function: false,
description: ''
},
timing_feedback: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {

View File

@ -14,6 +14,43 @@ jsPsych.plugins['reconstruction'] = (function() {
var plugin = {};
plugin.info = {
name: 'reconstruction',
description: '',
parameters: {
stim_function: {
type: [jsPsych.plugins.parameterType.FUNCTION],
default: undefined,
no_function: false,
description: ''
},
starting_value: {
type: [jsPsych.plugins.parameterType.FLOAT],
default: 0.5,
no_function: false,
description: ''
},
step_size: {
type: [jsPsych.plugins.parameterType.FLOAT],
default: 0.05,
no_function: false,
description: ''
},
key_increase: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'h',
no_function: false,
description: ''
},
key_decrease: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'g',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default parameter values

View File

@ -12,7 +12,70 @@ jsPsych.plugins['same-different'] = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('same-different', 'stimuli', 'image');
jsPsych.pluginAPI.registerPreload('same-different', 'stimuli', 'image',function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'same-different',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
answer: {
type: [jsPsych.plugins.parameterType.SELECT],
options: ['same', 'different'],
default: 75,
no_function: false,
description: ''
},
same_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'Q',
no_function: false,
description: ''
},
different_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'P',
no_function: false,
description: ''
},
timing_first_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_gap: {
type: [jsPsych.plugins.parameterType.INT],
default: 500,
no_function: false,
description: ''
},
timing_second_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
@ -105,11 +168,14 @@ jsPsych.plugins['same-different'] = (function() {
var correct = false;
if (info.key == trial.same_key && trial.answer == 'same') {
var skey = typeof trial.same_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.same_key) : trial.same_key;
var dkey = typeof trial.different_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.different_key) : trial.different_key;
if (info.key == skey && trial.answer == 'same') {
correct = true;
}
if (info.key == trial.different_key && trial.answer == 'different') {
if (info.key == dkey && trial.answer == 'different') {
correct = true;
}

View File

@ -13,7 +13,77 @@ jsPsych.plugins.similarity = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('similarity', 'stimuli', 'image');
jsPsych.pluginAPI.registerPreload('similarity', 'stimuli', 'image',function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'similarity',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
labels: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: ['Not at all similar', 'Identical'],
no_function: false,
description: ''
},
intervals: {
type: [jsPsych.plugins.parameterType.INT],
default: 100,
no_function: false,
description: ''
},
show_ticks: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
show_response: {
type: [jsPsych.plugins.parameterType.SELECT],
options: ['FIRST_STIMULUS', 'SECOND_STIMULUS','POST_STIMULUS'],
default: 'SECOND_STIMULUS',
no_function: false,
description: ''
},
timing_first_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_image_gap: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_second_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {

View File

@ -12,16 +12,58 @@ jsPsych.plugins["single-audio"] = (function() {
var plugin = {};
var context = new AudioContext();
jsPsych.pluginAPI.registerPreload('single-audio', 'stimulus', 'audio');
plugin.info = {
name: 'single-audio',
description: '',
parameters: {
stimulus: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
array: true,
default: jsPsych.ALL_KEYS,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
response_ends_trial: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
trial_ends_after_audio: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
}
}
plugin.trial = function(display_element, trial) {
// default parameters
trial.choices = trial.choices || [];
trial.choices = trial.choices || jsPsych.ALL_KEYS;
trial.response_ends_trial = (typeof trial.response_ends_trial === 'undefined') ? true : trial.response_ends_trial;
// timing parameters
trial.trial_ends_after_audio = (typeof trial.trial_ends_after_audio === 'undefined') ? false : trial.trial_ends_after_audio;
trial.timing_response = trial.timing_response || -1; // if -1, then wait for response forever
trial.prompt = (typeof trial.prompt === 'undefined') ? "" : trial.prompt;
@ -35,12 +77,20 @@ jsPsych.plugins["single-audio"] = (function() {
var setTimeoutHandlers = [];
// play stimulus
var context = jsPsych.pluginAPI.audioContext();
var source = context.createBufferSource();
source.buffer = jsPsych.pluginAPI.getAudioBuffer(trial.stimulus);
source.connect(context.destination);
startTime = context.currentTime + 0.1;
source.start(startTime);
// set up end event if trial needs it
if(trial.trial_ends_after_audio){
source.onended = function() {
end_trial();
}
}
// show prompt if there is one
if (trial.prompt !== "") {
display_element.append(trial.prompt);
@ -69,7 +119,7 @@ jsPsych.plugins["single-audio"] = (function() {
// gather the data to store for the trial
var trial_data = {
"rt": response.rt * 1000,
"stimulus": trial.audio_path,
"stimulus": trial.stimulus,
"key_press": response.key
};

View File

@ -13,7 +13,58 @@ jsPsych.plugins["single-stim"] = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('single-stim', 'stimulus', 'image');
jsPsych.pluginAPI.registerPreload('single-stim', 'stimulus', 'image', function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'single-stim',
description: '',
parameters: {
stimulus: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
array: true,
default: jsPsych.ALL_KEYS,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
timing_stim: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
response_ends_trial: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
}
}
plugin.trial = function(display_element, trial) {
@ -23,7 +74,7 @@ jsPsych.plugins["single-stim"] = (function() {
trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);
// set default values for the parameters
trial.choices = trial.choices || [];
trial.choices = trial.choices || jsPsych.ALL_KEYS;
trial.response_ends_trial = (typeof trial.response_ends_trial == 'undefined') ? true : trial.response_ends_trial;
trial.timing_stim = trial.timing_stim || -1;
trial.timing_response = trial.timing_response || -1;

View File

@ -12,6 +12,27 @@ jsPsych.plugins['survey-likert'] = (function() {
var plugin = {};
plugin.info = {
name: 'survey-likert',
description: '',
parameters: {
questions: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
labels: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default parameters for the trial

View File

@ -13,6 +13,46 @@ jsPsych.plugins['survey-multi-choice'] = (function() {
var plugin = {};
plugin.info = {
name: 'survey-multi-choice',
description: '',
parameters: {
questions: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
options: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
required: {
type: [jsPsych.plugins.parameterType.BOOL],
array: true,
default: false,
no_function: false,
description: ''
},
horitzontal: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
preamble: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
var plugin_id_name = "jspsych-survey-multi-choice";

View File

@ -13,6 +13,40 @@ jsPsych.plugins['survey-text'] = (function() {
var plugin = {};
plugin.info = {
name: 'survey-text',
description: '',
parameters: {
questions: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
premable: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
rows: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: 1,
no_function: false,
description: ''
},
columns: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: 40,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
trial.preamble = typeof trial.preamble == 'undefined' ? "" : trial.preamble;

View File

@ -13,9 +13,30 @@ jsPsych.plugins.text = (function() {
var plugin = {};
plugin.info = {
name: 'text',
description: '',
parameters: {
text: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
cont_key: {
type: [jsPsych.plugins.parameterType.KEYCODE, jsPsych.plugins.parameterType.SELECT],
options: ['mouse'],
array: true,
default: undefined,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
trial.cont_key = trial.cont_key || [];
trial.cont_key = trial.cont_key || jsPsych.ALL_KEYS;
// if any trial variables are functions
// this evaluates the function and replaces

120
plugins/jspsych-video.js Normal file
View File

@ -0,0 +1,120 @@
/* jspsych-video.js
* Josh de Leeuw
*
* This plugin displays a video. The trial ends when the video finishes.
*
* documentation: docs.jspsych.org
*
*/
jsPsych.plugins.video = (function() {
var plugin = {};
plugin.info = {
name: 'video',
description: '',
parameters: {
sources: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
width: {
type: [jsPsych.plugins.parameterType.INT],
default: undefined,
no_function: false,
description: ''
},
height: {
type: [jsPsych.plugins.parameterType.INT],
default: undefined,
no_function: false,
description: ''
},
autoplay: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
controls: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// set default values for the parameters
trial.prompt = trial.prompt || "";
trial.autoplay = typeof trial.autoplay == 'undefined' ? true : trial.autoplay;
trial.controls = typeof trial.controls == 'undefined' ? false : trial.controls;
// if any trial variables are functions
// this evaluates the function and replaces
// it with the output of the function
trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);
// this array holds handlers from setTimeout calls
// that need to be cleared if the trial ends early
var setTimeoutHandlers = [];
// display stimulus
var video_html = '<video id="jspsych-video-player" width="'+trial.width+'" height="'+trial.height+'" '
if(trial.autoplay){
video_html += "autoplay "
}
if(trial.controls){
video_html +="controls "
}
video_html+=">"
for(var i=0; i<trial.sources.length; i++){
var s = trial.sources[i];
var type = s.substr(s.lastIndexOf('.') + 1);
type = type.toLowerCase();
video_html+='<source src="'+s+'" type="video/'+type+'">';
}
video_html +="</video>"
display_element.append(video_html);
//show prompt if there is one
if (trial.prompt !== "") {
display_element.append(trial.prompt);
}
document.getElementById('jspsych-video-player').onended = function(){
end_trial();
}
// function to end trial when it is time
var end_trial = function() {
// gather the data to store for the trial
var trial_data = {
stimulus: JSON.stringify(trial.sources)
};
// clear the display
display_element.html('');
// move on to the next trial
jsPsych.finishTrial(trial_data);
};
};
return plugin;
})();

View File

@ -22,28 +22,86 @@ jsPsych.plugins["visual-search-circle"] = (function() {
jsPsych.pluginAPI.registerPreload('visual-search-circle', 'foil', 'image');
jsPsych.pluginAPI.registerPreload('visual-search-circle', 'fixation_image', 'image');
plugin.create = function(params) {
var trials = new Array(params.target_present.length);
for (var i = 0; i < trials.length; i++) {
trials[i] = {};
trials[i].target_present = params.target_present[i];
trials[i].set_size = params.set_size[i];
trials[i].target = params.target;
trials[i].foil = params.foil;
trials[i].fixation_image = params.fixation_image;
trials[i].target_size = params.target_size || [50, 50];
trials[i].fixation_size = params.fixation_size || [16, 16];
trials[i].circle_diameter = params.circle_diameter || 250;
trials[i].target_present_key = params.target_present_key || 74;
trials[i].target_absent_key = params.target_absent_key || 70;
trials[i].timing_max_search = (typeof params.timing_max_search === 'undefined') ? -1 : params.timing_max_search;
trials[i].timing_fixation = (typeof params.timing_fixation === 'undefined') ? 1000 : params.timing_fixation;
plugin.info = {
name: 'visual-search-circle',
description: '',
parameters: {
target: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
foil: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
fixation_image: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
no_function: false,
description: ''
},
set_size: {
type: [jsPsych.plugins.parameterType.INT],
default: undefined,
no_function: false,
description: ''
},
target_present: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
target_size: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: 50,
no_function: false,
description: ''
},
fixation_size: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: 16,
no_function: false,
description: ''
},
circle_diameter: {
type: [jsPsych.plugins.parameterType.INT],
default: 250,
no_function: false,
description: ''
},
target_present_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'j',
no_function: false,
description: ''
},
target_absent_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'f',
no_function: false,
description: ''
},
timing_max_search: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_fixation: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
}
}
}
return trials;
};
plugin.trial = function(display_element, trial) {

View File

@ -7,7 +7,7 @@
*
* Josh de Leeuw
*
* documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-vsl-animate-occlusion
* documentation: docs.jspsych.org
*
*/
@ -17,6 +17,66 @@ jsPsych.plugins['vsl-animate-occlusion'] = (function() {
jsPsych.pluginAPI.registerPreload('vsl-animate-occlusion', 'stimuli', 'image');
plugin.info = {
name: 'vsl-animate-occlusion',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
default: undefined,
array: true,
no_function: false,
description: ''
},
choices: {
type: [jsPsych.plugins.parameterType.KEYCODE],
array: true,
default: jsPsych.ALL_KEYS,
no_function: false,
description: ''
},
canvas_size: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: [400,400],
no_function: false,
description: ''
},
image_size: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: [100,100],
no_function: false,
description: ''
},
initial_direction: {
type: [jsPsych.plugins.parameterType.SELECT],
choices: ['left','right'],
default: 'left',
no_function: false,
description: ''
},
occlude_center: {
type: [jsPsych.plugins.parameterType.BOOL],
default: true,
no_function: false,
description: ''
},
timing_cycle: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_pre_movement: {
type: [jsPsych.plugins.parameterType.INT],
default: 500,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default trial parameters
@ -25,7 +85,7 @@ jsPsych.plugins['vsl-animate-occlusion'] = (function() {
trial.image_size = trial.image_size || [100, 100];
trial.initial_direction = trial.initial_direction || "left";
trial.occlude_center = (typeof trial.occlude_center === 'undefined') ? true : trial.occlude_center;
trial.choices = trial.choices || [];
trial.choices = trial.choices || jsPsych.ALL_KEYS;
trial.timing_pre_movement = (typeof trial.timing_pre_movement === 'undefined') ? 500 : trial.timing_pre_movement;
// if any trial variables are functions

View File

@ -17,6 +17,33 @@ jsPsych.plugins['vsl-grid-scene'] = (function() {
jsPsych.pluginAPI.registerPreload('vsl-grid-scene', 'stimuli', 'image');
plugin.info = {
name: 'vsl-grid-scene',
description: '',
parameters: {
stimuli: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
image_size: {
type: [jsPsych.plugins.parameterType.INT],
array: true,
default: [100,100],
no_function: false,
description: ''
},
timing_duration: {
type: [jsPsych.plugins.parameterType.INT],
default: 2000,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {
// default parameter values

View File

@ -12,7 +12,69 @@ jsPsych.plugins.xab = (function() {
var plugin = {};
jsPsych.pluginAPI.registerPreload('xab', 'stimuli', 'image');
jsPsych.pluginAPI.registerPreload('xab', 'stimuli', 'image',function(t){ return !t.is_html || t.is_html == 'undefined'});
plugin.info = {
name: 'xab',
description: '',
parameters: {
stimulus: {
type: [jsPsych.plugins.parameterType.STRING],
array: true,
default: undefined,
no_function: false,
description: ''
},
is_html: {
type: [jsPsych.plugins.parameterType.BOOL],
default: false,
no_function: false,
description: ''
},
left_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'q',
no_function: false,
description: ''
},
right_key: {
type: [jsPsych.plugins.parameterType.KEYCODE],
default: 'p',
no_function: false,
description: ''
},
prompt: {
type: [jsPsych.plugins.parameterType.STRING],
default: '',
no_function: false,
description: ''
},
timing_x: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_xab_gap: {
type: [jsPsych.plugins.parameterType.INT],
default: 1000,
no_function: false,
description: ''
},
timing_ab: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
},
timing_response: {
type: [jsPsych.plugins.parameterType.INT],
default: -1,
no_function: false,
description: ''
}
}
}
plugin.trial = function(display_element, trial) {

View File

@ -0,0 +1,36 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var first = {
type: 'text',
text: 'first trial; new trial added when on_finish is called',
on_finish: function(){
jsPsych.pauseExperiment();
jsPsych.addNodeToEndOfTimeline({
timeline: [{
type: 'single-stim',
stimulus: 'img/happy_face_4.jpg'
}]
}, jsPsych.resumeExperiment)
}
}
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [first],
on_finish: function(){jsPsych.data.displayData(); }
});
</script>
</html>

View File

@ -0,0 +1,47 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
<style>
img {
width: 300px;
}
</style>
</head>
<body>
</body>
<script>
var trial_1 = {
stimulus: '<p>All keys</p>',
choices: jsPsych.ALL_KEYS
}
var trial_2 = {
stimulus: '<p>No keys</p>',
timing_response: 2000,
choices: jsPsych.NO_KEYS
}
var node = {
type: 'single-stim',
is_html: true,
timeline: [trial_1, trial_2],
}
jsPsych.init({
timeline: [node],
on_finish: function() {
jsPsych.data.displayData();
},
default_iti: 250
});
</script>
</html>

View File

@ -0,0 +1,39 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var if_trial = {
type: 'text',
text: 'The random number generated showed this trial. Press any key to continue.'
}
var if_node = {
timeline: [if_trial],
conditional_function: function(){
console.log('conditional function evaluated');
return false;
}
}
var after_if_trial = {
type: 'text',
text: 'This is the trial after the conditional.'
}
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [if_node, after_if_trial],
on_finish: function(){jsPsych.data.displayData(); }
});
</script>
</html>

View File

@ -0,0 +1,40 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
<style>
img {
width: 300px;
}
</style>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var block_1 = {
type: 'single-stim',
stimulus: 'img/happy_face_1.jpg',
choices: [89, 78], // Y or N
prompt: '<p class="center-content">Have you seen this face before? Y or N.</p>'
}
jsPsych.data.ignore(['stimulus']);
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block_1],
on_finish: function() {
jsPsych.data.ignore(['time_elapsed']);
// data should have a subject and completed field for each trial.
jsPsych.data.displayData();
}
});
</script>
</html>

View File

@ -0,0 +1,129 @@
<!doctype html>
<html>
<head>
<title>Flanker Task</title>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script>
<link rel="stylesheet" href="../css/jspsych.css">
</head>
<body>
</body>
<script>
/*set up welcome block*/
var welcome = {
type: "text",
text: "<p style='margin:20%'>Welcome to the experiment. Press any key to begin.</p>"
};
/*set up instructions block*/
var instructions = {
type: "text",
text: "<p style='margin-top:20%; margin-right:10%'>In this task you are required to respond to " +
"stimuli displayed on the screen. In the following, you will see five arrows. Your task " +
"is to decide as quickly as possible if the arrow in the middle is pointing in the same " +
"direction as the others or not. If this is the case ('<strong><<<<<</strong>' or " +
"'<strong>>>>>></strong>'), please press the left arrow button on the keyboard. If the " +
"middle arrow is pointing in the opposite direction ('<strong><<><<</strong>' or " +
"'<strong>>><>></strong>'), please press the right arrow button on the keyboard. You can " +
"start the experiment by pressing ENTER.</p>",
timing_post_trial: 3000
};
/*defining stimuli*/
var test_stimuli = [
{
stimulus: "img/con1.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/con2.png",
data: { phase: 'congruent'}
},
{
stimulus: "img/inc1.png",
data: { phase: 'incongruent'}
},
{
stimulus: "img/inc2.png",
data: { phase: 'incongruent'}
}
];
/*randomising stimuli*/
var all_trials = jsPsych.randomization.repeat(test_stimuli, 25);
/*creating random ISI*/
var post_trial_gap = function() {
return Math.floor(Math.random() * 1500) + 500;
};
/*defining experimental block*/
var test_block = {
type: 'single-stim',
choices: [37, 39],
timing_response: 1500,
on_finish: function(data){
var correct = false;
if(data.phase == 'congruent' && data.key_press == '37' && data.rt > -1){
correct = true;
} else if(data.phase == 'incongruent' && data.key_press == '39' && data.rt > -1){
correct = true;
}
jsPsych.data.addDataToLastTrial({correct: correct});
},
timeline: all_trials,
timing_post_trial: post_trial_gap
};
/*function for getting mean RTs and error rates*/
function getSubjectData() {
var trials = jsPsych.data.getTrialsOfType('single-stim');
var sum_rt = 0;
var correct_trial_count = 0;
var correct_rt_count = 0;
for (var i = 0; i < trials.length; i++) {
if (trials[i].correct == true) {
correct_trial_count++;
if(trials[i].rt > -1){
sum_rt += trials[i].rt;
correct_rt_count++;
}
}
}
return {
rt: Math.floor(sum_rt / correct_rt_count),
accuracy: Math.floor(correct_trial_count / trials.length * 100)
}
};
/*defining debriefing block*/
var debrief_block = {
type: "text",
text: function() {
var subject_data = getSubjectData();
return "<p style='margin:20%'>You responded correctly on "+subject_data.accuracy+"% of the trials. " +
"Your average response time was <strong>" + subject_data.rt + "ms</strong>. Press any key to complete the "+
"experiment. Thank you!</p>";
}
};
/*set up experiment structure*/
var timeline = [];
timeline.push(welcome);
timeline.push(instructions);
timeline.push(test_block);
timeline.push(debrief_block);
/*start experiment*/
jsPsych.init({
timeline: timeline,
on_finish: function() {
jsPsych.data.displayData();
}
});
</script>
</html>

View File

@ -0,0 +1,31 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var block_1 = {
type: 'text',
text: 'This trial should display. Click to continue.',
cont_key: 'mouse'
}
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [block_1],
fullscreen: true,
on_finish: function() {
jsPsych.data.displayData();
}
});
</script>
</html>

BIN
tests&examples/img/con1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
tests&examples/img/con2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
tests&examples/img/inc1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
tests&examples/img/inc2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -22,7 +22,8 @@
timeline: [
{stimulus: 'sound/sound.mp3'},
{stimulus: 'sound/hammer.mp3'}
]
],
prompt: 'press any key to advance'
}
jsPsych.init({

View File

@ -14,7 +14,6 @@
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var trial_1 = {
@ -42,7 +41,6 @@
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [node],
on_finish: function() {
jsPsych.data.displayData();

View File

@ -2,14 +2,12 @@
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-survey-likert.js"></script>
<link rel="stylesheet" href="css/jquery-ui.css"></link>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
<div id="jspsych-target" class="jspsych-top"></div>
</body>
<script>

View File

@ -2,10 +2,8 @@
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-survey-text.js"></script>
<link rel="stylesheet" href="css/jquery-ui.css"></link>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>

View File

@ -0,0 +1,26 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-video.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var trial = {
type: 'video',
sources: ['video/sample_video.mp4']
}
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [trial],
on_finish: function() { jsPsych.data.displayData(); }
});
</script>
</html>

View File

@ -0,0 +1,36 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-text.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var first = {
type: 'text',
text: 'first trial!',
timing_post_trial: 0,
on_finish: function(){
jsPsych.pauseExperiment();
setTimeout(jsPsych.resumeExperiment, 4000);
}
}
var second = {
type: 'text',
text: 'second trial!'
}
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [first, second],
on_finish: function(){jsPsych.data.displayData(); }
});
</script>
</html>

View File

@ -26,5 +26,12 @@
var no_neighbor_repeats = jsPsych.randomization.shuffleNoRepeats(repeated_list);
console.log(JSON.stringify(no_neighbor_repeats));
// check to make sure everything is deep copy
var arr = [];
for(i=0;i<5;i++){arr.push({i:i})};
var arr = jsPsych.randomization.repeat(arr,4);
for(j=0;j<arr.length;j++){arr[j].j=j};
console.log(JSON.stringify(arr))
</script>
</html>

View File

@ -0,0 +1,60 @@
<!doctype html>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="../jspsych.js"></script>
<script src="../plugins/jspsych-single-stim.js"></script>
<script src="../plugins/jspsych-single-audio.js"></script>
<link rel="stylesheet" href="../css/jspsych.css"></link>
<style>
img {
width: 300px;
}
</style>
</head>
<body>
<div id="jspsych-target"></div>
</body>
<script>
var timeline_variables = [
{ v1: 'sound/sound.mp3', v2: 'Person A' },
{ v1: 'sound/hammer.mp3', v2: 'Person B' }
];
var node = {
timeline_variables: timeline_variables,
timeline: [
{
type: 'single-stim',
choices: ['none'], // Y or N
stimulus: "<p style='text-align:center; font-size:80px;'>+</p>",
timing_response: 500,
is_html: true
},
{
type: 'single-audio',
choices: [89, 78], // Y or N
stimulus: function() { return jsPsych.timelineVariable('v1'); },
prompt: function() { return '<p class="center-content">Have you seen '+jsPsych.timelineVariable('v2')+ ' before? Y or N.</p>' }
}
],
randomize_order: true,
repetitions: 2
}
jsPsych.pluginAPI.preloadAudioFiles(['sound/sound.mp3','sound/hammer.mp3'], function() {
jsPsych.init({
display_element: $('#jspsych-target'),
timeline: [node],
on_finish: function() {
jsPsych.data.displayData();
},
default_iti: 250
});
});
</script>
</html>

Binary file not shown.