self-paced reading with image element in the middle of the sentence

PennController for IBEX Forums Support self-paced reading with image element in the middle of the sentence

This topic contains 5 replies, has 2 voices, and was last updated by Avatar sarahlee 3 weeks, 6 days ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #6714
    Avatar
    sarahlee
    Participant

    Hi Jeremy,

    I’m trying to build a rebus sentence paradigm experiment, which is basically a self-paced reading experiment, except that one word in the middle will be replaced with an image.

    An example:
    Kim / picked / up / the / [image of a ball] / and / tossed / it / over / to / the / basketball / player.

    At each slash, the participant will press the space bar and the next word (or image) will appear, while the RTs to each word & image will be measured. Everything needs to be presented on the same horizontal line.

    (I don’t think using the canvas element will work because the x,y coordinates of the image will be different in each experimental item (e.g. depending on the length of the preceding words))

    I’ve been trying to approach it by using the “standard.before” and “standard.after” commands on the image element – so that the DashedSentence Controller containing “Kim picked up the” will appear to the left of the image and the DashedSentence Controller containing “and tossed it over to the basketball player” will appear to the right of the image.

    I’m currently having trouble controlling the execution order of different elements and making each word/image appear with a single space bar press. (e.g. first DashedSentence element -> image element -> second DashedSentence element)
    I was wondering if you could provide some insight into how to fix my unsuccessful attempt below. Thank you so much in advance.

    link: https://farm.pcibex.net/r/HvEGdD/

    code:

    newTrial( "experiment",
        newImage("ball", "ball.png")
        ,
        newController("part1", "DashedSentence", {
            s : "Kim picked_up the         " ,
            showAhead: false ,
            showBehind: false
        })
        ,
        newController("part2", "DashedSentence", {
            s : "         and tossed it over to the basketball player." ,
            showAhead: false ,
            showBehind: false
        })
        ,newKey("space", " ")
            .wait()
            .log()
        ,
        getImage("ball")
            .size(50,50)
            .before(getController("part1")
                .print()
                .log()
                .wait())
            .print()
            .wait()
            .after(getController("part2")
                .print()
                .log()
                .wait())
        )

    Best,
    Sarah

    • This topic was modified 1 month, 3 weeks ago by Avatar sarahlee.
    #6717
    Jeremy
    Jeremy
    Keymaster

    Hi Sarah,

    In this case, you’re probably better off re-coding DashedSentence’s function yourself. Here’s a suggestion, add this to your script (tested with PennController 1.9):

    addToDash = (commands,element,previousElement) => {
        id = element._element.id;
        type = element._element.type;
        if (previousElement && previousElement._runPromises && previousElement._runPromises instanceof Function){
            previousId = previousElement._element.id;
            previousType = previousElement._element.type;
            previousElement = window['get'+previousType](previousId).hidden()
        }
        commands.push(
            getKey("nextDash").wait(),
            previousElement,
            window['get'+type](id).log().print( getText("container") )
        )
    }
    myDash = (...args) => {
        commands = [
            newKey("nextDash", " ").log("all"),
            newText("container", "").css({display:"flex",'flex-flow':'row wrap'}).print()
        ];
        previousElement = null;
        args.forEach(a => {
            if (typeof(a)=="string") a = a.split(' ').forEach( s=>{
                newElement = newText(s);
                commands.push(newElement);
                addToDash(commands,newElement,previousElement);
                previousElement = newElement;
            });
            else if (a._runPromises && a._runPromises instanceof Function) {
                newElement = window['get'+a._element.type](a._element.id);
                addToDash(commands,newElement,previousElement);
                previousElement = newElement;
            }
        })
        return commands;
    }

    Then you can use it like this:

    newTrial( "experiment",
        newImage("ball","ball.png").size(50,50).print().remove()
        ,
        ...myDash("This is a very long sentence to see if linebreaks will be automatically handled", getImage("ball"), "in a satisfactory way, despite there being an Image element in the middle of this very very very very long sentence!")
        ,
        getKey("nextDash").wait()
    )

    Note that I print and immediately remove the Image element before using the function, as otherwise PennController has trouble printing it right. The participant shouldn’t see anything, just make sure to print any Image element you insert in myDash beforehand

    Let me know if you have questions

    Jeremy

    #6728
    Avatar
    sarahlee
    Participant

    Hi Jeremy,

    Thank you so much for the help! Yes, this would definitely work better, to accommodate cases where the sentence is long and spills over to the next line.

    Thanks again,

    Sarah

    #6856
    Avatar
    sarahlee
    Participant

    Hi Jeremy,

    I had a question following up on this earlier thread. I’m trying to put this “…mydash” element into a template in which a comprehension question (a new text element) is to be presented after the self-paced reading element, ideally on the next page.

    Currently, I’m having trouble removing the self-paced reading element after the last space bar press — the last word remains on the screen.

    I suppose this “…mydash” element cannot be called back with a get command? What would be a good way to remove it?

    I was also wondering if there is any way to align the text at the center of the image (in terms of horizontal alignment), so that the midpoint of the image’s height is aligned with the text?

    Here’s a link to the demonstration page of this project:

    https://farm.pcibex.net/r/TMKkRQ/

    Many thanks in advance!

    #6857
    Jeremy
    Jeremy
    Keymaster

    Hi Sarah,

    Yes, simply stack these two commands on your Image element:

    .css('transform','translateY(-50%)')
    .cssContainer('height','1em')

    The css command will move the element up by 50% of its size, effectively aligning its vertical midpoint with what used to be its top border. The cssContainer command will make it occupy only 1em (the height of a standard character) without actually diminishing the image’s height.

    If you look at the code of myDash, you’ll see that it creates a Text element named “container” and, in addToDash, you’ll see that every element is printed into it. So just do getText("container").remove() to take it off the screen (or .hidden() if you still want a blank space where it used to be)

    Jeremy

    #6860
    Avatar
    sarahlee
    Participant

    Thanks so much for the reply!

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.