Hi! I’m working on an animation library for Roact. It’s called Flick
and my plan is to make it open source soon!
Right now, I’m wondering about how I can improve the ergonomics of the API.
The library works by giving you access to a prop named flick
that lets you get animated values (which are just bindings) and change the goal values. Everything gets updated in the background.
To show the API, here’s a quick example of a button that will have a different color when hovering and being pressed:
local Button = Roact.Component:extend('Button')
function Button:init()
self.onMouseEnter = function()
self.props.flick:setGoals({ foo = Color3.new(0.75, 0.75, 0.75) })
end
self.onMouseLeave = function()
self.props.flick:resetGoals()
end
self.onMouseButton1Down = function()
self.props.flick:setGoals({ foo = Color3.new(0.5, 0.5, 0.5) })
end
self.onMouseButton1Up = function()
self.props.flick:resetGoals()
end
end
function Button:render()
local props = self.props
local flick = props.flick
local text = props.text
local onClick = props.onClick
return Roact.createElement('TextButton', {
AutoButtonColor = false,
Text = 'Click'
-- here we assign using the name of the generated binding
BackgroundColor3 = flick.bindings.foo,
[Roact.Event.MouseButton1Click] = onClick,
[Roact.Event.MouseEnter] = self.onMouseEnter,
[Roact.Event.MouseLeave] = self.onMouseLeave,
[Roact.Event.MouseButton1Down] = self.onMouseButton1Down,
[Roact.Event.MouseButton1Up] = self.onMouseButton1Up,
})
end
From this example, we see the API of the flick
object, which I am satisfied with, but if you have a suggestion for better function names let me know!
How do we get that flick
prop to be in our button’s prop? That is probably where I’m the less sure how I should design the API. Right now, what I have is something similar to Rodux connect function. You pass a table that defines the initial values (you can put multiple values) and (what I’ve named) the optional motion.
-- generates a new component that wraps our
-- Button and provides the flick prop
return Flick.withAnimation(
{
foo = Color3.new(1, 1, 1),
},
Flick.Motions.Timed(0.15)
)(Button)
Or maybe something like this (would makes it possible to exports Flick.withMotion(...)
and reuse it with different values)
return Flick.withMotion(Flick.Motions.Timed(0.15))
.withAnimation({
foo = Color3.new(1, 1, 1),
})(Button)
In brief:
- how should the user wrap its components
- how should the flick prop work
I’m sharing all this hoping to get feedback and ideas for the library! I really don’t mind criticism, even if you think the whole idea is the worst thing you’ve seen let me know why.
If tried to make the example as concise as possible, but let me know if I went to far and I just made it unclear.
My next steps before publishing this is to write a quick getting started/documentation site and then add springs as a possible motion type.