Creating Generic Context-Based Animations

At times, developers may find themselves having to create duplicate animations for many identical controls across their application. This can be very time-consuming and result in a bloated project.

Thankfully, Storyboard has the ability to create animations that have a dynamic Animation Variable/Context Key which is determined at runtime. This means you can create an animation that is reused by multiple controls, instead of needing to create an animation for each of the controls. 


Creating a Context-Based Animation

One of the most common uses of reusable animations is for button states. For example, let’s adjust the alpha of a button to create a fade out animation. If you’ve never created an animation before, I highly recommend checking out this video to learn how:

As you can see the Key being used is the Fully Qualified Path (Layer.Button.Variable) to the alpha variable; it specifies each Model Element by name. Instead of referring to these Elements by name, we can make it generic by instead referring to it by the type of Element that is in context. By doing that we can make this animation relative to the Control that is bound to the Action that triggers the animation:

Method 1:

Change the Design Context of the animation to one of the controls that will use it. To change the context, click the drop-down next to Design Context, then select “More Model Elements…”. 

Then navigate and select one of the controls that will use this animation and click OK. In this case it will be “base_button”.

Accept the Design Context Change dialog that will open. You will now see that the animation Key has changed to a generic path


Method 2:

Click “Change Variable” under the Animation Variable section in the Properties view for the animation step. 

Check the “Custom Key” checkbox.

Change the key to just reference the control in context and variable name, using this format: ${control:variable_name}

Note: “control” is being used here as a key term, this is not the actual name of the control. “variable_name” is what is changed to the actual variable that you wish to adjust on whatever control will be in context for the animation.


With that all setup, the animation step will look for the specified variable on the control from which the animation is triggered (this is the control in context).

This means that you could use this animation on any number of controls as long as they contain the same variable name and type. This is especially useful when creating components to be reused throughout your project or when using clone controls or tables.


Context-Based Animations with Tables


We can expand this animation design to be used with Tables. This is useful as now the animation can be reused across all of the Cells in the Table. In a Table, each Cell has its own duplicate variable. This means that the generic path we will provide looks slightly different because you will need to specify the Cell as well.

Create another animation to fade the alpha variable of a Control in your Table. This requires that you’ve created and bound variables to the alpha field of your Table Cells

Click “Change Variable” in the Properties view of the animation step.

Check the “Custom Key” checkbox

Change the key to reference the control and the cell before the variable name, using this format: ${cell:control:variable_name}


Note: “cell:control” is being used here as key terms, this is not the actual name of the cell and control. “variable_name” is what is changed to the actual variable that you wish to adjust on whatever cell’s control will be in context for the animation.

On the Table Cell, create a Press Action which triggers this animation. Now when you Press a Cell, it will fade the opacity just as designed.


Passing a Context Via Lua

It is also possible to trigger an animation from Lua. This means it is also possible to provide the context for the animation from a Lua as well. For example, let’s say you want to animate the y-value of a toggle button based on whether it is currently on or off.

Create your toggle buttons:

In the controls’ Properties tab, click the green Link and Chevrons icon next to the Position’s Y parameter to open the dialog to create and bind a variable to this field:

In the Variables tab, Right Click > New Variable to add a boolean variable that we’ll use to hold the state of the toggle:

Create a ‘toggled’ type animation which moves the ‘button’ to the bottom of the toggle and make it generic by changing Animation Variable to ${control:y}.

Create a reversed animation to toggle the button back on. To do this: Right Click the animation > Add Reversed Animation

Add a press event to each button to call your toggle logic function.

Create a Lua function that checks the state of the button and call the appropriate animation depending on the button’s state. Then pass the name of the control (via mapargs.context_control) being pressed to the animation in order to be used as the context:


--- @param gre#context mapargs
function cb_toggle_button(mapargs)
  local control = mapargs.context_control

local state_var = string.format("%s.on_state", control)
  local state = gre.get_value(state_var)

if (state == 1) then
   gre.animation_trigger("toggle_off", { context = control })
   state = 0
   gre.animation_trigger("toggle_on", { context = control })
   state = 1

gre.set_value(state_var, state)


Now you can press any of the toggles and it will animate correctly.

You can download the sample used in this article here: Download

That’s how to trigger the animation from Lua, but if you wanted to create a generic animation in Lua then there are some extra steps.

Firstly, if you’re unfamiliar with how to create an animation in Lua then I recommend taking a look at the documentation here: gre.animation_trigger()

You can also import the Storyboard sample called LuaAnimation which demonstrates the above.

Making a generic Lua animation actually just requires one small change. When specifying any path to a variable, instead of writing the fully qualified path, you can add context shorthand: 


data["key"] = "mylayer.mycontrol.grd_x"


data["key"] = "${control:grd_x}"

Note: this works for every animation data parameter, not just "key".


A sample of how this might look when building an animation step is as follows:

local function create_context_based_anim(mapargs)
local animation_id = gre.animation_create(30, false, trigger_animation)
local data = {}
data["rate"] = "linear"
data["duration"] = "${control:duration}"
data["to"] = "${control:destination}"
data["key"] = "${control:grd_x}"
gre.animation_add_step(animation_id, data)
gre.animation_trigger(animation_id, { context = "my_layer.my_control" })





Please sign in to leave a comment.

Didn't find what you were looking for?

New post