Animator

The Animator class provides a method for creating complex animations.  Unlike animations based on the UIElement animate() function, an Animator animation can animate two or more objects.  Animator animations can also modify multiple properties and each property’s value can change at varying rates during the course of the animation.  Animations that would be overly complex and awkward when implemented with a Timeline can be clean and simple using an Animator.  An Animator animation can also be used in conjunction with a Timeline to combine the advantages of both methods in a single animation.

In many cases, the same animation can be created using either an Animator or one or more Timelines, perhaps combined with Path, Interval and/or Score objects.  It is the responsibility of the programmer to decide on the best method of implementation.

This section describes and demonstrates the Animator class.  An extended example is described in the Animator Sample Application section.

Animator Modifiable Properties

An Animator animation can modify one or more of the following UIElement properties: (also shown is the property’s data type)

x, y, z, depthfloat
width, height, w, hfloat
opacityint
positiontable of { float x, float y }
sizetable of {float width, float height}
scaletable of { double x, double y }
cliptable of four integers specifying the clipping rectangle { x-origin, y-origin, width, height }
x_rotationdouble specifying rotation angle
y_rotationdouble specifying rotation angle
z_rotationdouble specifying rotation angle
colortable or string specifying color.  For information about color formats, refer to the Specifying Colors in the TrickPlay SDK section of the Programmer’s Guide.

Defining the Animator Animation: Object-Property Pairs

An Animator animation comprises one or more Object-Property pairs.  The Object is any UIElement-based object.  The Property is one of the properties listed above that can be animated.  For example, if we wanted to animate a UIElement Rectangle object called “rect” along the X-axis, the Object-Property pair would be “rect-x”.  If we also wanted to animate the Rectangle along its Y-axis, a second pair of “rect-y” would be defined.

When defining an Animator animation, each Object-Property pair is specified as a table contained within an Animator property called “properties.”  The “properties” property is itself a table of Object-Property pairs.  The “properties” property must be set in the Animator object’s constructor.  The Object is specified as “source” and the Property is specified as “name.”  An example Animator object that defines our earlier rect-x and rect-y pairs is shown below.

myAnimation = Animator( { properties = {
                             { -- Object-Property #1 (rect-x)
                               source = rect,
                               name   = "x"
                             },

                             { -- Object-Property #2 (rect-y)
                               source = rect,
                               name   = "y"
                             }
                          } -- end of properties table
                        } )

Defining the Animator Animation: Key Frames

In addition to Object-Property pairs, an Animator animation specifies various key frames.  Key frames define a property’s value at specific points in the animation.  They also enable a property’s value to change at different rates throughout the animation.  For example, key frames can be defined so that an object moves quickly along the X-axis for the first half of the animation, but then moves very slowly for the second half.

A key frame consists of the following three pieces of information.

progressthe animation’s percentage of completion expressed as a value between 0.0 and 1.0, inclusive.  The start of the animation is 0.0; the end is 1.0.  By the point in the animation specified by progress, the target value should be reached.
ease transitionthe Ease transition, if any, to use while moving toward the target value.  By default, a “LINEAR” Ease transition is used.  Supported Ease transitions are described in the Ease class.
target valuethe property’s value when the animation has reached the point specified by progress

Each key frame is defined in a table called “keys.”  As an example, say we want our Rectangle to move along the X-axis from point 0 to 200 and arrive there when the Animator has completed 20% of its animation.  To accomplish this, the following two key frames should be defined.

-- X-axis key frames
keys = {
    { 0.0, "LINEAR",       0.0   }, -- start at this location
    { 0.2, "EASE_IN_QUAD", 200.0 }  -- by this point in the animation, move to this location
}

The first key frame defined above specifies that at the start of the animation (at progress value 0.0), the Rectangle’s position along the X-axis should be at 0.  There is no ease transition at this key frame, so the “LINEAR” ease is simply a dummy value.  The second key frame states that when the animation is 20% complete at 0.2, the Rectangle’s X-axis position should be at 200.  Also, as it moves to that position, it should use an ease transition of EASE_IN_QUAD.

To continue with the example, let’s move onto the Y-axis.  After moving the Rectangle along the X-axis, we’ll move it along the Y-axis by the same amount.  The following key frames accomplish this.

