Docs > Designing an experiment with JSON

This page describes the basics of creating an experiment using the JSON file format.

  • 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.
    integer 42 A 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.

    Edit example | Run example

    {
    • "stages": [
      • {
        • "layers": [
          • {
            • "type": "image",
            • "name": "image",
            • "geometry": {
              • "position": {
                • "x": 0,
                • "y": 0
                },
              • "size": {
                • "width": 1024,
                • "height": 768
                }
              }
            }
          ],
        • "events": [
          • {
            • "layer": null,
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "canvas": {},
    • "trials": [],
    • "lists": []
    }
  • 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.

    Edit example | Run example

    {
    • "stages": [
      • {
        • "layers": [
          • {
            • "type": "text",
            • "name": "text",
            • "geometry": {
              • "position": {
                • "x": 470,
                • "y": 70
                },
              • "size": {
                • "width": 260,
                • "height": 20
                }
              }
            },
          • {
            • "type": "image",
            • "name": "image-left",
            • "geometry": {
              • "position": {
                • "x": 75,
                • "y": 175
                },
              • "size": {
                • "width": 450,
                • "height": 450
                }
              }
            },
          • {
            • "type": "image",
            • "name": "image-right",
            • "geometry": {
              • "position": {
                • "x": 667,
                • "y": 176
                },
              • "size": {
                • "width": 387,
                • "height": 448
                }
              }
            }
          ],
        • "events": [
          • {
            • "layer": "image-left",
            • "type": "onclick",
            • "action": "stage.next"
            },
          • {
            • "layer": "image-right",
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "trials": [],
    • "canvas": {},
    • "lists": []
    }
  • 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 delay to the relevant layer. The layer will appear delay milliseconds 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.

    Edit example | Run example

    {
    • "stages": [
      • {
        • "layers": [
          • {
            • "type": "text",
            • "name": "text",
            • "geometry": {
              • "position": {
                • "x": 470,
                • "y": 70
                },
              • "size": {
                • "width": 260,
                • "height": 20
                }
              }
            },
          • {
            • "type": "image",
            • "name": "image-left",
            • "geometry": {
              • "position": {
                • "x": 75,
                • "y": 175
                },
              • "size": {
                • "width": 450,
                • "height": 450
                }
              },
            • "delay": 2000
            },
          • {
            • "type": "image",
            • "name": "image-right",
            • "geometry": {
              • "position": {
                • "x": 667,
                • "y": 176
                },
              • "size": {
                • "width": 387,
                • "height": 448
                }
              },
            • "delay": 2000
            }
          ],
        • "events": [
          • {
            • "layer": "image-left",
            • "type": "onclick",
            • "action": "stage.next"
            },
          • {
            • "layer": "image-right",
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "trials": [],
    • "canvas": {},
    • "lists": []
    }
  • 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 delay of 1000.
    • The image layers' delay has been increased to 4000.

    Running the example shows that the text appears immediately, followed by the audio clip playing, followed by the images appearing.

    Edit example | Run example

    {
    • "stages": [
      • {
        • "layers": [
          • {
            • "type": "text",
            • "name": "text",
            • "geometry": {
              • "position": {
                • "x": 470,
                • "y": 70
                },
              • "size": {
                • "width": 260,
                • "height": 20
                }
              }
            },
          • {
            • "type": "audio",
            • "name": "audio",
            • "delay": 1000
            },
          • {
            • "type": "image",
            • "name": "image-left",
            • "geometry": {
              • "position": {
                • "x": 75,
                • "y": 175
                },
              • "size": {
                • "width": 450,
                • "height": 450
                }
              },
            • "delay": 5000
            },
          • {
            • "type": "image",
            • "name": "image-right",
            • "geometry": {
              • "position": {
                • "x": 667,
                • "y": 176
                },
              • "size": {
                • "width": 387,
                • "height": 448
                }
              },
            • "delay": 5000
            }
          ],
        • "events": [
          • {
            • "layer": "image-left",
            • "type": "onclick",
            • "action": "stage.next"
            },
          • {
            • "layer": "image-right",
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "trials": [],
    • "canvas": {},
    • "lists": []
    }
  • 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 delay removed. 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 target is the audio layer, and its type is "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.

    Edit example | Run example

    {
    • "stages": [
      • {
        • "layers": [],
        • "events": [
          • {
            • "layer": "audio",
            • "type": "onplaybackend",
            • "action": "stage.next"
            }
          ]
        },
      • {
        • "layers": [],
        • "events": [
          • {
            • "layer": "image-left",
            • "type": "onclick",
            • "action": "stage.next"
            },
          • {
            • "layer": "image-right",
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "trials": [],
    • "canvas": {},
    • "lists": []
    }
  • 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 geometry object defining a rectangular portion of the image, and a name to refer to the hotspot.

    Once the hotspot is defined, the event target is 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.

    Edit example | Run example

    {
    • "hotspots": [
      • {
        • "name": "nose",
        • "asset": "rowlf.jpg",
        • "geometry": {
          • "position": {
            • "x": 208,
            • "y": 136
            },
          • "size": {
            • "width": 67,
            • "height": 57
            }
          }
        }
      ],
    • "stages": [
      • {
        • "layers": [],
        • "events": []
        },
      • {
        • "layers": [],
        • "events": [
          • {
            • "layer": "image-left",
            • "hotspot": "nose",
            • "type": "onclick",
            • "action": "stage.next"
            }
          ]
        }
      ],
    • "trials": [],
    • "canvas": {},
    • "lists": []
    }
  • 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 custom text field for the user to enter their name. The answer's text has 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.

    Edit example | Run example

    {
    • "stages": [],
    • "canvas": {},
    • "trials": [],
    • "lists": [],
    • "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
          }
        ]
      }
    }