Getting Started With Concert.js

The below series of examples teaches the concepts and usage of Concert.js through working sample code with explanations, starting with the most basic concepts and progressing up to demonstrate some advanced uses. See the reference documentation for all the details of everything mentioned here and more.
 

Starting, Stopping, Seeking, and Synchronizing

There are a number of options for how to start and move around in an animation sequence, including the possibility of synchronizing it to other things (e.g., video or audio, other Concert.js sequences, or user controls).

See below to learn how to use some of these possibilities.

The Basics of Running Sequences

So far, we've run sequences using the begin() method. We will examine that function shortly. First let's take a step back and look at a more general function for running Concert.js sequences.

The fundamental method for making a sequence go is the run() method. The run() method takes a single, optional parameter, an object which can have any or all of a number of properties. For a full explanation, see the Reference documentation. But here is a rough overview of them all.

  • after: This specifies what to do upon reaching the end of the sequence timeline. It will be covered in the tutorial step on Repeating.
  • autoStopAtEnd: This specifies whether to automatically stop running the sequence when it hits the end. Defaults to true.
  • before: This specifies what to do when encountering time values before the beginning of the sequence timeline. It will be covered in the tutorial step on Repeating.
  • generateValues: Transformations can have start and end values that are dynamically generated at some later point rather than being fixed at the time they are added to the sequence. This parameter specifies whether the sequence should calculate all those values automatically just before running the animation. This feature is covered in tutorial step on Indexing and Value Generators. Defaults to true.
  • initialSeek: Numeric value indicating an intial seek point along the timeline. This allows starting a sequence from some point other than the beginning. If a non-null value is given for this parameter, the sequence will seek to the specified time before commencing the run.
  • onAutoStop: This allows you to specify a callback function that will be invoked just after automatically stopping at the end of the sequence. Note that it will only ever be called if the autoStopAtEnd parameter mentioned above is set to true.
  • pollingInterval: Numeric value indicating the time in between animation updates. This allows you to manually set how far apart (in milliseconds) the beginnings of successive frames of the animation are. When set to any value below 1 (0 is the default), Concert will handle this automatically using window.requestAnimationFrame().
  • speed: Numeric value indicating a run speed multiplier (0.5 = half-speed, 2 = double-speed, and so on).
  • stretchStartTimeToZero: As will be explained in the tutorial step on Repeating, various behaviors can be set to occur when the time goes past the end of the timeline, or before it reaches the beginning of it. If the first segment of animation begins at some time later than 0, however, this can bring about unexpected triggering of the sequence's "before" behavior or auto-stop when the sequence is run from time 0, since that is technically before the beginning of the sequence. Sometimes it is therefore useful for the sequence to behave as if the start point of the whole sequence is at time 0, even when the first segment of animation actually begins later than this. If stretchStartTimeToZero is set to true, the sequence will act as though its overall start is at time 0.
  • synchronizeTo: This allows setting a synchronization source for the sequence. It can take any of the following:
    • null: The sequence will be locked to the system clock.
    • A function object: The sequence will call this function every time the polling interval is reached, and the function's return value will be used as the current time to seek to. Using a custom function here allows you to synchronize the sequence to anything you want (for instance, locking it to the current value of a UI element, such as a slider, or to another Concert.Sequence object.)
    • An HTML audio or video DOM object: The sequence will be locked to the currentTime property of the media element (converted to milliseconds). This allows the sequence to remain synchronized to a media element even when it is paused, scrubbed, or the user skips around.
  • timeOffset: Numeric value indicating a constant value to be added to the current time before seeking. This is useful if you want your sequence to run a fixed amount ahead of or behind your synchronization source. If it is null, the value is calculated automatically, assuming you intend for the current sequence seek time to be matched to the current position of the synchronization source.
  • useSoleControlOptimization: Boolean value, indicating whether the sequence can assume it is the only thing controlling all the object properties it is modifying while running. Setting it to true allows Concert.js to make optimizations that speed up seek times and therefore improve performance. But if anything else will be touching the features being animated, this should be set to false.

Auxiliary Control Methods

