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, depth | float |
width, height, w, h | float |
opacity | int |
position | table of { float x, float y } |
size | table of {float width, float height} |
scale | table of { double x, double y } |
clip | table of four integers specifying the clipping rectangle { x-origin, y-origin, width, height } |
x_rotation | double specifying rotation angle |
y_rotation | double specifying rotation angle |
z_rotation | double specifying rotation angle |
color | table 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.
progress | the 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 transition | the 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 value | the 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.
Animator | The Animator class provides a method for creating complex animations. |
Constructors | |
Animator | The Animator() constructor defines most aspects of the animation, including all Object-Property pairs and key frames. |
Properties | |
duration | The duration property is an integer value specifying the length of the animation in milliseconds. |
timeline | The timeline property specifies a Timeline object whose characteristics are used to drive the animation. |
Functions | |
start | The start() function begins running the object’s animation. |
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:
props | table 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
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
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
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
The Animator() constructor defines most aspects of the animation, including all Object-Property pairs and key frames.
Animator( table props )
The duration property is an integer value specifying the length of the animation in milliseconds.
int duration
The timeline property specifies a Timeline object whose characteristics are used to drive the animation.
Timeline timeline
The start() function begins running the object’s animation.
start()
The duration property is an integer value specifying the length of the Timeline’s animation in milliseconds.
int duration