add animations (lerp only for now)

This commit is contained in:
2026-10-10 13:31:37 +02:00
parent 601eb47cad
commit ffc738604d
3 changed files with 438 additions and 461 deletions
+76 -25
View File
@@ -1,38 +1,89 @@
#include <dangerzone/render/anim.h>
#include <string.h>
void
anim_rect_pos(
framebuffer_e framebuffer,
uint32_t x0,
uint32_t y0,
uint32_t x1,
uint32_t y1,
uint32_t w,
uint32_t h,
uint32_t color
) {
// there's nowhere to move
if (x0 == x1 && y0 == y1) {
return;
anim_init(anim_t *anim)
{
if (anim != NULL)
memset(anim, 0, sizeof *anim);
}
bool
anim_start(anim_t *anim, const anim_track_t *tracks,
size_t count, float duration)
{
if (anim == NULL || (count != 0 && tracks == NULL) ||
count > ANIM_MAX_TRACKS || duration < 0.0f) {
return false;
}
anim->count = count;
anim->elapsed = 0.0f;
anim->duration = duration;
anim->active = duration > 0.0f && count > 0;
uint32_t dirx = (x1 - x0 > 0) ? 1 : -1;
uint32_t diry = (y1 - y0 > 0) ? 1 : -1;
for (size_t i = 0; i < count; ++i) {
anim->tracks[i] = tracks[i];
anim->items[i].payload = tracks[i].payload;
anim->items[i].rect = tracks[i].from;
}
if (x0 == x1) {
dirx = 0;
if (!anim->active) {
for (size_t i = 0; i < count; ++i)
anim->items[i].rect = tracks[i].to;
}
if (y0 == y1) {
diry = 0;
return true;
}
bool
anim_update(anim_t *anim, float dt)
{
if (anim == NULL || !anim->active)
return true;
if (dt < 0.0f)
dt = 0.0f;
anim->elapsed += dt;
float t = anim->elapsed / anim->duration;
if (t >= 1.0f) {
t = 1.0f;
anim->active = false;
}
/**
* 1. shift the rectangle by one pixel in the direction of movement
* 2. remove the trailing row / column left
*/
/* Ease-out. Replace with t for linear motion. */
float eased = 1.0f - (1.0f - t) * (1.0f - t);
if (true) {
for (size_t i = 0; i < anim->count; ++i) {
const anim_track_t *track = &anim->tracks[i];
anim_rect_t *rect = &anim->items[i].rect;
rect->x = track->from.x + (track->to.x - track->from.x) * eased;
rect->y = track->from.y + (track->to.y - track->from.y) * eased;
rect->w = track->from.w + (track->to.w - track->from.w) * eased;
rect->h = track->from.h + (track->to.h - track->from.h) * eased;
}
return !anim->active;
}
bool
anim_is_active(const anim_t *anim)
{
return anim != NULL && anim->active;
}
size_t
anim_count(const anim_t *anim)
{
return anim != NULL ? anim->count : 0;
}
const anim_item_t *
anim_items(const anim_t *anim)
{
return anim != NULL ? anim->items : NULL;
}