-- Y-axis key frames
keys = {
    { 0.0, "LINEAR",       0.0   }, -- start at this location
    { 0.2, "LINEAR",       0.0   }, -- at this point in the animation, remain at last location
    { 0.4, "EASE_IN_QUAD", 200.0 }  -- at this point in the animation, move to this location
}

The first key frame starts the Rectangle along the Y-axis at position 0.  When the animation is 20% complete, the Rectangle is still at point 0 on the Y-axis.  This intermediate key frame is necessary to guarantee that no movement occurs along the Y-axis while the Rectangle is moving along the X-axis.  Because there is no movement, the ease transition is another dummy value.  The third key frame states that when the animation is 40% complete, the Rectangle should be positioned at point 200 on the Y-axis and the movement should follow the EASE_IN_QUAD ease transition.

For the remainder of the animation, we’ll move the Rectangle along both the X- and Y-axes, simultaneously, resulting in a diagonal line.  The following key frames accomplish this.

-- X-axis key frames
keys = {
    { 0.0, "LINEAR",       0.0   },  -- start at this location
    { 0.2, "EASE_IN_QUAD", 200.0 },  -- by this point in the animation, move to this location
    { 0.4, "LINEAR",       200.0 },  -- by this point in the animation, remain at last location
    { 1.0, "EASE_IN_QUAD", 800.0 }   -- by this point in the animation, move to this location
}
-- Y-axis key frames
keys = {
    { 0.0, "LINEAR",       0.0   },  -- start at this location
    { 0.2, "LINEAR",       0.0   },  -- by this point in the animation, remain at last location
    { 0.4, "EASE_IN_QUAD", 200.0 },  -- by this point in the animation, move to this location
    { 1.0, "EASE_IN_QUAD", 800.0 }   -- by this point in the animation, move to this location
}

The final key frames in each table move the Rectangle along both the X- and Y-axes.  The Rectangle is travelling a farther distance in this phase that it was in its earlier movements, so it will also move faster.

The key tables should be defined within their associated Object-Property table in the Animator’s “properties” table.  The combined definition is shown below.

myAnimation = Animator( { properties = {
                             { -- Object-Property #1 (rect-x)
                               source = rect,
                               name   = "x",

                               -- X-axis key frames
                               keys = {
                                    { 0.0, "LINEAR",       0.0   },  -- start at this location
                                    { 0.2, "EASE_IN_QUAD", 200.0 },  -- by this point in the animation, move to this location
                                    { 0.4, "LINEAR",       200.0 },  -- by this point in the animation, remain at last location
                                    { 1.0, "EASE_IN_QUAD", 800.0 }   -- by this point in the animation, move to this location
                               }
                             },

                             { -- Object-Property #2 (rect-y)
                               source = rect,
                               name   = "y",

                               -- Y-axis key frames
                               keys = {
                                    { 0.0, "LINEAR",       0.0   },  -- start at this location
                                    { 0.2, "LINEAR",       0.0   },  -- by this point in the animation, remain at last location
                                    { 0.4, "EASE_IN_QUAD", 200.0 },  -- by this point in the animation, move to this location
                                    { 1.0, "EASE_IN_QUAD", 800.0 }   -- by this point in the animation, move to this location
                               }
                             }
                          } -- end of properties table
                        } -- end of Animator table
                      )

Defining the Animator Animation: Optional Properties

Several optional properties may be set in the Animator object’s constructor.

--- The duration Property ---

The duration property can specify the animation’s length in milliseconds.  If not set, duration defaults to 2000 milliseconds.  A sample is shown below.

myAnimation = Animator( { duration = 1000,
                          properties = { ... }
                        }
                      )

--- The timeline Property ---

An Animator object can define and run an animation by itself, but it can also work in conjunction with a Timeline object.  When a Timeline object is attached to an Animator, the properties of the Timeline provide additional characteristics to the animation that are not available in an Animator alone.  For example, a Timeline animation can loop infinitely, define an initial delay, or play in reverse; an Animator by itself cannot perform these operations.

To attach a Timeline object to the Animator, define the timeline property in the Animator’s constructor, as shown below.  Notice that the timeline field is defined outside the properties table.

