Hi! I am new to Psychopy. I am creating an updating task in which participants have to click with the mouse on polygons. I want them to change color when pressed. How can I do it by using the Builder view? Thank you so much:)
Hi There,
You want to use a code component. In the begin routine tab list your polygons:
polygons = [polygon, polygon_1]
then on every frame check if the mouse is pressed in the polygon:
for thisPolygon in polygons:
if mouse.isPressedIn(thisPolygon):
thisPolygon.color = 'red'
Here is a demo file. polyChangeCol.psyexp (10.9 KB)
Hope this helps,
Becca
PS. I donât know if you want to take that online, but just incase, it will need a slight edit in the code component (change code type to âbothâ, on the right hand side change color to fillColor, since âcolorâ is âfillColorâ in psychoJS JSDoc: Class: Polygon)
Thank you so much, it works!
And if I want to let participants press againg on the polygon to make it return to the previous color? Is it possible?
Sure, you just need to add another âifâ statement (beware on indentation!), for example:
for thisPolygon in polygons:
if mouse.isPressedIn(thisPolygon):
if thisPolygon.color == 'red':
thisPolygon.color = 'blue'
else:
thisPolygon.color = 'red'
Hi There,
I think the initial reason this wouldnât work is because the first âifâ statement would need a double == to test for equality (rather than assign a variable). (i.e. if thisPolygon.color == white:
)
However, this is a little tricker because the âisPressedInâ method will check for mouse presses every time your screen refreshes (16.66 ms on a 60Hz monitor). So, if the participant continues to hold the mouse the polygon will appear to flicker (as it transitions from one colour to the other very quickly).
A work around for this it to add a time window in which you will register ânewâ clicks.
So, in your âbegin routineâ you would use something like:
polygons = [polygon, polygon_2]
bufferTime=.2
clickClock=core.Clock()
lastClickTime = 0
Then in your each frame you would use something like:
for thisPolygon in polygons:
if mouse.isPressedIn(thisPolygon):
thisClickTime = clickClock.getTime()
if (thisClickTime - lastClickTime) > bufferTime:
if thisPolygon.fillColor =='red':
thisPolygon.fillColor = 'white'
else:
thisPolygon.fillColor = 'red'
lastClickTime = thisClickTime
This will only register clicks seperated by 200ms as ânewâ clicks, and avoid the flicker effect. Here is an updated demo file polyChangeCol.psyexp (12.1 KB)
Hope this helps,
Becca
PS. I noticed that the color attribute has actually been changed to fillColor in the recent release (probably to be consistent with PsychoJS - so updated accordingly)
It works perfectly! Thank you so much:)
Hi Becca! This Code works perfectly in Psychopy but not in Pavlovia.
Polygons donât change color on click and they donât return to the previous color if I double click them.
Moreover, it is written that I have to define thisClickTime.
Any advise?
Hi Rachele,
For this âthisClickTimeâ error you will just need to add that to the begin tab to initialize the variable on the JS side, e.g.:
thisClickTime=0
There are a few extra tweaks needed to get this online. So here is the demo I sent functioning online https://pavlovia.org/lpxrh6/change-color-on-click.
The main principles of this are as follows, change code type to âbothâ and then make the following changes to the right hand side of the code:
- core.clock must be util.clock
- instead of
thisPolygon.fillColor ==='red'
usethisPolygon.fillColor['_rgb'][2] === 0
this is fetching the rgb values of the color to check if the blue channel is â1â or â0â (white = [1, 1, 1] red = [1, 0, 0] - when assigning a new color, use
thisPolygon.fillColor = new util.Color("white")
instead ofthisPolygon.fillColor = 'white'
Hope this helps,
Becca
what error do you get?
Hi Becca,
I think this is a silly question but somehow I canât figure out how to exhange the color red with blue in this code:
if ((thisPolygon.fillColor[â_rgbâ][2] === 0)) {
thisPolygon.fillColor = new util.Color(âwhiteâ);
} else {
thisPolygon.fillColor = new util.Color(âredâ);
}
So I would like the polygon to change to blue (now red) when clicked and back to white when clicked again.
Thank you!!
Hi There, did you figure this out? it would just be replacing the âredâ like this:
if ((thisPolygon.fillColor[â_rgbâ][2] === 0)) {
thisPolygon.fillColor = new util.Color(âwhiteâ);
} else {
thisPolygon.fillColor = new util.Color(âblueâ);
}
My problem is very similar to this one. I cannot make the thing work though. Would you look at it and tell me what you think? Thank you very much.
https://discourse.psychopy.org/t/make-image-appear-and-disappear-on-click/23007/1
Hi everyone,
I used the above mentioned code for a similar study that I am programming.
I was just wondering, using the above created code, is there a way to store the two colors of the Polygons displayed in the datafile as well, a column that contains the two colors of the left and right polygon (polygon and polygon_2) such as [white, black]?
Thanks,
Caro
Yes! You can use myLoopName.addData()
in a Code component to store data, the data to store would be:
[myPolygon1.fillColor, myPolygon2.fillColor]
Although, this will store it in whatever colour space youâre using. So, for example, "black"
might be [-1, -1, -1]
if your colour space is rgb
. To get it specifically as named colours, assuming all the colours used have names, you can do:
[myPolygon1._fillColor.named, myPolygon2._fillColor.named]
Hi everyone,
even though these messages are old, I want to continue this old conversation.
I used the code that was posted here in this thread for an experiment, where observers had to change colours of polygons and it worked smoothly. I ran this on PsychoPy 2020.2.4 on various computer with both, OSX and Windows.
However, none of that code works on newer PsychoPy versions.
In the 2021.2.3 version, the colours change after the first click, but never again when clicking to return to the previous colour.
In the 2022.1.4 version, PsychoPy immediately crashes when running the code.
Note, that I did the with my own experiment code, but also with Beccaâs code that she posted, that was accepted as a solution.
What has changed in the 2022.1.4 that even this simple demo code cause PsychoPy to crash? And even in the 2021.2.3 version it does not change the colour back to its original colour, even though Becca added that to the code.
Cheers, Caro
Was there any error message in the Runner window when the experiment crashed? Or, if you were running online, was there any error message which popped up?
Hello all,
The solutions posted above did not work for me. Iâm running Psychopy v2022.2.2. My original code was the following:
for thisPolygon in clickables:
if mouse_response.isPressedIn(thisPolygon):
if thisPolygon.fillColor == 'white':
thisPolygon.fillColor = 'blue'
else:
thisPolygon.fillColor = 'white'
For some reason, psychopy failed to enter the second if statement with this code. As a result, none of my polygons would turn blue when I clicked them.
I found this solution from NatYeung. Nat replaced the second if statement with an equality check on the RGB values. Since my polygons are originally white, I checked whether the first RGB value is 1. This solution, as presented below, works for me. Note I didnât incorporate Beccaâs solution to the flickering issue yet. Iâm not totally sure why the first solution doesnât work, but hope this helps anyone who runs into a similar issue.
for thisPolygon in clickables:
if mouse_response.isPressedIn(thisPolygon):
if thisPolygon.fillColor[0] == 1.0:
thisPolygon.fillColor = 'blue'
else:
thisPolygon.fillColor = 'white'