From 8759217f0ef0c1d127ca58440d1cbe5f152dbde5 Mon Sep 17 00:00:00 2001 From: Josh de Leeuw Date: Tue, 6 Dec 2022 17:07:20 -0500 Subject: [PATCH 1/2] Add options (`randomize_item_locations` and `location_first_item`) to allow for fixed locations of the item array across trials. --- .changeset/nervous-carrots-raise.md | 5 +++++ docs/plugins/visual-search-circle.md | 2 ++ .../plugin-visual-search-circle/src/index.ts | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 .changeset/nervous-carrots-raise.md diff --git a/.changeset/nervous-carrots-raise.md b/.changeset/nervous-carrots-raise.md new file mode 100644 index 0000000000..e1c978d548 --- /dev/null +++ b/.changeset/nervous-carrots-raise.md @@ -0,0 +1,5 @@ +--- +"@jspsych/plugin-visual-search-circle": minor +--- + +Add options (`randomize_item_locations` and `location_first_item`) to allow for fixed locations of the item array across trials. diff --git a/docs/plugins/visual-search-circle.md b/docs/plugins/visual-search-circle.md index c6af9959a5..58458600b3 100644 --- a/docs/plugins/visual-search-circle.md +++ b/docs/plugins/visual-search-circle.md @@ -32,6 +32,8 @@ The `target_present` and `fixation_image` parameters must always be specified. O | target_absent_key | string | 'f' | The key to press if the target is not present in the search array. | | trial_duration | numeric | null | The maximum amount of time the participant is allowed to search before the trial will continue. A value of null will allow the participant to search indefinitely. | | fixation_duration | numeric | 1000 | How long to show the fixation image for before the search array (in milliseconds). | +| randomize_item_locations | bool | true | Whether to use randomized locations on the circle for the items. If `false`, then the first item will always show at the location specified by `location_first_item`. +| location_first_item | numeric | 0 | If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. ## Data Generated diff --git a/packages/plugin-visual-search-circle/src/index.ts b/packages/plugin-visual-search-circle/src/index.ts index 1232970d03..91803e4c57 100644 --- a/packages/plugin-visual-search-circle/src/index.ts +++ b/packages/plugin-visual-search-circle/src/index.ts @@ -89,6 +89,18 @@ const info = { pretty_name: "Fixation duration", default: 1000, }, + /** Whether to use randomized locations on the circle for the items. If `false`, then the first item will always show at the location specified by `location_first_item`. */ + randomize_item_locations: { + type: ParameterType.BOOL, + pretty_name: "Randomize item locations", + default: true, + }, + /** If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. */ + location_first_item: { + type: ParameterType.INT, + pretty_name: "Location first item", + default: 0, + }, }, }; @@ -263,10 +275,11 @@ class VisualSearchCirclePlugin implements JsPsychPlugin { var display_locs = []; var random_offset = Math.floor(Math.random() * 360); + var offset = trial.randomize_item_locations ? random_offset : trial.location_first_item; for (var i = 0; i < n_locs; i++) { display_locs.push([ - Math.floor(paper_size / 2 + this.cosd(random_offset + i * (360 / n_locs)) * radi - hstimw), - Math.floor(paper_size / 2 - this.sind(random_offset + i * (360 / n_locs)) * radi - hstimh), + Math.floor(paper_size / 2 + this.cosd(offset + i * (360 / n_locs)) * radi - hstimw), + Math.floor(paper_size / 2 - this.sind(offset + i * (360 / n_locs)) * radi - hstimh), ]); } return display_locs; From 4723f57eac01ad668df610a78bc464c591e919a5 Mon Sep 17 00:00:00 2001 From: jade <101148768+jadeddelta@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:01:57 -0500 Subject: [PATCH 2/2] clarify location_first_item direction, add example --- docs/plugins/visual-search-circle.md | 2 +- examples/jspsych-visual-search-circle.html | 16 ++++++++++++++-- .../plugin-visual-search-circle/src/index.ts | 16 ++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/docs/plugins/visual-search-circle.md b/docs/plugins/visual-search-circle.md index 326a4f8637..b78b7bf4bf 100644 --- a/docs/plugins/visual-search-circle.md +++ b/docs/plugins/visual-search-circle.md @@ -33,7 +33,7 @@ The `target_present` and `fixation_image` parameters must always be specified. O | trial_duration | numeric | null | The maximum amount of time the participant is allowed to search before the trial will continue. A value of null will allow the participant to search indefinitely. | | fixation_duration | numeric | 1000 | How long to show the fixation image for before the search array (in milliseconds). | | randomize_item_locations | bool | true | Whether to use randomized locations on the circle for the items. If `false`, then the first item will always show at the location specified by `location_first_item`. -| location_first_item | numeric | 0 | If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. +| location_first_item | numeric | 0 | If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. 0 degrees is above the fixation, and moving clockwise in the positive direction. | response_ends_trial| boolean | true | If true, the trial will end when the participant makes a response. | ## Data Generated diff --git a/examples/jspsych-visual-search-circle.html b/examples/jspsych-visual-search-circle.html index 8e26b33389..25e060abeb 100644 --- a/examples/jspsych-visual-search-circle.html +++ b/examples/jspsych-visual-search-circle.html @@ -51,15 +51,27 @@ timeline: [trial_1, trial_2, trial_3] }; - // example using arbitrary image array + // example putting the first location at 90 degrees (right of the fixation) var trial_4 = { + type: jsPsychVisualSearchCircle, + target: 'img/backwardN.gif', + foil: 'img/normalN.gif', + fixation_image: 'img/fixation.gif', + target_present: true, + set_size: 3, + randomize_item_locations: false, + location_first_item: 90 + }; + + // example using arbitrary image array + var trial_5 = { type: jsPsychVisualSearchCircle, stimuli: ['img/backwardN.gif', 'img/normalN.gif', 'img/1.gif', 'img/2.gif', 'img/3.gif'], fixation_image: 'img/fixation.gif', target_present: true }; - jsPsych.run([preload_images, intro, trials, trial_4]); + jsPsych.run([preload_images, intro, trials, trial_4, trial_5]); diff --git a/packages/plugin-visual-search-circle/src/index.ts b/packages/plugin-visual-search-circle/src/index.ts index ba2ea8c8a8..09c06ea6b7 100644 --- a/packages/plugin-visual-search-circle/src/index.ts +++ b/packages/plugin-visual-search-circle/src/index.ts @@ -106,7 +106,10 @@ const info = { pretty_name: "Randomize item locations", default: true, }, - /** If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. */ + /** + * If `randomize_item_locations` is `false`, the location of the first item on the circle, in degrees. + * 0 degrees is above the fixation, and moving clockwise in the positive direction. + */ location_first_item: { type: ParameterType.INT, pretty_name: "Location first item", @@ -152,7 +155,7 @@ type Info = typeof info; /** * This plugin presents a customizable visual-search task modelled after [Wang, Cavanagh, & Green (1994)](http://dx.doi.org/10.3758/BF03206946). * The participant 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. Here is an example using normal and backward Ns: + * equidistant from a fixation point. * * @author Josh de Leeuw * @see {@link https://www.jspsych.org/latest/plugins/visual-search-circle/ visual-search-circle plugin documentation on jspsych.org} @@ -287,10 +290,6 @@ class VisualSearchCirclePlugin implements JsPsychPlugin { end_trial(); }, trial.trial_duration); } - - function clear_display() { - display_element.innerHTML = ""; - } }; } @@ -315,8 +314,9 @@ class VisualSearchCirclePlugin implements JsPsychPlugin { var hstimw = stimw / 2; var display_locs = []; - var random_offset = Math.floor(Math.random() * 360); - var offset = trial.randomize_item_locations ? random_offset : trial.location_first_item; + var offset = trial.randomize_item_locations + ? Math.floor(Math.random() * 360) + : trial.location_first_item - 180; // makes it so 0 is up, moving clockwise for (var i = 0; i < n_locs; i++) { display_locs.push([ Math.floor(paper_size / 2 + this.cosd(offset + i * (360 / n_locs)) * radi - hstimw),