feat: Calculate animation curve by time points rather than passed frames
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user