feat: Calculate animation curve by time points rather than passed frames

This commit is contained in:
DreamMaoMao
2025-11-04 11:31:04 +08:00
parent 70eb70ef0d
commit b39ab429f5
6 changed files with 76 additions and 84 deletions

View File

@@ -234,10 +234,15 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
if (!l)
return;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t passed_time = timespec_to_ms(&now) - l->animation.time_started;
double animation_passed =
l->animation.total_frames
? (double)l->animation.passed_frames / l->animation.total_frames
l->animation.duration
? (double)passed_time / (double)l->animation.duration
: 1.0;
int type = l->animation.action = l->animation.action;
double factor = find_animation_curve_at(animation_passed, type);
unsigned int width =
@@ -280,13 +285,11 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
wlr_scene_node_for_each_buffer(&l->scene->node,
scene_buffer_apply_opacity, &opacity);
if (animation_passed == 1.0) {
if (animation_passed >= 1.0) {
wl_list_remove(&l->fadeout_link);
wlr_scene_node_destroy(&l->scene->node);
free(l);
l = NULL;
} else {
l->animation.passed_frames++;
}
}
@@ -295,9 +298,13 @@ void layer_animation_next_tick(LayerSurface *l) {
if (!l || !l->mapped)
return;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t passed_time = timespec_to_ms(&now) - l->animation.time_started;
double animation_passed =
l->animation.total_frames
? (double)l->animation.passed_frames / l->animation.total_frames
l->animation.duration
? (double)passed_time / (double)l->animation.duration
: 1.0;
int type = l->animation.action == NONE ? MOVE : l->animation.action;
@@ -349,12 +356,10 @@ void layer_animation_next_tick(LayerSurface *l) {
.height = height,
};
if (animation_passed == 1.0) {
if (animation_passed >= 1.0) {
l->animation.running = false;
l->need_output_flush = false;
l->animation.action = MOVE;
} else {
l->animation.passed_frames++;
}
}
@@ -448,10 +453,8 @@ void init_fadeout_layers(LayerSurface *l) {
fadeout_layer->current.height = 0;
}
// 计算动画帧数
fadeout_layer->animation.passed_frames = 0;
fadeout_layer->animation.total_frames =
fadeout_layer->animation.duration / all_output_frame_duration_ms();
// 动画开始时间
fadeout_layer->animation.time_started = get_now_in_ms();
// 将节点插入到关闭动画链表中,屏幕刷新哪里会检查链表中是否有节点可以应用于动画
wlr_scene_node_set_enabled(&fadeout_layer->scene->node, true);
@@ -534,23 +537,11 @@ void layer_commit(LayerSurface *l) {
}
l->animation.initial = l->animainit_geom;
// 设置动画速度
l->animation.passed_frames = 0;
l->animation.total_frames =
l->animation.duration / output_frame_duration_ms(l->mon);
l->animation.time_started = get_now_in_ms();
// 标记动画开始
l->animation.running = true;
l->animation.should_animate = false;
} else {
// 如果动画没有开始,且被判定为不应该动画,
// 则设置总帧数为1,不然其他地方一旦获取动画
// 进度,总帧数作为分母会造成除零
// 比如动画类型为none的时候
if (!l->animation.running) {
l->animation.passed_frames = 1;
l->animation.total_frames = 1;
}
}
// 请求刷新屏幕
wlr_output_schedule_frame(l->mon->wlr_output);