Timer element

Timer elements let you run timers and, if used with wait, pause the execution of the trial’s script for the specified duration.

Creation:

newTimer("myTimer", 1000)

Example:

newText("pleasewait", "Please wait 1s.")
    .print()
,
newTimer("wait", 1000)
    .start()
    .wait()
,
getText("pleasewait")
    .remove()

The code above adds the text Please wait 1s to the screen, starts a 1000ms timer and waits until it is done before removing the text.

Actions

timer.start

getTimer(id).start()

Starts the timer.

Example:

newText("pleasewait", "Please wait 1s.")
    .print()
,
newTimer("wait", 1000)
    .start()
    .wait()
,
getText("pleasewait")
    .remove()

The code above adds the text Please wait 1s to the screen, starts a 1000ms timer and wait until it is done before removing the text.

timer.stop

getTimer(id).stop() (since version 1.1)

Stops the timer early. Nothing happens if the timer has already elapsed.

When timers are stopped early, the script proceeds in the same way as if they had elapsed on their own: any callback command associated to the timer is executed and any wait command on the timer is resolved.

newText("instructions", "Wait 3s or press Space")
    .print()
,
newTimer("delay", 3000)
    .start()
,
newKey("stop early", " ")
    .settings.callback( getTimer("delay").stop() )
,
getTimer("delay")
    .wait()

Will wait 3 seconds before proceeding, or will proceed if the space bar is pressed in the meantime.

timer.wait

getTimer(id).wait()

or getTimer(id).wait("first")

or getTimer(id).wait( test )

Waits until the timer has finished running before evaluating and executing the next commands.

If you call wait("first"), then if the timer has already completed a full run before this command is evaluated, the next commands are evaluated and executed right away. If the timer was never completed before, the next commands are only evaluated and executed after the timer has finished running.

If you pass a test on an element as an argument, it only evaluates and executes the next commands when the timer finishes while the test is successful. If the test is not successful, it will be checked again next time the timer finishes.

Note: if you do not call start on the timer before calling wait, the script will wait forever. This can be useful for the last screen of your experiment, or if you set an interaction with an element on the screen to call the special command end.

newText("instructions", "Please press the spacebar in less than a second")
    .print()
,
newKey("spacebar", " ")
,
newTimer("hurry", 1000)
    .start()
    .wait()
,
getKey("spacebar")
    .test.pressed(" ")
    .success( newText("success", "Good job!").print() )
    .failure( newText("failure", "Too slow...").print() )

Adds a line of text to the page, starts listening for any press on the spacebar, waits 1 second (1000ms) and tests whether the key was pressed: if it was, adds Good job! to the screen, adds Too slow… otherwise.

standard.setVar

getElement(id).setVar( varName ) (since beta 0.3)

Stores the current value of the element in the Var element named varName (if it exists).

What the current value corresponds to is specific to each element type:

  • For Audio elements, it corresponds to the timestamp of the end of the last playback so far (0 if never played back or playback never eneded).
  • For Button elements, it corresponds to the timestamp of the last click so far (0 if never clicked).
  • For Canvas elements, it corresponds to the number of elements it currently contains.
  • For Function elements, it corresponds to the value returned by the function.
  • For Html elements, it corresponds to whether the element is completely filled.
  • For Image elements, it corresponds to whether the image is currently being displayed.
  • For Key elements, it corresponds to the last key that was pressed so far (empty string if no key has been pressed so far).
  • For Scale elements, it corresponds to the value of the last option that was selected (NaN if no option has been selected so far).
  • For Selector elements, it corresponds to the last element that was selected (null if no element has been selected so far).
  • For Text elements, it corresponds to the current text.
  • For TextInput elements, it corresponds to the text that is currently in the input box.
  • For Timer elements, it corresponds to whether the timer has elapsed.
  • For Tooltip elements, it corresponds to whether the tooltip has been validated.
  • For Var elements, it corresponds to the element’s value.
  • For Video elements, it corresponds to the timestamp of the end of the last playback so far (0 if never played back or playback never eneded).
  • For VoiceRecorder elements, it corresponds to the last recording (undefined if no recording so far).
  • For Youtube elements, it corresponds to whether the video has been played.

Example:

newVar("name")
,
newTextInput("nameInput", "What is your name?")
    .settings.once()
    .print()
    .wait()
    .setVar("name")
,
newText("helloname")
    .settings.before( newText("hello", "Hello ") )
    .settings.text( getVar("name") )
    .print()

