Developer Portal
Quick StartsComposition scriptingAPIs and SDKsSupport
  • Portal overview
  • Quick start
  • REST API
    • Introduction
    • Rate limits
    • Authorization
    • How-to guides
      • Get a control app's API token
      • Get a composition's sub-composition IDs and names and their payload structures
      • Get a control app's model
      • Get a control app's metadata
      • Update a sub-composition's content
      • Update a sub-composition's animation state
      • Update a sub-composition's content and animation state in one call
      • Update multiple sub-compositions in one call
    • API reference
      • Get control app details
        • Get a control app's metadata
        • Get a control app's model
        • Get a control app's control data
      • Send data to a control app
        • Update a control app's content
        • Update a control app's animation state
      • Take out all of an app's output
  • Data stream API
    • Introduction
    • Rate limits
    • Authorization
    • How-to guides
      • Create a data stream
      • Link a data stream to a composition
      • Send data to an app using the data stream API
    • API reference
  • Composition scripting
    • Introduction
    • Overview
    • Quick start
      • Find sub-compositions and widgets
      • Read and update control nodes
      • Set text widget text properties
      • Read and update widget properties
      • Read control nodes and update widget properties
      • Set image widget URL property
      • Set table widget content property
    • Cheat sheets
      • Fundamentals
      • Interactive overlays
      • Best practices
    • Use cases
      • Read control nodes and generate HTML text
      • Read control nodes, generate HTML text with background
      • Text Ticker - Start ticker on "In" animation
    • Composition script editor reference
  • Software development kits
    • Graphics SDK
      • Getting started
      • Reference
        • SDK functions
        • Composition object
        • Sequencer object
      • Guides and examples
        • Load a composition with its token
        • Load a composition with its URL
        • Get the composition URL of an app instance
        • Sequencer VOD example
        • Control local preview of app
        • Load app instance output
    • Overlay SDK
      • Getting started
      • SDK functions
      • Use case examples
    • Widget SDK
      • Preparing your environment
      • Getting started
      • Reference
        • Widget UI definition
        • Widget callback functions
        • Time control object
        • Composition instance
      • Guides and examples
        • Widget example: CSS patterns
    • App SDK
  • Singular Basics
    • Overview of Singular
    • Managing overlays in the Dashboard
      • How to create a new composition
      • How to open a new app template
      • How to create an app for a composition
      • How to extract a composition from an app
      • How to find an app's shared app token and shared API URL
      • Dashboard reference
    • Building overlays in Composer
      • How to build a composition
      • How to set up layer logic to automate overlay transitions
      • How to set up control nodes to make widget properties available to a control app
      • Animating overlays
        • How to create timeline animations
        • How to create behavior animations
        • How to create update animations
      • How to make overlays interactive
      • How to adapt overlays to various screen sizes
      • Composer reference
    • Controlling overlays in Studio and UNO
      • How to use Studio
      • Studio reference
      • UNO reference
  • Support
    • Singular status
    • Support resources
    • Singular terminology
    • Performance Testing
Powered by GitBook
On this page
  • Common uses for composition scripts
  • Types of composition scripts
  • Initialization order
  • Essential functions of every composition script
  • Working in Composer and the composition script editor simultaneously
  • Global script
  • Root and sub-composition scripts
  • Overlay script
  • Using the Chrome debugger

Was this helpful?

  1. Composition scripting

Overview

An overview of composition scripting

PreviousIntroductionNextQuick start

Last updated 2 years ago

Was this helpful?

Singular overlays are essentially an HTML/CSS layer that sits on top of video, and composition scripting enables you to add JavaScript code to that layer. Thus, composition scripting allows you to make overlays interactive and set them up to update based on logic.

Composer includes a built-in where you can write composition scripts and test their functionality directly with a composition's output without having to deploy code to a web environment.

Working with composition scripts requires experience in JavaScript and, in some cases, CSS. For recommendations for learning JavaScript, visit the .

Common uses for composition scripts

Composition scripts can be written to perform countless functions. These are the most common:

  • Interpreting and formatting data, e.g., data time, colors, add unit symbols, etc.

  • Triggering animations depending on data, such as playing an animation when a team scores

  • Defining lookup-tables and handle tri-codes

  • Reading and writing data from/to servers

  • Connecting to external data sources

  • Creating interactive user experiences

  • Defining custom animations and transitions

With a basic understanding of composition scripting and some of the functions they can serve, let's take a closer look into the following areas:

Types of composition scripts

There are four types of composition scripts:

Global script

The global script is used to define global variables and library functions that are needed throughout the entire composition. Variables and functions are exposed using the global context of the composition scripts.

Root script

