79 lines
2.3 KiB
Lua
79 lines
2.3 KiB
Lua
-- Timing helpers for collab backgrounds ported from Lumen data. Lengths are multiples of
|
|
-- `unit` ms: a beat (60000 / bpm) for things that follow the song, 1 for plain ms.
|
|
|
|
-- Moves { length, distance, ease } run back to back (distance 0 is a hold); the offset
|
|
-- they describe is the sum of their attributes
|
|
local function chain_moves(moves, unit, scale)
|
|
local out, at = {}, 0
|
|
for _, m in ipairs(moves) do
|
|
local length, distance, ease = m[1], m[2], m[3]
|
|
if distance ~= 0 then
|
|
local move = anim.move(length * unit, {
|
|
total_distance = math.floor(distance * scale),
|
|
delay = at,
|
|
ease_in = ease == "in" and "quadratic" or nil,
|
|
ease_out = ease == "out" and "quadratic" or nil,
|
|
})
|
|
move:start()
|
|
table.insert(out, move)
|
|
end
|
|
at = at + length * unit
|
|
end
|
|
return out
|
|
end
|
|
|
|
-- Frames { index, length } shown back to back
|
|
local function frame_change(steps, unit, opts)
|
|
local textures, t = {}, 0
|
|
for _, step in ipairs(steps) do
|
|
table.insert(textures, { t, t + step[2] * unit, step[1] })
|
|
t = t + step[2] * unit
|
|
end
|
|
return anim.texture_change(t, textures, opts)
|
|
end
|
|
|
|
local function sum(moves)
|
|
local total = 0
|
|
for _, m in ipairs(moves) do total = total + m.attribute end
|
|
return total
|
|
end
|
|
|
|
local function concat(...)
|
|
local out = {}
|
|
for _, t in ipairs({ ... }) do
|
|
for _, v in ipairs(t) do table.insert(out, v) end
|
|
end
|
|
return out
|
|
end
|
|
|
|
-- Ambient loop: `build()` returns a table of one-shot anims (or lists of them) that is
|
|
-- rebuilt every `period` ms, so several anims stay in step without each looping alone
|
|
local Loop = {}
|
|
Loop.__index = Loop
|
|
|
|
function Loop.new(period, build)
|
|
return setmetatable({ period = period, build = build }, Loop)
|
|
end
|
|
|
|
function Loop:update(current_time_ms)
|
|
if not self.t0 or current_time_ms - self.t0 >= self.period then
|
|
self.t0 = current_time_ms
|
|
self.anims = self.build()
|
|
end
|
|
for _, a in pairs(self.anims) do
|
|
if a.update then
|
|
a:update(current_time_ms)
|
|
else
|
|
for _, m in ipairs(a) do m:update(current_time_ms) end
|
|
end
|
|
end
|
|
end
|
|
|
|
return {
|
|
chain_moves = chain_moves,
|
|
frame_change = frame_change,
|
|
sum = sum,
|
|
concat = concat,
|
|
Loop = Loop,
|
|
}
|