Slider: position and randomisation of labels

PennController for IBEX Forums Support Slider: position and randomisation of labels

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #6583
    suz
    Participant

    Hi Jeremy,

    I hope you’re doing fine!

    I’m trying to set up a slider experiment: a carrier sentence is printed at the top, and then come two possible sentence continuations, for which the participants are to indicate which one is more acceptable. The two options (Alt1 and Alt2) on either side of the slider should be shown randomly. For various reasons, and because the continuations can be a little lengthy, they are to appear on top of each end of the (long) slider.

    This is what I came up with, which actually works okay-ish and should illustrate what I’m after (adjustments to slider settings for aesthetic reasons as per suggestions in other posts):

    
        newTrial("training",
    
            newScale("slider", 100)
                .size("500px", "1em")
                // .settings.slider()
                //.size(500)
                .settings.slider()
                .css("max-width", "unset")
                .print("center at 50vw", "middle at 35vh")
                .log()
            ,
            
            newText("Item", row.CARRIER)
                .print("center at 50vw", "middle at 20vh")
                .center()
                .log()
            ,
            
            newText("Alt1", row.SENTENCE1)
                .print("center at 25vw", "middle at 30vh")
                .center()
                .log()    
            ,
            
            newText("Alt2", row.SENTENCE2)
                .print("center at 75vw", "middle at 30vh")
                .center()
                .log()    
            ,
            
            newSelector("choice")
                .add(getText("Alt1"), getText("Alt2"))
                .shuffle()
                .log()    
            ,
            
            getScale("slider")
                .wait()
                .log()
            ,
            newTimer(500).start().wait()
        )
    
    

    I initially wasn’t happy with the aesthetics of .before() and .after() for the labels, so I thought I’d print them independently, and now I am thinking that shuffle() may not work with them anyway. So that’s why I came up with trying to position Alt1 and Alt2 on top of either end of an intentionally rather long slider.

    The one thing I am concerned about is that slider size and position of Alt1 and Alt2 look very different on different machines/browsers. (I could probably continue to fiddle with the position values.) But I gathered from other forum posts that I’d probably be better off using a canvas for a more “fixed” appearance – but after some trial and error I have been unable to build a canvas AND use the shuffle() command, the error message says that shuffle() is not a function of the canvas element. More likely, the canvas logic is still a little beyond me and I’m using slider, selector, shuffle, etc. all for wildly inconsistent crossed-purposes 🙂

    Relatedly, most importantly, is there a way to log where Alt1 and Alt2 were actually shown in a given trial? This would of course be necessary to adjust the response values. The .log() command with newSelector() is probably not the solution, as there is nothing actually “selected” at that point.

    I tried to build and test my code, also in the test trial example boxes (they are gold!), but the server has been painfully slow over the last week or so, e.g., running very simple code in the trial example test boxes takes up to 30 seconds, and loading the experiment URL takes up to 1 minute (that’ll be some unhappy prolific people…). Is there some maintenance going on?

    As always, any help is so much appreciated!

    Best,
    Susanne

    #6584
    Jeremy
    Keymaster

    Hi Susanne,

    You are right, the best solution is to use a Canvas element. The Selector element being the only PennControllement element that will let you easily shuffle the position of elements on the screen, you are also right to use it for that purpose. With that in mind, the following code will generate what you’re looking for:

    newTrial("training",
        newCanvas("container", "500px","5em")
            .print("center at 50vw","middle at 50vh")
        ,
        newText("Item", row.CARRIER)
            .print("center at 50%", "top at 0%", getCanvas("container"))
            .log()
        ,
        defaultText.css("white-space","nowrap")
        ,
        newText("Alt1", row.SENTENCE1).print("center at 0%", "top at 2em", getCanvas("container"))
        ,
        newText("Alt2", row.SENTENCE2).print("center at 100%", "top at 2em", getCanvas("container"))
        ,
        newSelector("choice")
            .disable()
            .add(getText("Alt1"), getText("Alt2"))
            .shuffle()
            .log()
        ,
        newScale("slider", 100)
            .slider()
            .size("500px", "1em")
            .css("max-width", "unset")
            .print(0, "bottom at 100%", getCanvas("container"))
            .log()
            .wait()
        ,
        newTimer(500).start().wait()
    )

    The idea is to create a Canvas element 500px wide, and print the Scale element onto it. Then we can print the Text elements onto that Canvas element, and center their positions to 0% and 100%. For a reason I cannot quite explain, the text on the right seemed to want to use two lines before I added .css("white-space","nowrap"), which forces the text to use a single line.

    There is a bug in PennController 1.9 where the Selector element fails to report the position of the elements in the absence of a selection, and sometimes gets it wrong otherwise anyway. So until I release PennController 2.0, you will have to randomize using javascript instead: delete the whole Selector bit and replace your newText lines with this

    alts=[row.SENTENCE1,row.SENTENCE2].sort(()=>Math.random()-Math.random())
    ,
    newText("Alt1", alts[0]).print("center at 0%", "top at 2em", getCanvas("container"))
    ,
    newText("Alt2", alts[1]).print("center at 100%", "top at 2em", getCanvas("container"))

    And add this to the closing parenthesis of your newTrial command:

    .log("Alt1", alts[0])
    .log("Alt2", alts[1])

    Regarding the server, we are moving to a new farm. We will release an announcement soon, but if the farm at expt.pcibex.net is becoming too unstable, feel free to move to https://farm.pcibex.net — note that you’ll need to create a new account, and your experiments will not be automatically transferred to the new farm, but you can easily drag-and-drop zip archive versions of your projects

    Let me know if you have any questions

    Jeremy

    #6591
    suz
    Participant

    Hi Jeremy,

    Thanks a million, you are a life-saver, works a charm! Thanks for the many explanations also, makes it easy to understand and learn.

    The new farm looks great! I might have a go over there. The old server doesn’t appear to be unstable, it behaves as expected; it is just slow in loading the experiment/code (updates from Github are quite fast, actually).

    Best,
    Susanne

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.