LibAnimate

3k Downloads

General Information

LibAnimate is a library for performing time-based interpolation of values.

It gives you the ability to animate properties of Rift frames out-of-the-box with very little code. It has a comprehensive set of interpolation functions for a high variety of animation curves. All you need to provide are starting values, end values, a duration and the name the of interpolation function, and the rest is handled behind the scenes for you.

Simple Example

In this example, we are going to animate a frame's alpha value from 0.0 to 1.0 over a duration of 3.0 seconds using the cubic Hermite interpolation also known as smoothstep.

First we need a template to represent the animation curves and value projection:

local template = LibAnimate.CreateTemplate({ false, "smoothstep" })

CreateTemplate receives a single argument: a table containing the interpolation methods for each component of the animation. The concrete values mean:

  • false: The first value is not animated at all but is always the starting value.
  • "smoothstep": The second value is interpolated using the smoothstep function.

This is required once at Addon startup and the template should be stored somewhere for later use. Now we can start spawning animations from this template. Note the number of animations you create from a template is not limited. In the following snippet the Frame object frame's alpha is animated from 0.0 to 1.0:

local animation = LibAnimate.CreateAnimation(template, frame.SetAlpha, 3.0, { frame, 0.0 }, { frame, 1.0 })
animation:Start()

The following happens: Over the next 3 seconds the library will call the target function (in this example frame.SetAlpha) in its Event.Syste.Update.Begin cycle with the interpolated arguments, starting at alpha 0.0 and ending at alpha 1.0 using the smoothstep interpolation function as defined in the template creation.

Now it becomes apparent why the animation template requires 2 values even though we are only interpolating a single property (the alpha value). The template requires exactly the same amount of values as the target function. In this example it is Frame:SetAlpha(alpha) which has the hidden self argument which needs to be provided. Note that animation is not necessarily a fire and forget variable. The reference can be used to stop, pause and resume the animation later. The Start method can optionally take a new independent set of start values, end values or duration which override the values the animation was created with for the started run. For a detailed listing of the available methods check the Animation reference page.

Convenience methods

The library comes shipped with predefined convenience functions to remove the boilerplate code for animating predefined frame properties. The above example could have been written shorter using:

frame:SetAlpha(0.0)
local anim = frame:AnimateAlpha(3.0, "smoothstep", 1.0)

Or even shorter (but with linear interpolation):

frame:SetAlpha(0.0)
frame:FadeIn(3.0)

The following methods are created by the library and added to the methods of the frame types returned by UI.CreateFrame:

  • Frame:AnimateAlpha()
  • Frame:AnimateBackgroundColor()
  • Text:AnimateFontColor() (only for Text frames)
  • Frame:AnimateHeight()
  • Frame:AnimatePoint()
  • Frame:AnimateWidth()
  • Frame:FadeIn()
  • Frame:FadeOut()

Each method animates the frame's property using the corresponding SetXX method. The signatures of the animate methods is in general

anim = AnimateXX(duration, interpolation, ...[, finish])

... is a placeholder for the respective SetXX arguments. finish is an optional argument present in all animation functions and explained later. The return value is a reference to the currently triggered animation and can be stored for later use (e.g. stop/pause/resume it). These methods have a relatively low overhead, except for AnimatePoint, which has a few nitpicks and is explained in greater detail on the Frame:AnimatePoint() page.

FadeIn and FadeOut are there for fire-and-forget alpha fading where you do not care about the animation once it started. Both functions can be called with a duration argument or none, in which case the default duration of 0.25 seconds is used. The duration is scaled according to the remaining alpha, that means a frame with alpha 0.0 fades in withing 0.25s, but a frame with alpha 0.5 takes only 0.125s to fade in.

Detailed Explanation

Some aspects of LibAnimate might not be obvious and this section hopefully makes things clear.

Values

The library can animate any values of type T for which the following operations are defined (either implicitly or by metatables):

  • T + T
  • T - T
  • T * number

If you receive errors like "performing arithmetic on XXX value" it means you are providing values for which one of the above conditions is not satisfied. The values in the two tables provided to CreateAnimation and/or Start are mapped based on their index. For the time being only numerically indexed values are supported. The number of values as well as their position must be consistent across CreateTemplate, CreateAnimation and Start or errors might occur.

Templates

The library is based on two components: templates and animations. A template specifies how values are interpolated and forwarded to the target function, for example "interpolate values #1 and #5 linearly, #2 quadratically and forward #3 and #4 unchanged". Creating templates may be an expensive operation as it may involve multiple calls to loadstring, but they are expected to be created once at Addon startup and then reused. Even though they are cached it is an unnecessary amount of work to recreate templates more often than necessary.

You may have noticed by now that the predefined AnimateXX methods do not have a template argument. The reasoning behind this design decision is their ease of use. Not having to worry about template management makes the methods very convenient to use, but they incurr a slight performance hit due to the template creation (though this overhead slowly diminishes as templates are cached if the interpolation function stays the same). This will usually not be a problem as long as you do not launch a gazillion animations at once. If you are paranoid about performance then create the templates and animations only when necessary. Remeber you can reuse animations after they finished running.

Interpolations

The interpolation functions are performing the actual computations. They all receive as first argument the transition factor t ∈ [0;1] and optionally additional parameters depending on the type of interpolation. The return value is usually also within the range [0;1], which means the interpolated values do not exceed the interval [start value;end value]. There are however interpolations which do not satisfy this constraint (for example the elastic and back functions) and you need to be prepared to handle these cases.

The library comes shipped with an extensive list of interpolation functions. This page has a graphical overview of all the predefined functions (make sure the Complete button is pressed). The following are defined in addition to those shown on the linked page:

  • smoothstep (cubic Hermite spline interpolation)
  • easeInPower, easeOutPower, easeInOutPower, easeOutInPower (arbitrary powers for t)

The Interpolations page has more detailed descriptions of all the functions. In case none of them satisfies your needs you can always pass your own functions into the CreateTemplate method:

local f = function(t) return exp(i * pi) + 42 * t end
local template = LibAnimate.CreateTemplate({ false, "linear", f })

Some interpolations allow additional customization. For example: the back functions accept an additional argument besides t: the overshoot amount which controls by how much the function overshoots the provided value range. Such additional parameters are passed into the CreateTemplate function as follows:

local template = LibAnimate.CreateTemplate({ false, "easeInBack:1.70158" })

Important: Values which shall not be interpolated must be marked with false, never with nil!

References

Animation Class
Frame Extension Methods

Function Plots (click the Complete button)