52 lines
1.5 KiB
Lua
52 lines
1.5 KiB
Lua
--- @alias voidCallback fun(): nil
|
||
--- @alias animationRunner fun(node: AnimationNode)
|
||
|
||
--- @class AnimationNode
|
||
--- @field count integer
|
||
--- @field run animationRunner
|
||
--- @field parent AnimationNode?
|
||
--- @field children AnimationNode[]
|
||
--- @field finish voidCallback
|
||
--- @field onEnd voidCallback?
|
||
local animation = {}
|
||
animation.__index = animation
|
||
|
||
--- Регистрация завершения дочерней анимации
|
||
function animation:bubbleUp()
|
||
self.count = self.count - 1
|
||
if self.count > 0 then return end
|
||
if self.onEnd then self.onEnd() end
|
||
if self.parent then self.parent:bubbleUp() end
|
||
end
|
||
|
||
--- @param children AnimationNode[]
|
||
--- Запланировать анимации после текущей, которые запустятся одновременно друг с другом
|
||
function animation:chain(children)
|
||
for _, child in ipairs(children) do
|
||
child.parent = self
|
||
table.insert(self.children, child)
|
||
self.count = self.count + 1
|
||
end
|
||
return self
|
||
end
|
||
|
||
--- @param data {[1]: animationRunner, onEnd?: voidCallback, children?: AnimationNode[]}
|
||
--- @return AnimationNode
|
||
local function new(data)
|
||
local t = setmetatable({}, animation)
|
||
t.run = data[1]
|
||
t.onEnd = data.onEnd
|
||
t.count = 1 -- своя анимация
|
||
t.children = {}
|
||
t:chain(data.children or {})
|
||
t.finish = function()
|
||
t:bubbleUp()
|
||
for _, anim in ipairs(t.children) do
|
||
anim:run()
|
||
end
|
||
end
|
||
return t
|
||
end
|
||
|
||
return new
|