There are several shortcut methods which can be used for making a sequence run, along with several other useful, related functions. These can be seen in the below example. If you experiment with the buttons on this demo, you can see how the different functions work.

  • begin: Try clicking this button at any time. You'll see the yellow box start at the beginning and move to the end, without regard for whether the video is running.
  • follow: Try starting the video, and then clicking the "follow" button. You'll notice that the yellow box moves in sync with the video, but offset by whatever position the video was in when the follow button was clicked.
  • syncTo: Try clicking the "syncTo" button before or after starting the video. You'll see that the yellow box moves in sync with the video as with "follow", except that it jumps to the position the video is in (that is, it is like "follow" with an offset of 0).
  • stop: The stop() method will stop a sequence at any time.
  • seek: Try entering a time value in millseconds (0-5000 is the range of this animation), then hitting the "seek" button. You'll see the yellow box immediately jump to whatever time position you specified-- unless the animation is already running, in which case your seek will be overridden so fast you probably won't see it happen at all.

You also may notice that in this case the sequence does not stop running automatically when using syncTo or follow. This allows you to scrub the video back and forth even after it is finished, or restart it, and the sequence is still locked to it. It does mean that the poller is still running, though, and continually updating the position of the yellow box. In many cases that is an unnecessary waste of processing, and it is only done here to demonstrate how these functions work. Often a better route would be to set onplay, onpause, and onseeked event handlers to run the sequence's syncTo(), stop(), and seek() methods, respectively.

Below is the source code for this example. In comments it shows how the various sequence start methods are all just shortcuts for common ways of calling the run() method.

const BeginButton = document.getElementById("BeginButton"),
  FollowButton = document.getElementById("FollowButton"),
  SyncToButton = document.getElementById("SyncToButton"),
  StopButton =  document.getElementById("StopButton"),
  VideoElement = document.getElementById("MovingBoxVideo"),
  MovingBox = document.getElementById("MovingBox"),
  StatusBox = document.getElementById("StatusBox"),
  SeekInput = document.getElementById("SeekInput"),
  SeekButton =  document.getElementById("SeekButton");

function showStatus(isRunning)
{ StatusBox.innerHTML = "Running: " + (isRunning === true); }

let sequence = new Concert.Sequence();
sequence.setDefaults(
  { applicator: Concert.Applicators.Style, unit: "px" });

let animation =
{
  target: MovingBox, feature: "left",
  keyframes: { times: [0, 5000], values: [0, 270] }
};

let params = { onAutoStop: function() { showStatus(false); } };

sequence.addTransformations(animation);

BeginButton.onclick =
  function ()
  {
    showStatus(true);

    sequence.begin(params);
    // equivalent to:
    //   sequence.run(
    //   {
    //     synchronizeTo: null, initialSeek: 0,
    //     timeOffset: null, autoStopAtEnd: true,
    //     [plus whatever properties are set in the params variable]
    //   });
  };

FollowButton.onclick =
  function ()
  {
    showStatus(true);

    sequence.follow(VideoElement, params);
    // equivalent to:
    //   sequence.run(
    //	 {
    //     synchronizeTo: VideoElement, initialSeek: null,
    //     timeOffset: null, autoStopAtEnd: false,
    //     [plus whatever properties are set in the params variable]
    //   });
  };

SyncToButton.onclick =
  function ()
  {
    showStatus(true);
    
    sequence.syncTo(VideoElement, params);
    // equivalent to:
    //   sequence.run(
    //	 {
    //     synchronizeTo: VideoElement, initialSeek: null,
    //     timeOffset: 0, autoStopAtEnd: false,
    //     [plus whatever properties are set in the params variable]
    //   });
  };

StopButton.onclick =
  function () { sequence.stop(); showStatus(false); };

SeekButton.onclick =
  function ()
  {
    let position = parseInt(SeekInput.value);
    sequence.seek(isNaN(position) ? 0 : position);
  };

SeekInput.onkeyup =
  function (event)
  {
    if (event.keyCode === 13)
      SeekButton.click();
  };

A few more functions that may come in handy occasionally are:

  • getCurrentTime(), which gets the current position along a sequence's timeline.
  • getStartTime(), which gets the start time of a sequence's timeline. (The start time of a sequence is considered to be the first start time of any transformation within that sequence.)
  • getEndTime(), which gets the end time of a sequence's timeline. (The end time of a sequence is considered to be the last end time of any transformation within that sequence.)
  • isRunning(), which returns a Boolean value indicating whether the sequence is presently running.