How to Animate Color

It's not always clear how animating a color transition works within Storyboard, but the main idea is this:

Instead of adjusting a hex value, it's better to adjust the rgb value for this.
To expand on that, the work needs to be done programmatically in Lua. Each rgb channel should be individually interpolated from the start color to the end color.
Once these calculations have been completed, you could create a timer that calls a function on a set interval. This function would simply update the color of your fill to the next pre-calculated color in the sequence.

I've put together a sample application that demonstrates this behavior.

In this sample you will see that I am interpolating between two colors:

  local start_color = {r = 250, g = 250, b = 10}
  local end_color = {r = 142, g = 79, b = 180}

Then I calculate a total of 10 linear interpolations (10 colors) to get from the start color to the end color. I store these colors into a table called tween_colors for use later. If you wanted to perform this operation in more than 10 steps for an increased gradual change, all you have to do is adjust the value of total_steps.

  local total_steps = 10
  for i = 1, total_steps do
    local t = i/total_steps
r = lerp(start_color.r,end_color.r,t)
    g = lerp(start_color.g,end_color.g,t)
    b = lerp(start_color.b,end_color.b,t)
    tween_colors[i] = gre.rgb(r,g,b)
    print(string.format("step %d: color: rgb(%d,%d,%d)", i,r,g,b))

Now that that is calculated I create an interval timer with a callback function of cb_change_fill which triggers every 25 ms

  if (idval == nil) then
    print("interval timer created")
    idval = gre.timer_set_interval(cb_change_fill,25)

Then finally in this callback all it does is set the color variable tied to the fill color of the control.
There is a check to see if the color we've updated to is the last one in the table (tween_colors). This means that we've completed our interpolation and can clear/delete the timer.

local color_index = 1
function cb_change_fill()
  if (color_index > #tween_colors) then
    print("TIMER: cleared.")
    idval = nil
    local r,g,b = gre.to_rgb(tween_colors[color_index])
    print(string.format("TIMER: setting color to rgb(%d,%d,%d)",r,g,b))
    gre.set_value("Layer.color.color", tween_colors[color_index])
    color_index = color_index + 1

As a side note:

You could do away with the math all-together if you already knew what values you wanted to use.
Websites like this: can create a gradient transition between two colors, using a # of steps you can specify from 1-40.

It shows each individual step/color and it's corresponding hex,rgb value. From this you could instead manually add each color to tween_colors and your application would interpolate through those.

Please find the attached application below.




Please sign in to leave a comment.

Didn't find what you were looking for?

New post