diff --git a/components/boundingNew.js b/components/boundingNew.js index ea671538..48c4d62f 100644 --- a/components/boundingNew.js +++ b/components/boundingNew.js @@ -324,6 +324,7 @@ export const restrictLevelBeforeFixation = ( fontCharacterSet, spacingDirection = "horizontal", targetSizeIsHeightBool = false, + letterCharacters, ) => { const quickCase = getQuickCase( targetTask, @@ -347,10 +348,20 @@ export const restrictLevelBeforeFixation = ( targetString = sampleWithoutReplacement(fontCharacterSet, 1)[0]; characterSet = targetString; } else if (quickCase === "typographicCrowding") { - [targetString, flanker1String, flanker2String] = sampleWithoutReplacement( - fontCharacterSet, - 3, - ); + const { target, flanker1, flanker2 } = letterCharacters ?? {}; + const selectedCharacters = [target, flanker1, flanker2]; + if ( + selectedCharacters.some( + (character) => typeof character !== "string" || character.length === 0, + ) + ) { + throw new Error( + "Typographic crowding requires a selected target and two flankers.", + ); + } + targetString = target; + flanker1String = flanker1; + flanker2String = flanker2; characterSet = [flanker1String, targetString, flanker2String]; } else if (quickCase === "ratioCrowding") { switch (spacingDirection) { diff --git a/components/stimulusGeneration.ts b/components/stimulusGeneration.ts index 013f416c..e50fa44e 100644 --- a/components/stimulusGeneration.ts +++ b/components/stimulusGeneration.ts @@ -28,6 +28,7 @@ import type { RsvpReadingStimulusResults, VernierStimulusResults, TextStimsLetter, + CharactersLetter, } from "./stimulus"; import { rc, viewingDistanceCm } from "./global"; import { Screens } from "./multiple-displays/globals"; @@ -127,7 +128,7 @@ const getLettersStimulus = ( reader, extraInfo.characterSetBoundingRect, extraInfo.stage as PartOfTrial, - extraInfo.characters.target, + extraInfo.characters, extraInfo.proposedLevel, )); } @@ -272,13 +273,14 @@ const getLettersStimulusV2 = ( reader: ParamReader, characterSetBoundingRectOld: any, stage: PartOfTrial, - targetCharacter?: string, + letterCharacters: CharactersLetter, proposedLevel?: number, ): { level: number; stimulusParameters: any; characterSetBoundingRect: any; } => { + const targetCharacter = letterCharacters.target; if (stage === "afterFixation" && !(targetCharacter && proposedLevel)) { throw new Error( `targetCharacter (${targetCharacter}) and proposedLevel (${proposedLevel}) must be provided for afterFixation letter stimulus generation.`, @@ -304,6 +306,7 @@ const getLettersStimulusV2 = ( String(reader.read("fontCharacterSet", block_condition)).split(""), reader.read("spacingDirection", block_condition), reader.read("targetSizeIsHeightBool", block_condition), + letterCharacters, ); } else if (stage === "afterFixation") { [level, stimulusParameters] = restrictLevelAfterFixation(