psychopy.org | Reference | Downloads | Github

How to loop over stimuli in PsychoJS

URL of experiment: pilot link: https://run.pavlovia.org/michele_conni/trial/html/
code: https://gitlab.pavlovia.org/michele_conni/trial

Description of the problem: I want to run a loop in which the observer selects some images with her/his mouse, and as she/he does that, the opacity of the selected image shifts from 1.0 to 0.3. After each repetition, however, this should reset, as the images are shuffled and reselected from a wide database.
In PsychoPy this isn’t really a problem: I successfully implemented this for each image stimulus (image1, image2 etc.) with:

for loc in [image1, image2, image3, image4]:
    if mouse_1.isPressedIn(loc):
        loc.setOpacity(.3)

for each frame, and something similar (without the if) can be set up at the end of the routine to reset the opacity to 1.
In Javascript, this can be done by explicitly, stimulus by stimulus, with:

if (image1.contains(mouse_1) && mouse_1.getPressed()[0] === 1) {
    image1.setOpacity(0.3);
    }

However, it seems impossible that there is no standard way to loop over all the stimuli without having to repeat the code for each one of them. I tried in various ways, by defining the array

imgStimuli = [image1, image2, image3, image4];

both at the begin of the routine and for each frame, but it doesn’t work.

Do you have any suggestion on how to do it? Thank you in advance.

I managed to get the following working:

In Begin Experiment I have

for Idx in range (9):
    bars.append(visual.ImageStim(
    win=win,
    name='ladder', 
    image='ladder.png', ori=0, pos=[0,(Idx-4)*scale+voffset], size=[scale*dtarget*28.72,scale*dtarget],
    color=white, colorSpace='rgb', opacity=1,
    flipHoriz=False, flipVert=False,
    texRes=128, interpolate=True)
    )

This will auto-translate, but you need to change .append to .push

Then in Begin Routine I have

if  conditions[trials.thisN] == 3:
    dflanker = 1
    nflankers = 50
    for Idx in range(9):
        bars[Idx].setAutoDraw(True)

Best wishes,

Wakefield

@michele_conni, the equivalent for loop in JS is:

imgStimuli = [image1, image2, image3, image4];

for ( let i=0; i<imgStimuli.length; i+=1; ) {
  if (imgStimuli[i].contains(mouse_1) && mouse_1.getPressed()[0] === 1) {
    imgStimuli[i].setOpacity(0.3);
  }
}

The more readable version (and more like Python):

imgStimuli = [image1, image2, image3, image4];

for (let im of imgStimuli) {
  if (im.contains(mouse_1) && mouse_1.getPressed()[0] === 1) {
    im.setOpacity(0.3);
  }
}