Hello world

hello

We will create a simple task that says “Hello world”. As we go, we will comment on several of the player’s features and explain some of the ways you can customize your task.

You can follow along and play around with the code right here.

The wrapper

miTime’s scripts are usually a single JavaScript file. The script is wrapped within a define function (You don’t have to understand what it does, but if you are interested look up requirejs).

/* The script wrapper */
define(['timeAPI'], function(APIconstructor) {
	var API = new APIconstructor();

	/*
		Your script comes here...
	*/

	return API.script;
});
/* don't forget to close the wrapper */

The wrapper creates the API object for you. The API object is the instrument that we will use to create and run tasks. The whole task is written by creating a bunch of objects and arrays. The API object has functions that accept those objects and arrays and know how to create a task from them.

The task structure

Each task is composed of one or more trials, that are activated sequentially. We set trials into the player using a function called API.addSequence that accepts an array of trials as its argument.

define(['timeAPI'], function(APIconstructor) {

	var API = new APIconstructor();

	API.addSequence([
		/*
			This is where you input all your trials.
			We will see below how to write trials.
		*/
	]);

	return API.script;
});

In the following section we will see how to populate the trial sequence. Later, we will see that API provides many additional functions that allow us to further customize the player.

A simple trial

Let’s populate the sequence with a simple trial. The following trial displays the words “Hello world” at the center of the screen, and ends when you press space.

{
	input: [
		// What input to accept from the participant (user)
		{handle:'space',on:'space'}
	],
	layout: [
		// What to show throughout the trial.
		{
			media :{word:'Hello world'},
			css:{fontSize:'2em',color:'#D7685A'}
		}
	],
	interactions: [
		// What to do when different events occur.
		{
			conditions: [
				{type:'inputEquals',value:'space'}
			],
			actions: [
				{type:'endTrial'}
			]
		}
	]
}

What we see above is a definition of a trial. A trial is a JavaScript object. Inside that object, there are three other objects: input, layout and interaction. Each of these objects defines a different aspect in the trial. Let’s learn about these three objects, one by one.

Input

The input object is an array of objects that define the input we expect the participant to use. Each object in theinput array defines one input element (full documentation here).

[//Open the array of input objects.
	//An input object that defines what to do when the user hits space.
	{handle:'space', on:'space'} 
]//Close the array

Each input object must include the properties handle and on. The handle property defines the name of this input. Other parts of the script can then refer to this input using this name (e.g., check whether the input was activated). The on property defines what type of input this object listens to.

In this case, we created an input object that listens to the “space keypressed” event (on:'space'), and triggers an event called “space” (handle:'space'). We will use the event name in the interactions section.

The player supports many types of input. For now, let’s learn only about keypressed. keypressed creates an input listener for simple keyboard interactions. The following code creates a listener for the event of hitting the 'e' key:

[
	{handle:'space', on:'keypressed', key:'e'}
]

Note that the event type is now keypressed and we added an additional property to the object, key which defines what type of keypressed triggers this event. Note also that the name that we give the event is absolutely arbitrary, so we can leave the handle as 'space' and it still works. However, it is generally a good practice to use meaningful names (e.g., 'key_e'). You can try replacing the old input object with this one, and see what happens. Then try creating an object that responds to the 'i' key being pressed.

Layout

The layout object is responsible for stimuli that are presented during the whole trial. All the stimuli that are set into the layout array will be displayed automatically from the beginning of the trial until its end. (We use a different object, named stimuli to define stimuli that are displayed only for a part of the trial. We will learn about the stimuli object in more advanced examples).

The layout is an array of objects. Each object represents a stimulus. The stimulus object is a complex objects, and we’ll learn more about it in more advanced examples. For now, let’s start with a simple example:

[//This opens an array of stimulus objects to show in the layout.
	{//Each object is a stimulus object.
		media :{word:'Hello world'}, //Media defines what to show
		css:{fontSize:'2em',color:'#FF0000'} //css defines its style.
	}
]

This stimulus displays the words “Hello world” at the center of the player’s canvas.

Stimulus objects hold a media object to display, and relevant data regarding how to display it. This particular stimulus sets the style for the media using the css property. CSS is the language used by browsers to describe styles. Using the stimulus css property we can control css in any way we want. In this case we use the css object to set the font size and color of the stimulus.

The font size of this stimulus is set to 2em. em is a css size unit, 1em is the standard (default) font size, 2em is twice that size and so on (you can use fractions too: e.g., 1.3em). So that the text displayed by this stimulus is double the default text size.

The color attribute accepts any valid css color. You can try the following: '#0000FF', '#FFFFFF', '#00FF00' or use this site to find additional colors.

The css object can do far more than this. If you want to know more you can check out the full API here

Interactions

Interactions are a grouping of conditions (statements of truth) and actions to perform if (and only if) all conditions are true. We won’t really get into interactions here, but these are the basics:

[
	{
		conditions: [
			{type:'inputEquals',value:'space'}
		],
		actions: [
			{type:'endTrial'}
		]
	}
]

Each interaction object has a conditions property and an actions property. The conditions property is an array of condition objects. Each condition objects defines a condition that can be true of false. For instance, the condition in the example above is that the name (i.e., handle) of currently active input is ‘space’. This condition is true only when the participant hits space (that is what we defined in the input section). There are a few other possible conditions that can be defined, and we will learn about them in more advanced examples (to see the full list of conditions, see here). If all the condition objects in the conditions array are true, then all the actions in the actions array are executed.

The actions array holds an array of actions to perform if all conditions are evaluated as true. In this case the only action is to end this trial. We will learn about other forms of actions in more advanced examples (to see the full list of conditions, see here).

Play ground

Here is the whole code again, with comments that explain each and every line.

Run Download

Epilogue (of sorts)

You’ve learned how to create a single trial, and the different elements that compose it. The next stage is seeing how different trials come together to form a task.

Last modified March 11, 2021: fixing actions? (2e5870a)