Fusion
Fusion copied to clipboard
Animation timelines/sequences/keyframes
Right now, it can be awkward to work with animations in Fusion that involve multiple keyframes or values.
Fusion could implement a Timeline object which allows the user to define 'keyframes' for a value, which can then be moved/interpolated between by some state representing the current time:
local currentTime = State(0)
local colour = Timeline(currentTime, {
[0] = Color3.new(1, 0, 0)
[0.5] = Color3.new(0, 1, 0)
[1] = Color3.new(0, 0, 1)
})
print(colour:get()) -- red
currentTime:set(0.5)
print(colour:get()) -- green
currentTime:set(0.75)
print(colour:get()) -- halfway between green and blue
currentTime:set(1)
print(colour:get()) --blue
This would be useful for defining more complex declarative animations in Fusion.
For reference, the above code might currently look like this today:
local currentTime = State(0)
local RED = Color3.new(1, 0, 0)
local GREEN = Color3.new(0, 1, 0)
local BLUE = Color3.new(0, 0, 1)
local color = Computed(function()
local t = currentTime:get()
if t <= 0 then
return RED
elseif t <= 0.5 then
return RED:Lerp(GREEN, t*2)
elseif t <= 1 then
return GREEN:Lerp(BLUE, t*2 - 1)
else
return BLUE
end
end)
Also worth mentioning Fusion can also provide perceptually uniform colour blending (Oklab) which looks better than default Roblox lerping (sRGB)
Plus, this could even be used beyond just animation - because this is all done with state objects, you can use it to process any kind of data you'd like!
Here's an example where you can use it to map values from one range (50-100) to another (0-1):
local input = State(50)
local output = Timeline(input, {[50] = 0, [100] = 1})
print(input:get(), "=", output:get()) -- 50 = 0
input:set(75)
print(input:get(), "=", output:get()) -- 75 = 0.5
input:set(100)
print(input:get(), "=", output:get()) -- 100 = 1
Comparing the code with the Timeline
component to the one without it, I definitely think that the Timeline
component will be a great addition to Fusion. Is there a way to "tween" the currentTime
value?
Yup - using a Tween or Spring object:
local currentTime = State(0)
local colour = Timeline(
Tween(currentTime, TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)),
{
[0] = Color3.new(1, 0, 0)
[0.5] = Color3.new(0, 1, 0)
[1] = Color3.new(0, 0, 1)
}
)
Yup - using a Tween or Spring object:
local currentTime = State(0) local colour = Timeline( Tween(currentTime, TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)), { [0] = Color3.new(1, 0, 0) [0.5] = Color3.new(0, 1, 0) [1] = Color3.new(0, 0, 1) } )
Then that's perfect!
Could also be useful in conjunction with timers: https://github.com/Elttob/Fusion/issues/12
Another thing to consider is 'extrapolation behaviour' - what if you pass in a value before the start of the timeline, or after the end?
For animation uses, clamping to the nearest value would be good enough, but perhaps for some uses it'd be worth providing an option to allow for extrapolation?
Perhaps 'Keyframes' would be a more appropriate name for this API?