animationTL = Timeline( { loop = true } )

myAnimation = Animator( { timeline = animationTL,
                          properties = { ... }
                        }
                      )

An alternative method of attaching a Timeline to an Animator is by setting the Animator’s timeline property after the object has been constructed.

-- Construct Animator object
myAnimation = Animator( { ... } )

-- Construct Timeline object and attach to Animator
animationTL = Timeline( { loop = true } )
myAnimation.timeline = animationTL

--- The interpolation Property ---

By default, an animated property’s in-between values are calculated in a straight, linear manner.  This linear type of interpolation is appropriate when the property progresses along a straight, non-swerving path.  However, when a property’s in-between values change in a non-linear fashion--such as when following a twisting X,Y path--a linear interpolation may produce a slightly choppy or abrupt motion.  To produce a smoother animation in such cases, the optional interpolation property can be set to “CUBIC” to calculate in-between values using cubic interpolation instead of the default linear interpolation.  Cubic interpolation will produce smoothly curving in-between values for a property.

The interpolation property can be applied on an individual-property basis, so some animated properties can use linear interpolation and others cubic, depending on which method is most appropriate for each property.  In the example shown below, the position property is defined to use cubic interpolation, and the scale property is explicitly defined to use linear interpolation.  Because linear interpolation is the default, the scale property’s interpolation setting is not required, but is shown for demonstration purposes.

myAnimation = Animator( { properties = {
                            { source = rect,
                              name   = "position",
                              interpolation = "CUBIC",  -- produce smoothly curving in-between values
                              keys = { ... }
                            },

                            { source = rect,
                              name   = "scale",
                              interpolation = "LINEAR", -- produce straight, linear in-between values
                              keys = { ... }
                            }
                         }
                      } )

--- The ease_in Property ---

Another optional property is called “ease_in”.  It is a boolean value indicating whether or not the animation should gradually move the object from its current location to the location specified in the first key frame.  If ease_in is false, the object will jump instantly from its current location to the first key frame’s location without inserting any intermediate steps; if ease_in is true, the object will move gradually to the first frame’s location.  By default, ease_in is true.

The ease_in property is associated with an Object-Property pair, so it is defined within the Object-Property table, as shown in the example below.

