feat: different animation curve for different window action

This commit is contained in:
DreamMaoMao 2025-02-28 17:49:09 +08:00
parent 75d9827c16
commit e633cc6346
5 changed files with 84 additions and 22 deletions

View file

@ -121,8 +121,12 @@ because your keybinds contain shift, the `2` cover to `at`
# custom animation
```
animation_curve=0.46,1.0,0.29,1
animation_curve_open=0.46,1.0,0.29,1.1
animation_curve_move=0.46,1.0,0.29,1
animation_curve_tag=0.46,1.0,0.29,1
```
notice: close and move animations are the same curve.
You can design your animaition curve in:
[here, on cssportal.com](https://www.cssportal.com/css-cubic-bezier-generator/),

View file

@ -9,7 +9,9 @@ animation_duration_move=500
animation_duration_open=400
animation_duration_tag=350
animation_duration_close=500
animation_curve=0.46,1.0,0.29,0.99
animation_curve_open=0.46,1.0,0.29,1
animation_curve_move=0.46,1.0,0.29,1
animation_curve_tag=0.46,1.0,0.29,1
# Scroller Layout Setting
scroller_structs=20

View file

@ -683,34 +683,64 @@ struct vec2 {
};
#define BAKED_POINTS_COUNT 256
struct vec2 *baked_points;
struct vec2 calculate_animation_curve_at(double t) {
struct vec2 *baked_points_move;
struct vec2 *baked_points_open;
struct vec2 *baked_points_tag;
struct vec2 calculate_animation_curve_at(double t, int type) {
struct vec2 point;
double *animation_curve;
if (type == MOVE) {
animation_curve = animation_curve_move;
} else if (type == OPEN) {
animation_curve = animation_curve_open;
} else if (type == TAG) {
animation_curve = animation_curve_tag;
}
point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] +
3 * t * t * (1 - t) * animation_curve[2] + t * t * t;
3 * t * t * (1 - t) * animation_curve[2] + t * t * t;
point.y = 3 * t * (1 - t) * (1 - t) * animation_curve[1] +
3 * t * t * (1 - t) * animation_curve[3] + t * t * t;
3 * t * t * (1 - t) * animation_curve[3] + t * t * t;
return point;
}
void init_baked_points(void) {
baked_points = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points));
baked_points_move = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_move));
baked_points_open = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_open));
baked_points_tag = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_tag));
for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points[i] =
calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1));
baked_points_move[i] =
calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1), MOVE);
}
for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points_open[i] =
calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1), OPEN);
}
for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points_tag[i] =
calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1), TAG);
}
}
double find_animation_curve_at(double t) {
double find_animation_curve_at(double t,int type) {
size_t down = 0;
size_t up = BAKED_POINTS_COUNT - 1;
size_t middle = (up + down) / 2;
struct vec2 *baked_points;
if(type == MOVE) {
baked_points = baked_points_move;
} else if(type == OPEN) {
baked_points = baked_points_open;
} else if(type == TAG) {
baked_points = baked_points_tag;
}
while (up - down != 1) {
if (baked_points[middle].x <= t) {
down = middle;
@ -719,8 +749,8 @@ double find_animation_curve_at(double t) {
}
middle = (up + down) / 2;
}
return baked_points[up].y;
}
// 有 bug,只是让上面那根透明了
@ -762,8 +792,8 @@ void fadeout_client_animation_next_tick(Client *c) {
return;
double animation_passed =
(double)c->animation.passed_frames / c->animation.total_frames;
double factor = find_animation_curve_at(animation_passed);
int type = c->animation.action == NONE ? MOVE : c->animation.action;
double factor = find_animation_curve_at(animation_passed,type);
uint32_t width = c->animation.initial.width +
(c->current.width - c->animation.initial.width) * factor;
uint32_t height = c->animation.initial.height +
@ -802,7 +832,10 @@ void fadeout_client_animation_next_tick(Client *c) {
void client_animation_next_tick(Client *c) {
double animation_passed =
(double)c->animation.passed_frames / c->animation.total_frames;
double factor = find_animation_curve_at(animation_passed);
int type = c->animation.action == NONE ? MOVE : c->animation.action;
double factor = find_animation_curve_at(animation_passed,type);
Client *pointer_c = NULL;
double sx = 0, sy = 0;
struct wlr_surface *surface = NULL;

View file

@ -76,7 +76,9 @@ typedef struct {
uint32_t animation_duration_open;
uint32_t animation_duration_tag;
uint32_t animation_duration_close;
double animation_curve[4];
double animation_curve_move[4];
double animation_curve_open[4];
double animation_curve_tag[4];
int scroller_structs;
float scroller_default_proportion;
@ -480,11 +482,23 @@ void parse_config_line(Config *config, const char *line) {
config->animation_duration_tag = atoi(value);
} else if (strcmp(key, "animation_duration_close") == 0) {
config->animation_duration_close = atoi(value);
} else if (strcmp(key, "animation_curve") == 0) {
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve[0],
&config->animation_curve[1], &config->animation_curve[2],
&config->animation_curve[3]) != 4) {
fprintf(stderr, "Error: Invalid animation_curve format: %s\n", value);
} else if (strcmp(key, "animation_curve_move") == 0) {
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_move[0],
&config->animation_curve_move[1], &config->animation_curve_move[2],
&config->animation_curve_move[3]) != 4) {
fprintf(stderr, "Error: Invalid animation_curve_move format: %s\n", value);
}
} else if (strcmp(key, "animation_curve_open") == 0) {
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_open[0],
&config->animation_curve_open[1], &config->animation_curve_open[2],
&config->animation_curve_open[3]) != 4) {
fprintf(stderr, "Error: Invalid animation_curve_open format: %s\n", value);
}
} else if (strcmp(key, "animation_curve_tag") == 0) {
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_tag[0],
&config->animation_curve_tag[1], &config->animation_curve_tag[2],
&config->animation_curve_tag[3]) != 4) {
fprintf(stderr, "Error: Invalid animation_curve_tag format: %s\n", value);
}
} else if (strcmp(key, "scroller_structs") == 0) {
config->scroller_structs = atoi(value);
@ -1030,7 +1044,9 @@ void override_config(void) {
animation_duration_close = config.animation_duration_close;
// 复制数组类型的变量
memcpy(animation_curve, config.animation_curve, sizeof(animation_curve));
memcpy(animation_curve_move, config.animation_curve_move, sizeof(animation_curve_move));
memcpy(animation_curve_open, config.animation_curve_open, sizeof(animation_curve_open));
memcpy(animation_curve_tag, config.animation_curve_tag, sizeof(animation_curve_tag));
scroller_structs = config.scroller_structs;
scroller_default_proportion = config.scroller_default_proportion;
@ -1132,6 +1148,10 @@ void set_value_default() {
config.disable_while_typing = 1;
config.left_handed = 0;
config.middle_button_emulation = 0;
memcpy(config.animation_curve_move, animation_curve_move, sizeof(animation_curve_move));
memcpy(config.animation_curve_open, animation_curve_open, sizeof(animation_curve_open));
memcpy(config.animation_curve_tag, animation_curve_tag, sizeof(animation_curve_tag));
}
void parse_config(void) {

View file

@ -15,7 +15,10 @@ uint32_t animation_duration_move = 500; // Animation move speed
uint32_t animation_duration_open = 400; // Animation open speed
uint32_t animation_duration_tag = 300; // Animation tag speed
uint32_t animation_duration_close = 300; // Animation close speed
double animation_curve[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
/* appearance */
unsigned int axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