Skip to content

Commit

Permalink
Merge pull request #66 from jspsych/plugin-corsi-blocks
Browse files Browse the repository at this point in the history
Add Corsi blocks task plugin
  • Loading branch information
jodeleeuw authored Mar 7, 2023
2 parents 2407687 + 484477b commit cd32dae
Show file tree
Hide file tree
Showing 12 changed files with 583 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/rare-dolphins-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@jspsych-contrib/plugin-corsi-blocks": major
---

Initial release of Corsi block plugin. This plugin can show a configurable display of blocks, highlight them in a specified sequence, and record a sequence of clicks by the user.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Plugin/Extension | Contributor | Description
----------- | ----------- | -----------
[audio-multi-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-audio-multi-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an audio file using both button clicks and key presses.
[audio-swipe-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-audio-swipe-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an audio file using swipe gestures and keyboard responses.
[corsi-blocks](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-corsi-blocks/README.md) | [Josh de Leeuw](https://github.com/jodeleeuw) | This plugin displays a configurable Corsi blocks task and records a series of click responses.
[html-multi-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-html-multi-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an arbitrary HTML string using both button clicks and key presses.
[html-swipe-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-html-swipe-response/README.md) | [Adam Richie-Halford](https://github.com/richford) | This plugin collects responses to an arbitrary HTML string using swipe gestures and keyboard responses.
[html-vas-response](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-html-vas-response/README.md) | [Isaac Kinley](https://github.com/kinleyid) | This plugin collects responses to an arbitrary HTML string using a point-and-click visual analogue scale.
Expand Down
34 changes: 31 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions packages/plugin-corsi-blocks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# corsi-blocks

## Overview

This plugin implements the Corsi block tapping task. It has two modes: a display mode and an input mode. In the display mode, the participant is shown a sequence of blocks. In the input mode, the participant is shown a sequence of blocks and must tap the blocks in the same order. Feedback can be provided after each responses. The number and arrangement of the blocks can be customized.

## Loading

### In browser

```js
<script src="https://unpkg.com/@jspsych-contrib/[email protected]">
```

### Via NPM

```
npm install @jspsych-contrib/plugin-corsi-blocks
```

```js
import jsPsychCorsiBlocks from '@jspsych-contrib/plugin-corsi-blocks';
```

## Compatibility

jsPsych 7.3.2.

(Earlier versions of jsPsych version 7 will work if you explicitly set the `blocks` parameter in a trial. Using the default `blocks` parameter requires `7.3.2` or later.)

## Documentation

See [documentation](https://github.com/jspsych/jspsych-contrib/blob/main/packages/plugin-corsi-blocks/docs/jspsych-corsi-blocks.md)

## Author / Citation

Josh de Leeuw
55 changes: 55 additions & 0 deletions packages/plugin-corsi-blocks/docs/jspsych-corsi-blocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# jspsych-corsi-blocks plugin

This plugin displays a sequence of blocks and then gets the subject's response. The sequence can be displayed in either 'display' mode or 'input' mode. In 'display' mode, the sequence is displayed and the trial ends after the sequence is complete. In 'input' mode, the subject must click on the blocks in the correct order.

## Parameters

In addition to the [parameters available in all plugins](https://www.jspsych.org/overview/plugins#parameters-available-in-all-plugins), this plugin accepts the following parameters. Parameters with a default value of *undefined* must be specified. Parameters can be left unspecified if the default value is acceptable.

| Parameter | Type | Default Value | Description |
| ----------|------|---------------|------------ |
| sequence | array | undefined | An array of block indexes that specify the order of the sequence to be displayed. For example, `[0, 1, 2, 3, 4]` would display the first 5 blocks in the order they appear in the blocks parameter. |
| blocks | array | See description | An array of objects that specify the x and y coordinates of each block. The coordinates represent the center of the block. The coordinates are specified as percentages of the width and height of the display. For example, `{x: 50, y: 50}` would place the block in the center of the display. The default value is an array of nine blocks that approximates the layout of the original Corsi blocks task. |
| block_size | int | 12 | The size of the blocks as a percentage of the overall display size. |
| display_width | string | "400px" | The width of the display, specified as a valid CSS measurement. |
| display_height | string | "400px" | The height of the display, specified as a valid CSS measurement. |
| prompt | string | null | An optional text prompt that can be shown below the display area. |
| mode | string | "display" | The mode of the trial. If 'display', then the sequence is displayed and the trial ends after the sequence is complete. If 'input', then the use must click on the blocks in the correct order.
| sequence_gap_duration | int | 250 | The duration, in milliseconds, between each block in the sequence |
| sequence_block_duration | int | 1000 | The duration, in milliseconds, that each block is displayed in the sequence |
| pre_stim_duration | int | 500 | The duration, in milliseconds, to show the blocks before the sequence begins. |
| response_animation_duration | int | 500 | The duration, in milliseconds, to show the feedback response animation during input mode. |
| block_color | string | "#555" | The color of unselected, unhighlighted blocks. |
| highlight_color | string | "#f00" | The color of the highlighted block. |
| correct_color | string | "#0f0" | The color of correct feedback. |
| incorrect_color | string | "#f00" | The color of incorrect feedback. |

## Data Generated

In addition to the [default data collected by all plugins](../overview/plugins.md#data-collected-by-all-plugins), this plugin collects the following data for each trial.

| Name | Type | Value |
| --------- | ------- | ---------------------------------------- |
| sequence | array | The sequence of block indexes that was displayed. |
| response | array | The sequence of block indexes that was selected by the subject. |
| correct | boolean | Whether the subject's response was correct. |
| rt | array | The time, in milliseconds, that the subject took to respond to each block. These times are cumulative, measured from the onset of the display. |
| blocks | array | The coordinates of the blocks that were displayed. |

## Examples

### Displaying a two-item sequence and then getting the subject's response.

```javascript
const show_sequence = {
type: jsPsychCorsiBlocks,
sequence: [3,1],
mode: 'display'
}

const response = {
type: jsPsychCorsiBlocks,
sequence: [3,1],
mode: 'input'
}
```
44 changes: 44 additions & 0 deletions packages/plugin-corsi-blocks/examples/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]"></script>
<script src="../dist/index.browser.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/jspsych.css" />
</head>
<body></body>
<script>
const jsPsych = initJsPsych({
on_finish: function() {
jsPsych.data.displayData();
}
});

const corsi_original_config = [
{y: 80, x: 45},
{y: 85, x: 80},
{y: 70, x: 20},
{y: 60, x: 70},
{y: 50, x: 35},
{y: 40, x: 15},
{y: 45, x: 90},
{y: 35, x: 60},
{y: 25, x: 47}
];

const timeline = [];

timeline.push({
type: jsPsychCorsiBlocks,
sequence: [3,1],
mode: 'display'
});

timeline.push({
type: jsPsychCorsiBlocks,
sequence: [3,1],
mode: 'input'
});

jsPsych.run(timeline);
</script>
</html>
1 change: 1 addition & 0 deletions packages/plugin-corsi-blocks/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);
44 changes: 44 additions & 0 deletions packages/plugin-corsi-blocks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@jspsych-contrib/plugin-corsi-blocks",
"version": "0.1.0",
"description": "Corsi blocks task plugin for jsPsych",
"type": "module",
"main": "dist/index.cjs",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"typings": "dist/index.d.ts",
"unpkg": "dist/index.browser.min.js",
"files": [
"src",
"dist"
],
"source": "src/index.ts",
"scripts": {
"test": "jest",
"test:watch": "npm test -- --watch",
"tsc": "tsc",
"build": "rollup --config",
"build:watch": "npm run build -- --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jspsych/jspsych-contrib.git",
"directory": "packages/plugin-corsi-blocks"
},
"author": "Josh de Leeuw",
"license": "MIT",
"bugs": {
"url": "https://github.com/jspsych/jspsych-contrib/issues"
},
"homepage": "https://github.com/jspsych/jspsych-contrib/tree/main/packages/plugin-corsi-blocks",
"peerDependencies": {
"jspsych": ">=7.3.2"
},
"devDependencies": {
"@jspsych/config": "^1.0.0",
"@jspsych/test-utils": "^1.0.0",
"jspsych": "^7.3.2"
}
}
3 changes: 3 additions & 0 deletions packages/plugin-corsi-blocks/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { makeRollupConfig } from "@jspsych/config/rollup";

export default makeRollupConfig("jsPsychCorsiBlocks");
35 changes: 35 additions & 0 deletions packages/plugin-corsi-blocks/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { startTimeline } from "@jspsych/test-utils";

import jsPsychCorsiBlocks from ".";

jest.useFakeTimers();

describe("corsi-blocks plugin", () => {
it("should load", async () => {
const { expectFinished, getHTML, getData, displayElement, jsPsych } = await startTimeline([
{
type: jsPsychCorsiBlocks,
sequence: [0, 1, 2],
blocks: [
{ x: 10, y: 10 },
{ x: 20, y: 20 },
{ x: 30, y: 30 },
],
},
]);

await jest.runAllTimers();

await expectFinished();
});
it("should work with default blocks", async () => {
const { expectFinished, getHTML, getData, displayElement, jsPsych } = await startTimeline([
{
type: jsPsychCorsiBlocks,
sequence: [0, 1, 2],
},
]);
await jest.runAllTimers();
await expectFinished();
});
});
Loading

0 comments on commit cd32dae

Please sign in to comment.