The root script contains root-specific functions, such as receiving or fetching data, interpreting them, and deploying the content to relevant sub-compositions.

Sub-composition scripts

Sub-composition scripts—there can be one per sub-composition—contain data and functions required within their scope. They are used to access control nodes and widgets within them.

The root composition script and sub-compositions scripts are the same except that the root composition doesn't have a parent.

Overlay script

The overlay script provides the interface to communicate with parent web pages, player embed code, and native iOS and Android apps. It is only required for expert use cases and integration with video players.

Interaction between composition scripts

Composition scripts can share data and communicate with each other. For example, you can send data from one sub-composition to another or call functions from one sub-composition to another sub-composition.

Initialization order

Composition scripts are initialized in the following order:

  1. Overlay script

  2. Global script

  3. Sub-compositions starting from lowest child up to parent

  4. Root script

Because of this initialization order, sub-composition scripts have access to the global script, and when the root script is initialized, it has access to all the data in the sub-compositions and can call them. This order ensures that when the root script is initialized, all the parent scripts already exist and it can interact with them.

When the sub-compositions scripts are initialized, widgets associated with them are already there. In other words, widgets are loaded and initialized before composition scripts.

Essential functions of every composition script

At minimum, every composition script needs two functions: init() and close().

The init() function is where you write most of the code. It provides access to a composition object and context.

The composition object contains numerous methods. It can:

  • Add listeners

  • Access children within that sub-composition

  • Find sub-compositions

  • Find group widgets

  • Access the dom element to create various animation effects

  • Get payloads

  • Set a payloads

  • Use jump and play to control the animation

The close() function is used to clean up memory, clear timers, and close data streams.

Working in Composer and the composition script editor simultaneously

As for work done in the composition editor, it won't affect the composition until it is saved.

Global script

The global script is used to define global variables and library functions. Variables and functions are exposed using the “global context” of the composition scripts.

Global script boilerplate
(function() {

  // Function must return the init function. close is optional
  return {

    // the init function is called after the script has been evaluated
		// context: gives access to common objects
    init: function(context) {
      console.log("Initialize Global script ");
    },

    // the close function will be called when the script will be unloaded. 
    // use this function to cleanup timeouts, intervals, XHR request and so on
    close: function() {
      console.log("Close Global script");
    }
  };
})();

init: function(context)

The init function is called after the script has been evaluated.

The context gives access to global objects and utilities. Use the global object to manage custom data, lookup tables, and functions with a global scope. Utility functions include tools and libraries provided by Singular R&D.

context
    global: {}
    utils:
        createConditionalSubCompLink: ƒ ()
        createDataStream: ƒ (t,e,i)
        createMoment: ƒ i()
        createNumeral: ƒ (n)
        createTimeControl: ƒ ()
        createTinyColor: ƒ c(e,t)

close: function()

The close function is called when the script is to be unloaded. Use this function to clean up timeouts, intervals, and XHR, and fetch requests, etc.

Root and sub-composition scripts

The root script contains root specific functions. For example, the root script receives or fetches data, interprets them, and deploys the content to the relevant sub-compositions.

Root and sub-composition boilerplate
(function() {

  // Function must return the init function. close is optional
  return {

    // the init function is called after the script has been evaluated
    // comp: the composition object the script is attached to
		// context: gives access to common objects
    init: function(comp, context) {
      console.log("Initialize Composition script " + comp.name);

      // this listener receives messages from graphics SDK
      // these messages are usually triggered by the "send message to JavaScript" option
      // in the event panel of the composer. 
      // widgets can also send custom messages to the composition script using the  
      // sendCustomMessage of the widget SDK
      comp.addListener('message', (event, msg, e) => {
        console.log("Composition message " + comp.name, event, msg, e);
        e.stopPropagation();
      });
      
      // when the animation state of this comp or a sub comp changes
      comp.addListener('state_changed', (event, msg, e) => {
        console.log("Composition state " + comp.name, event, msg, e);
        e.stopPropagation();
      });

      // when the control nodes of this comp or a sub comp changes
      comp.addListener('payload_changed', (event, msg, e) => {
        console.log("Composition payload " + comp.name, event, msg);
        e.stopPropagation();
      });
      
      // when the payload of a datanode of this comp or a sub comp changes
      comp.addListener('datanode_payload_changed', (event, msg, e) => {
        console.log("Composition datanode payload " + comp.name, event, msg);
        e.stopPropagation();
      });
    },

    // the close function will be called when the script will be unloaded. 
    // use this function to cleanup timeouts, intervals, XHR request and so on
    close: function(comp, context) {
      console.log("Close Composition script " + comp.name);
    }
  };
})();

init: function(context)

  • comp: composition object

  • context: context object