Creates a Var element named name and adds a text box in which to enter a name. When the return/enter key is pressed while editing the input box, it disables the box and stores its value in the Var element named name. Then it prints a text reading Hello name, where name corresponds to the value of the Var element.

Settings

timer.settings.callback

getTimer(id).settings.callback( element )

or getTimer(id).settings.callback( function )

Warning: until PennController beta 0.2, this command has a bug that freezes the script

Will execute the function or element command when the timer has finished running for the first time.

Example:

newText("start", "Ready... go!")
    .print()
,
newButton("click", "Click me!")
    .print()
,
newTimer("hurry", 1000)
    .settings.callback( getButton("click").remove() )
    .start()
,
getButton("click")
    .wait()
,
newText("success", "You're quick!")
    .print()

Adds a line of text saying Ready… go! to the screen above a button reading Click me!, then starts a 1s timer and waits for a click on the button. After 1s, the button disappears. The text You’re quick! appears on the page after a click on the button. If the button was not clicked within 1s, the text does not show up and the script waits for a click forever (since the button no longer can be clicked). If the button was clicked, then the button’s wait command is validated and the text shows up (the button will still disappear after one second, as specified in the callback).

timer.settings.log

getTimer(id).settings.log()

Will add a line to the results file each time the timer starts and each time it ends.

Example:

newText("pleasewait", "Please wait 1s.")
    .print()
,
newTimer("wait", 1000)
    .settings.log()
    .start()
    .wait()
,
newButton("continue", "Now click here to continue.")
    .print()
    .wait()

Adds the text Please wait 1s to the screen, starts a 1000ms timer and wait until it is done before adding a button to the page. Two lines will be added to the results file, reporting the timestamps at the start and at the end of running the timer (should be spaced apart by about 1000ms).

standard.settings.disable

getElement(id).settings.disable()

Disables any interactive feature of the element.

Note: this does not prevent an element that is part of a Selector element from being selected.

Example:

newAudio("sentence", "test.mp3")
    .print()
    .wait()
,
getAudio("sentence")
    .settings.disable()

Prints buttons to play/pause the audio file test_sentence.ogg, and disables those buttons when the file has played through.

standard.settings.enable

getElement(id).settings.enable()

Enables any interactive feature of the element that was previously disabled.

Example:

newAudio("sentence", "test.mp3")
    .settings.once()
    .print()
,
newKey("secret key", "R")
    .wait()
,
getAudio("sentence")
    .settings.enable()

Prints buttons to play/pause the audio file test_sentence.ogg, and disables those buttons when the file has played through (see audio.settings.once).

Tests

timer.test.ended

getTimer(id).test.ended() (since beta 0.3)

Tests whether the timer has ended.

Example:

newText("start", "Ready... go!")
    .print()
,
newTimer("hurry", 1000)
    .start()
,
newButton("click", "Click me!")
    .print()
    .wait()
,
getTimer("hurry")
    .test.ended()
    .success( newText("slow", "Too slow...").print() )
    .failure( newText("fast", "Good job!").print() )

Adds a line of text saying Ready… go! to the screen, starts a 1s timer, adds a button reading Click me!, and waits for a click on the button. If the timer has ended by the time the button is clicked, the text Too slow… is added to the screen, otherwise if the button is clicked within 1s, Good job! appears below it.

timer.test.running

getTimer(id).test.running() (since beta 0.3)

Tests whether the timer is currently running.

Example:

newTooltip("not running", "The timer is not running")
,
newText("on", "[on]")
    .settings.before( newText("off", "[off]") )
    .print()
,
newSelector("switch")
    .settings.add( getText("on") , getText("off") )
,
newTimer("quick", 500)
    .settings.callback( getSelector("switch").select(getText("off")) )
,
getSelector("switch")
    .settings.callback(
        getSelector("switch").test.selected( getText("on") )
            .success( getTimer("quick").start() )
    )
,
newButton("target", "Click here within 500ms of start")
    .print()
    .wait(
        getTimer("quick")
            .test.running()
            .failure( getTooltip("not running").print("target") )
    )

Shows off and on on a single line above a button reading Click here within 500ms of start. When on is clicked, the 500ms timer starts. If the button is clicked within 500ms, then the running test is successful and the click is validated. If the target button is clicked before the timer has started (i.e. before on was clicked) or after the timer has ended, the running test fails and the wait command does not release the execution of the script: the click is not validated and a new attempt at a on-target click sequence within 500ms is necessary.