-
Overview
JSON
JSON is a file format which uses JavaScript notation. If you're not familiar with JSON or JavsScript, the table below describes the various datatypes used in an experiment.
string"hello"A piece of text, always surrounded by double-quotes. integer42A whole number array[42, "hello"]A sequence of other JSON objects, separated by commas and surrounded with square brackets. object{"name" : "Bob", "age" : 25}A set of key/value pairs, separated by commas and surrouunded with curly braces. Stages
Each experiment is split into stages, which you can think of as the different screens that the user will see when participating.
Each stage contains layers, which describe where images, text and audio will appear on the stage.
Stages also have events, which let you control when layers appear, and how the user proceeds through the experiment.
Trials
Your experiment can have any number of trials, which in turn can contain any number of conditions. Each condition has a variables array, allowing you to define which assets appear in the stage's layers.
Lists
Your experiment can also have any number of lists, which allow you to control which trials (and which condition of each trial) should be displayed to the user.
-
Basic experiment
The simplest possible experiment contains one stage. The stage contains one layer and one event.
- The layer is set to display a single image at the full size of the canvas.
- The event is configured to advance the stage (and therefore end the trial) whenever the user clicks anywhere on the stage.
If you run the example, you can see that clicking anywhere on the stage counts as a valid click, and ends the experiment.
You'll also note that researchers will need to edit each image if they wish to change the text, or reposition the images.
{- "stages": [
- {
- "layers": [
- {
- "type": "image",
- "name": "image",
- "geometry": {
- "position": {
- "x": 0,
- "y": 0
- "size": {
- "width": 1024,
- "height": 768
- "position": {
- {
- "events": [
- {
- "layer": null,
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "image",
- "value": "muppets.jpg"
- {
- {
- {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
-
Using separate assets
By spliting the display into multiple images & layers, you can edit text easily and re-use the same images across trials & experiments.
- There are now three layers, one for each image and another for the text.
- There are also two events, one for each image.
Running the example shows that participants must now click one of the images to continue.
{- "stages": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "image",
- "name": "image-left",
- "geometry": {
- "position": {
- "x": 75,
- "y": 175
- "size": {
- "width": 450,
- "height": 450
- "position": {
- {
- "type": "image",
- "name": "image-right",
- "geometry": {
- "position": {
- "x": 667,
- "y": 176
- "size": {
- "width": 387,
- "height": 448
- "position": {
- {
- "events": [
- {
- "layer": "image-left",
- "type": "onclick",
- "action": "stage.next"
- {
- "layer": "image-right",
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "text",
- "value": "Which is your favourite muppet?"
- {
- "layer": "image-left",
- "value": "rowlf.jpg"
- {
- "layer": "image-right",
- "value": "kermit.jpg"
- {
- {
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
-
Delaying layer appearance
You may want your text & images to appear at different times. For example, you may want the text to appear, but then give time for the participant to read the text before showing the images.
A simple way to do this is to add a
delayto the relevant layer. The layer will appeardelaymilliseconds after the stage begins.- Both layers have been given a delay of 2000.
Running the example shows that the text appears immediately, with both images appearing after 2 seconds.
Note that while layers are hidden, events targeting them will not be triggered.
{- "stages": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "image",
- "name": "image-left",
- "geometry": {
- "position": {
- "x": 75,
- "y": 175
- "size": {
- "width": 450,
- "height": 450
- "position": {
- "delay": 2000
- {
- "type": "image",
- "name": "image-right",
- "geometry": {
- "position": {
- "x": 667,
- "y": 176
- "size": {
- "width": 387,
- "height": 448
- "position": {
- "delay": 2000
- {
- "events": [
- {
- "layer": "image-left",
- "type": "onclick",
- "action": "stage.next"
- {
- "layer": "image-right",
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "text",
- "value": "Which is your favourite muppet?"
- {
- "layer": "image-left",
- "value": "rowlf.jpg"
- {
- "layer": "image-right",
- "value": "kermit.jpg"
- {
- {
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
-
Audio
You can add an audio file just by defining another layer. Audio layers do not have
geometry, as they display no UI of their own.- Another layer has been added, with a
delayof 1000. - The image layers'
delayhas been increased to 4000.
Running the example shows that the text appears immediately, followed by the audio clip playing, followed by the images appearing.
{- "stages": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "audio",
- "name": "audio",
- "delay": 1000
- {
- "type": "image",
- "name": "image-left",
- "geometry": {
- "position": {
- "x": 75,
- "y": 175
- "size": {
- "width": 450,
- "height": 450
- "position": {
- "delay": 5000
- {
- "type": "image",
- "name": "image-right",
- "geometry": {
- "position": {
- "x": 667,
- "y": 176
- "size": {
- "width": 387,
- "height": 448
- "position": {
- "delay": 5000
- {
- "events": [
- {
- "layer": "image-left",
- "type": "onclick",
- "action": "stage.next"
- {
- "layer": "image-right",
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "text",
- "value": "Which muppet is making noise?"
- {
- "layer": "audio",
- "value": "dog.wav"
- {
- "layer": "image-left",
- "value": "rowlf.jpg"
- {
- "layer": "image-right",
- "value": "kermit.jpg"
- {
- {
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
- Another layer has been added, with a
-
Events
In the Audio example above, we used a delay to ensure the images appeared when the audio clip had finished. However, this would not work if you have trials with audio clips of differing durations.
Instead, you can split your content across two stages and link them together with an event.
- A second stage has been added; the image layers have been moved to that stage, and their
delayremoved. The events targetting the images have also been moved. - The text layer has been duplicated in the second stage, as we want it to appear in both stages.
- Another event has been added to the first stage. This time, the event's
targetis the audio layer, and itstypeis "onplaybackend".
Running the example shows that the trial moves to the second stage as soon as the audio clip finishes. Now the images will appear after the audio, regardless of the duration of the clip.
{- "stages": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "audio",
- "name": "audio",
- "delay": 1000
- {
- "events": [
- {
- "layer": "audio",
- "type": "onplaybackend",
- "action": "stage.next"
- {
- "layers": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "image",
- "name": "image-left",
- "geometry": {
- "position": {
- "x": 75,
- "y": 175
- "size": {
- "width": 450,
- "height": 450
- "position": {
- {
- "type": "image",
- "name": "image-right",
- "geometry": {
- "position": {
- "x": 667,
- "y": 176
- "size": {
- "width": 387,
- "height": 448
- "position": {
- {
- "events": [
- {
- "layer": "image-left",
- "type": "onclick",
- "action": "stage.next"
- {
- "layer": "image-right",
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "text",
- "value": "Which muppet is making noise?"
- {
- "layer": "audio",
- "value": "dog.wav"
- {
- "layer": "image-left",
- "value": "rowlf.jpg"
- {
- "layer": "image-right",
- "value": "kermit.jpg"
- {
- {
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
- A second stage has been added; the image layers have been moved to that stage, and their
-
Hotspots
If you need finer control over which parts of an image should register clicks, you can use hotspots.
Hotspots always reference an image, with a
geometryobject defining a rectangular portion of the image, and a name to refer to the hotspot.Once the hotspot is defined, the event
targetis assigned the asset & hotspots names separated by a full-stop, e.g. "asset.hotspot".- A hotspot has been added.
- The events have been updated to refer to the hotspot.
If you run the example, you can see that valid clicks are only registered against the defined hotspot.
{- "hotspots": [
- {
- "name": "nose",
- "asset": "rowlf.jpg",
- "geometry": {
- "position": {
- "x": 208,
- "y": 136
- "size": {
- "width": 67,
- "height": 57
- "position": {
- {
- "stages": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "audio",
- "name": "audio",
- "delay": 1000
- {
- "events": [
- {
- "layer": "audio",
- "type": "onplaybackend",
- "action": "stage.next"
- {
- "layers": [
- {
- "layers": [
- {
- "type": "text",
- "name": "text",
- "geometry": {
- "position": {
- "x": 470,
- "y": 70
- "size": {
- "width": 260,
- "height": 20
- "position": {
- {
- "type": "image",
- "name": "image-left",
- "geometry": {
- "position": {
- "x": 75,
- "y": 175
- "size": {
- "width": 450,
- "height": 450
- "position": {
- {
- "type": "image",
- "name": "image-right",
- "geometry": {
- "position": {
- "x": 667,
- "y": 176
- "size": {
- "width": 387,
- "height": 448
- "position": {
- {
- "events": [
- {
- "layer": "image-left",
- "hotspot": "nose",
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "text",
- "value": "Click the nose of the muppet that is making noise!"
- {
- "layer": "audio",
- "value": "dog.wav"
- {
- "layer": "image-left",
- "value": "rowlf.jpg"
- {
- "layer": "image-right",
- "value": "kermit.jpg"
- {
- {
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
-
Questionnaire
You can create a questionnaire to gain additional information about your participants, and optionally use their responses to assign a list to the participant.
A questionnaire consists of one or more questions, each with one or more answers. You can specify if the participant can provide multiple answers, if they must provide an answer, and also allow them to type custom answers.
- The first question creates an optional
customtext field for the user to enter their name. The answer'stexthas been left empty here, as no further explanation is needed. - The second question defines a series of possible answers. If the user chooses the custom answer, a list will be assigned to them.
{- "stages": [
- {
- "layers": [
- {
- "type": "image",
- "name": "image",
- "geometry": {
- "position": {
- "x": 0,
- "y": 0
- "size": {
- "width": 1024,
- "height": 768
- "position": {
- {
- "events": [
- {
- "layer": null,
- "type": "onclick",
- "action": "stage.next"
- {
- "layers": [
- {
- "canvas": {
- "size": {
- "width": 1024,
- "height": 768
- "size": {
- "trials": [
- {
- "name": "muppet",
- "conditions": [
- {
- "name": "favourite",
- "variables": [
- {
- "layer": "image",
- "value": "muppets.jpg"
- {
- {
- {
- "lists": [
- {
- "name": "1",
- "trials": [
- "muppet:favourite"
- {
- "questionnaire": {
- "questions": [
- {
- "text": "What is your name?",
- "answers": [
- {
- "text": "",
- "custom": true
- {
- "required": false
- {
- "text": "Which languages do you speak fluently?",
- "answers": [
- {
- "text": "English"
- {
- "text": "Español"
- {
- "text": "普通话"
- {
- "text": "Other",
- "custom": true,
- "list": "1"
- {
- "multiple": true
- {
- "questions": [
- The first question creates an optional