Scrollable Image/Polygon on pavlovia (use for consent form)

Hi there, I’m making a consent for an online experiment appear as a scroll-able image.

gitlab: Scrollable polygonscrollPolygon.psyexp (9.0 KB)

The local version uses 2 lines custom code & works as expected: image appears, and can easily be scrolled through vertically (picked up from this post).

newY = mouse.getWheelRel()[1] / 100
polygon.pos += (0, newY)

For JS, newY is initialized in Begin Experiment:

newY = [];

In Each Frame js:

newY = (mouse.getWheelRel()[1] / 100);
image.pos = [0, newY];

Pavlovia behavior:
The polygon appears for a few milliseconds (I’m guessing the length of one frame?) then disappears and seems to create a new polygon on top of the old one that is not scrollable-- so I’d guess that it uses the initial position from drawing the polygon, and then gets into trouble once it tries to update new ‘Y’ position.
In reality I’m using an image, and its similar behavior where the image is visable for a few milliseconds, disappears, but for whatever reason does not reappear as the polygon does.

Am I missing something silly in JS? Does mouse.getWheelRel() behave differently in psychojs?

Thanks! Attached simplified version of the experiment.

scrollPolygon.psyexp (9.0 KB)

I think the blue rectangle is presented on top of the triangle, but with a delay of one frame. Also, for the scrolling, you’ll need to make a slight adjustment in your. You’ll need to change the position by the scroll distance (instead of setting the position by the scroll distance). Got some untested code below for you, but it’s probably enough to get your underway :slight_smile:

// Change y position
deltaY = (mouse.getWheelRel()[1] / 100);
oldY = image.pos[1];
newY = oldY + deltaY:
image.pos = [0, newY];
// Debugging; let's log everything to the browser console
// Don't have this in your final experiment, because it can impact performance
console.log([deltaY, oldY, newY]);

@thomas_pronk Thank you! This works with slight edits!
It also turns out that mouse.getWheelRel() does behave slightly differently in js than py in that in py, to get the expected acuity per scroll, you need to divide by 100, while in js I actually am multiplying by 3-- getWheelRel() refreshes much more often in js?

It’s also odd to me that the initial version didn’t work-- it seems ‘+=’ has the same logic in py & js? In my initial comment I just wrote ‘=’, but meant to write:

newY = (mouse.getWheelRel()[1] / 100);
image.pos += [0, newY];

which doesn’t draw the image at all interestingly…

For others making a scrollable image/polygon/consent form on pavlovia, make sure to have a mouse component in the routine (or create one via code), and add this as a js code component in Every Frame (no need to initialize the variables earlier):

oldY = image.pos[1];
deltaY = (mouse.getWheelRel()[1] * 3);
newY = (oldY + deltaY);
image.pos = [0, newY];


Happy to read it works! Got some follow-ups:

PsychoPy (via numpy) supports vector addition, but JS doesn’t
That’s why the statement below works in PsychoPy but not in PsychoJS

image.pos += [0, newY];

How to get the speed right
Could be that PsychoPy refreshes more often than PsychoJS. Maybe by adding some time-based criterion (only getWheelRel if at least 50 ms passed since the last one) you could even that out?

@thomas_pronk Thanks for the follow-ups!

I was looking a javascript documentation and it looks like ‘+=’ works & has the same logic as py (x+= y) == (x = x + y)-- is it that psychojs is different from javascript wrt ‘+=’? Or I’m looking at wonky documentation? :slight_smile:

Re speed, thanks that could work! Since I’m just using it to scroll through a consent form, getting it equal for local & online versions isn’t too much of a concern for me, but hopefully folks can try that if they are using scroll within their experimental designs!

No, you’re totally correct about that. I think I made a mistake about how addition behaves in Python (+ numpy) and JS. For example, if I run these statements:

x = [1,2]
x += 1

I get “1,21” in JS (first, [1,2] gets converted to the string “1,2” then the 1 gets appended. I get an error in Python.

If I run these statements

x = [1,2]
x += [1,1]

I get “1,21,1” in JS (same procedure as above). I get [1,2,1,1] in Python; both arrays get appended to each other.