myAnimation = Animator( { properties = {
                            { -- Object-Property #1 (rect-x)
                              source  = rect,
                              name    = "x",
                              ease_in = false,
                              keys = { ... }
                            },

                            { -- Object-Property #2 (rect-y)
                              source  = rect,
                              name    = "y",
                              ease_in = false,
                              keys = { ... }
                            }
                        } )

Complete Animator Code Example

The program below animates a sphere to circle around an orbit, getting larger as it approaches and smaller as it moves farther away.  In actuality, the sphere animates two properties: the X-axis and scale properties.  The animation uses an attached Timeline object to have the animation loop.  The Animator-specific code is located in the bottom half of the example.

-- Create a screen background
bckgnd = Canvas( 1920, 1080 )
bckgnd:set_source_color( "ffffffFF" )
bckgnd:paint()
bckgndImage = bckgnd:Image()
bckgndImage.name = "Background"
screen:add( bckgndImage )

-- Create a rectangular demo area
demoArea = Rectangle {
                color = { 100, 100, 100, 255 },
                border_color = { 0, 0, 0, 255 },
                border_width = 4,
                name = "demoArea",
                position = { 746, 96, 0 },
                size = { 308, 308 },
                opacity = 255,
            }
screen:add( demoArea )

-- Create a sphere image using Canvas
sphere = Canvas( 40, 40 )
sphere:set_source_radial_pattern( 12, 12, 2, 20, 20, 20 )
sphere:add_source_pattern_color_stop( 0.0, "d00000FF" )
sphere:add_source_pattern_color_stop( 1.0, "000000FF" )
sphere:arc( 20, 20, 20, 0, 360 )
sphere:fill()

-- Convert Canvas object to Image object and show on the screen
sphereImage = sphere:Image()
sphereImage.position = { 770, 220 }
sphereImage.name = "Sphere"
sphereImage.anchor_point = { 20, 20 },
screen:add( sphereImage )
screen:show()

-- Attach a Timeline to the Animator's animation to have it loop
sphereTL = Timeline( { duration = 1500, loop = true } )

-- Define an Animator for the sphere
sphereAnimator = Animator( {
    timeline = sphereTL,
    properties = {
        -- Object-Property #1
        -- Animate along the X-axis. The sphere simply moves back and forth along the X-axis.
        -- When moving from left to right, it moves faster than when moving from right to left.
        -- When combined with the scale key frames below, this gives the appearance of the sphere
        -- moving faster when it is closer to us, and slower when farther away.
        { source = sphereImage,     -- object to animate
          name = "x",               -- property to animate
          interpolation = "CUBIC",  -- smooth interpolation
          -- X-axis key frames
          keys = {
            { 0.000, "LINEAR", 770 },
            { 0.150, "LINEAR", 900 },
            { 0.300, "LINEAR", 1030 },
            { 0.600, "LINEAR", 900 },
            { 1.000, "LINEAR", 770 }
          }
        },

        -- Object-Property #2
        -- Animate the sphere's scale to give the appearance of moving closer and then farther away.
        { source = sphereImage,
          name = "scale",
          -- Scale key frames
          keys = {
            { 0.000, "LINEAR", { 1.0, 1.0 } },
            { 0.150, "LINEAR", { 3.0, 3.0 } },
            { 0.300, "LINEAR", { 1.0, 1.0 } },
            { 0.600, "EASE_OUT_QUAD", { 0.5, 0.5 } },
            { 1.000, "EASE_IN_QUAD", { 1.0, 1.0 } }
          }
        }
    }
} )

-- Start the Animator animation
sphereAnimator:start()

The animation generated by the example code is shown below.

Summary
AnimatorThe Animator class provides a method for creating complex animations.
Constructors
AnimatorThe Animator() constructor defines most aspects of the animation, including all Object-Property pairs and key frames.
Properties
durationThe duration property is an integer value specifying the length of the animation in milliseconds.
timelineThe timeline property specifies a Timeline object whose characteristics are used to drive the animation.
Functions
startThe start() function begins running the object’s animation.

Constructors

Animator

Animator(table props)

The Animator() constructor defines most aspects of the animation, including all Object-Property pairs and key frames.  The opening section of this page fully describes the creation of an Animator animation.

The Animator animation can be run by calling the object’s start() function.

Arguments:

propstable of Animator properties that define the Object-Property pairs and key frames of the animation

Return Value: Animator object containing the defined animation

See Also: the start function

Properties

duration

int duration

The duration property is an integer value specifying the length of the animation in milliseconds.

The animation’s duration can also be set in the Animator object’s constructor or in the duration property of an attached Timeline.  If the Animator and Timeline objects each specify a different duration, the duration setting most-recently assigned is used.

Default Value: 2000

See Also: the Timeline.duration property

timeline

Timeline timeline

The timeline property specifies a Timeline object whose characteristics are used to drive the animation.  For example, the Timeline’s loop property can be set to have the animation loop infinitely.

The timeline property can also be set in the Animator object’s constructor.

Default Value: nil

See Also: the Timeline class

Functions

start

start()

The start() function begins running the object’s animation.

To stop the animation before it finishes, the Animator object must have a Timeline associated with it and assigned to its timeline property.  The Timeline object’s stop() function can then be called to stop the animation.

Arguments: None

Return Value: None

See Also: the description located at the beginning of this page about defining an Animator animation

Animator(table props)
The Animator() constructor defines most aspects of the animation, including all Object-Property pairs and key frames.
int duration
The duration property is an integer value specifying the length of the animation in milliseconds.
Timeline timeline
The timeline property specifies a Timeline object whose characteristics are used to drive the animation.
start()
The start() function begins running the object’s animation.
The Animator sample application uses the TrickPlay SDK Library’s Animator class to animate screen elements and their properties.
When specifying a particular color, the TrickPlay SDK libraries recognize several formats.
The Ease class enables the application of ease-in and ease-out transitions to animations or ranges of values.
int duration
The duration property is an integer value specifying the length of the Timeline’s animation in milliseconds.
The Timeline class enables the asynchronous animation of one or more UIElement objects.
Close