Available listeners

  • 'message' listener

  • 'state_changed' listener

  • 'timeline_event' listener

  • 'payload_changed' listener

  • 'datanode_payload_changed' listener

'message' listener

  • Triggered when:

    • The composition uses interactive events

    • Widgets generate custom events

    • Composition script generates custom events

      comp.addListener('message', (event, msg, e) => {
        console.log("Composition message " + comp.name, event, msg, e);
        e.stopPropagation();
      });

'state_changed' listener

  • Triggered when the animation state of the sub-composition has changed, e.g., when the In or Out state is reached.

      comp.addListener('state_changed', (event, msg, e) => {
        console.log("Composition state " + comp.name, event, msg, e);
        e.stopPropagation();
      });

'timeline_event' listener

  • Triggered on the start and the end of an animation.

      comp.addListener('timeline_event', (event, msg, e) => {
        console.log(comp.name + ".timeline_event() - msg =", msg);
        e.stopPropagation();
      });

'payload_changed' listener

  • Triggered when the content of any control node of the sub-composition changes.

      comp.addListener('payload_changed', (event, msg, e) => {
        console.log("Composition payload " + comp.name, event, msg);
        e.stopPropagation();
      });

'datanode_payload_changed' listener

  • Triggered when the content of any data node added to the sub-composition changes.

      comp.addListener('datanode_payload_changed', (event, msg, e) => {
        console.log("Composition datanode payload " + comp.name, event, msg);
        e.stopPropagation();
      });

close: function()

  • comp: composition object

  • context: context object

Cleans up memory and clears timers in the close function.

Overlay script

The overlay script provides the interface to communicate with parent web pages, player embed code, and native iOS and Android apps.

The overlay script is general only required in very specific cases and requires advanced composition scripting skills.

Overlay script boilerplate
(function() {

  // Function must return the init function. close is optional
  return {
		
    // the init function gives you access to the graphics SDK object and the overlay SDK object
    // more information in the resources menu
    init: function(graphics, overlay) {

      console.log("Initialize Overlay script ");

      // this listener receives messages from graphics SDK
      // these messages are usually triggered by the "send message to JavaScript" option
      // in the event panel of the composer. 
      // widgets can also send custom messages to the composition script using the  
      // sendCustomMessage of the widget SDK
      graphics.addListener('message', (event, msg) => {
        console.log("Graphics SDK message", event, msg);
      });
      
      // when the animation state of a sub composition changes
      graphics.addListener('state_changed', (event, msg) => {
        console.log("Graphics SDK state changed", event, msg);
      });

      // when the control nodes of a sub composition changes
      graphics.addListener('payload_changed', (event, msg) => {
        console.log("Graphics SDK payload changed", event, msg);
      });
      
      // when the payload of a datanode in the composition changes
      graphics.addListener('datanode_payload_changed', (event, msg) => {
        console.log("Graphics SDK datanode payload changed", event, msg);
      });

      // errors will be reported here
      graphics.addListener('error', (event, msg) => {
        console.log("Graphics SDK error", event, msg);
      });
      
      // overlay only exists if the composition is instanciated using the Overlay SDK
      // more info in the resources menu
      if (overlay) {
        overlay.addListener((event, msg) => {
          console.log("Overlay SDK message", event, msg);
        });
      }
    },

    // the close function will be called when the script will be unloaded. 
    // use this function to cleanup timeouts, intervals, XHR request and so on
    close: function() {
      console.log("Close Overlay script");
    }
  };
})();

init: function(graphics, overlay)

  • graphics: Graphics SDK object

  • overlay: overlay object

Available listeners

  • ‘message’ listener

  • ‘state_changed’ listener

  • ‘timeline_event’ listener

  • ‘payload_changed’ listener

  • ‘datanode_payload_changed’ listener

  • Listener ‘error’ listener

close: function()

  • comp: composition object

  • context: context object

Using the Chrome debugger

An important tool in singular composition script is the chrome debugger. It gives you access to all your scripts. To open the chrome debugger click F12 on your keyboard or go to the development tools and select the development tools button.

If you don't have any of the files open, enter ctrl b in the chrome debugger and write the name of your sub-composition to open the composition script.

You can add breakpoints and look at the variables.

To trigger that, just save it and have the windows side by side.

The

The

The

How composition scripts interact with sub-compositions, widgets and each other

While you're working in the composition script editor, another person can work independently in Composer. To bring updates made in Composer into the composition editor, select the in the menu bar.

composition script editor
Support resources page
Types of composition scripts
Initialization order
How composition scripts interact
Essential functions of composition scripts
Using the Chrome debugger to work with composition scripts
global script
root script
Sub-composition scripts
overlay script
Reload Composition button