Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add plugin-image-click-response #140

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions package-lock.json

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

35 changes: 35 additions & 0 deletions packages/plugin-image-click-response/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# image-click-response

## Overview

This plugin shows an image on which the user can place points by clicking/touching the image. The location of each point is recorded as data.

## Loading

### In browser

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

### Via NPM

```
npm install @jspsych-contrib/plugin-image-click-response
```

```js
import jsPsychImageClickResponse from '@jspsych-contrib/plugin-image-click-response';
```

## Compatibility

jsPsych 7.0.0

## Documentation

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

## Author / Citation

[Christophe Bossens](https://github.com/ChristopheBossens)
64 changes: 64 additions & 0 deletions packages/plugin-image-click-response/docs/image-click-response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# image-click-response

This plugin shows an image on which the user can place points by clicking/touching the image. The x,y coordinates for each point are recorderd.

## Parameters

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

| Parameter | Type | Default Value | Description |
| ------------------- | ---------------- | ------------------ | ---------------------------------------- |
| preamble | HTML_STRING | <p>Click the image to add a point. Click a point to remove<p> | Instruction text that will appear above the image |
| stimulus |IMAGE | undefined | URL to the image that will be displayed|
| dot_radius | INT | 5| Radius of the dot in pixels|
| dot_color | STRING | lightblue| Color name for the dot|
| button_label | STRING | Continue| Label for the continue button |
| minimum_dots_required | INT | 0| Minimum number of dots required before the Continue button becomes active|

## Data Generated

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

| Name | Type | Value |
| --------- | ------- | ---------------------------------------- |
| stimulus | IMAGE | URL to the image that will be displayed |
| rt | INT | Time in milliseconds to compete the trial |
| points | ARRAY | Array of (x,y) coordinates for each point on the image |

## Install

Using the CDN-hosted JavaScript file:

```js
<script src="https://unpkg.com/@jspsych-contrib/plugin-image-click-response"></script>
```

Using the JavaScript file downloaded from a GitHub release dist archive:

```js
<script src="jspsych/plugin-image-click-response.js"></script>
```

Using NPM:

```
npm install @jspsych-contrib/plugin-image-click-response
```

```js
import ImageClickResponse from '@jspsych-contrib/plugin-image-click-response';
```

## Examples

### Title of Example

```javascript
const trial = {
type: jsPsychImageClickResponse,
stimulus: "https://www.jspsych.org/7.3/img/jspsych-logo.jpg",
dot_radius : 10
};
```

See [example #1](../examples/index.html) for a live demonstration.
25 changes: 25 additions & 0 deletions packages/plugin-image-click-response/examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>

<head>
<script src="https://unpkg.com/jspsych"></script>
<!-- The plugin is loaded here -->
<script src="https://unpkg.com/@jspsych/plugin-image-click-response"></script>
<script src="../dist/index.browser.js"></script>
<link rel="stylesheet" href="https://unpkg.com/jspsych/css/jspsych.css">
</head>

<body></body>
<script>
const jsPsych = initJsPsych();

const trial = {
type: jsPsychImageClickResponse,
stimulus: "https://www.jspsych.org/7.3/img/jspsych-logo.jpg",
dot_radius : 10
};

jsPsych.run([trial])
</script>

</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/plugin-image-click-response/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@jspsych/config/jest").makePackageConfig(__dirname);
47 changes: 47 additions & 0 deletions packages/plugin-image-click-response/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@jspsych-contrib/plugin-image-click-response",
"version": "0.0.1",
"description": "This plugin shows an image on which the user can place points by clicking/touching the image. The location of each point is recorded as data.",
"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-image-click-response"
},
"author": {
"name": "Christophe Bossens",
"url": "https://github.com/ChristopheBossens"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/jspsych/jspsych-contrib/issues"
},
"homepage": "https://github.com/jspsych/jspsych-contrib/tree/main/packages/plugin-image-click-response",
"peerDependencies": {
"jspsych": ">=7.0.0"
},
"devDependencies": {
"@jspsych/config": "^2.0.0",
"@jspsych/test-utils": "^1.0.0",
"jspsych": "^7.0.0"
}
}
3 changes: 3 additions & 0 deletions packages/plugin-image-click-response/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("jsPsychImageClickResponse");
106 changes: 106 additions & 0 deletions packages/plugin-image-click-response/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { clickTarget, startTimeline } from "@jspsych/test-utils";

import jsPsychImageClickResponse from ".";

jest.useFakeTimers();

describe("imag-click-response", () => {
it("should load", async () => {
const { expectFinished, getHTML, getData, displayElement, jsPsych } = await startTimeline([
{
type: jsPsychImageClickResponse,
stimulus: "image.jpg",
dot_radius: 6,
dot_color: "blue",
minimum_dots_required: 1,
},
]);
});

it("correctly configures layout parameters", async () => {
const stimulus_value = "../examples/jspsych-logo.jpg";
const button_label_value = "random label";

const { expectRunning, getHTML } = await startTimeline([
{
type: jsPsychImageClickResponse,
stimulus: stimulus_value,
button_label: button_label_value,
},
]);

await expectRunning();

const html = getHTML().replace(/"/g, "'");

expect(html).toContain(`href='${stimulus_value}'`);
expect(html).toContain(button_label_value);
});

it("correctly sets the continue button state when the minimum_dots_required parameter is > 0", async () => {
const minimum_dots_required = 1;

const { expectRunning, getHTML, getData, displayElement, jsPsych } = await startTimeline([
{
type: jsPsychImageClickResponse,
stimulus: "image.jpg",
minimum_dots_required: 1,
},
]);

const response_button = displayElement.querySelector(
"#image-click-response-button"
) as HTMLButtonElement;
const svg_container = document.getElementById("image-click-response-svg") as HTMLElement;

await expectRunning();

expect(response_button.disabled).toBe(true);
await clickTarget(svg_container);

expect(response_button.disabled).toBe(false);
});

it("should end the trial when the button is clicked", async () => {
const { expectRunning, getHTML, expectFinished, getData, displayElement, jsPsych } =
await startTimeline([
{
type: jsPsychImageClickResponse,
stimulus: "image.jpg",
},
]);

const response_button = displayElement.querySelector(
"#image-click-response-button"
) as HTMLButtonElement;
await clickTarget(response_button);

await expectFinished();
});

it("should add (x,y) coordinates to the data structure when the image is clicked", async () => {
const { expectRunning, getHTML, expectFinished, getData, displayElement, jsPsych } =
await startTimeline([
{
type: jsPsychImageClickResponse,
stimulus: "image.jpg",
},
]);

const response_button = displayElement.querySelector(
"#image-click-response-button"
) as HTMLButtonElement;
const svg_container = document.getElementById("image-click-response-svg") as HTMLElement;

await clickTarget(svg_container);
await clickTarget(response_button);

await expectFinished();

const data = getData().values()[0];
console.log(data);
expect(data).toHaveProperty("points");
expect(data.points.length).toBe(1);
expect(data.points[0].length).toBe(2);
});
});
Loading