diff options
| author | Federico Angelilli <code@fedang.net> | 2024-03-14 19:16:11 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-03-14 19:22:40 +0100 |
| commit | 164a2559cbc9012194484fba767dcd127b36a993 (patch) | |
| tree | b84f5d7f795cf759b6213273d67b2ba3f8824af5 /src/animate.c | |
| parent | 3be41d4351edf3dd4e9d9ac8fcadb38b5d580ef7 (diff) | |
Use a gradient pattern for the shine
Diffstat (limited to 'src/animate.c')
| -rw-r--r-- | src/animate.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/src/animate.c b/src/animate.c index ca5cbfe..7a6f77c 100644 --- a/src/animate.c +++ b/src/animate.c @@ -1,5 +1,6 @@ #include <glib.h> #include <stdbool.h> +#include <math.h> #include "animate.h" #include "state.h" @@ -32,47 +33,76 @@ typedef struct { Animation anim; gint64 start; gint64 duration; + int width; + cairo_pattern_t *gradient; } AnimationShine; -bool shine_paint(AnimationShine *anim, cairo_t *cr, const Layout *layout) +// FIXME: Not working for button group +bool shine_paint(AnimationShine *shine, cairo_t *cr, const Layout *layout) { gint64 now = g_get_monotonic_time(); - if (anim->start == 0) - anim->start = now; + if (shine->start == 0) + shine->start = now; - gint64 end = anim->start + anim->duration; - double pos = 1.0; + gint64 end = shine->start + shine->duration; + if (now > end) return false; - if (now <= end) { - double t = (double)(now - anim->start) / (end - anim->start); - pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0); - } + double t = (double)(now - shine->start) / (end - shine->start); + double pos = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0); - int w = 10; - int x = layout->x + pos * layout->width - w; + double angle = atan((double)layout->height / layout->width); + + // Make it double just to be sure + int h = 2 * (double)layout->height / cos(angle); + int x = layout->x + pos * layout->width - shine->width; int y = layout->y; - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba(cr, 1, 1, 1, 0.1); - cairo_rectangle(cr, x, y, w, layout->height); + cairo_matrix_t matrix; + cairo_matrix_init_translate(&matrix, -x, -y); + cairo_pattern_set_matrix(shine->gradient, &matrix); + + int dx = layout->x + layout->width / 2; + int dy = layout->y + layout->height / 2; + + cairo_translate(cr, dx, dy); + cairo_rotate(cr, -angle); + cairo_translate(cr, -dx, -dy); + + cairo_set_operator(cr, CAIRO_OPERATOR_ATOP); + cairo_set_source(cr, shine->gradient); + cairo_rectangle(cr, x, y - (h - layout->height) / 2, shine->width, h); cairo_fill(cr); - return pos < 1.0; + return true; } Animation *animation_shine_create(gint64 duration) { // Note the 0 initialization - AnimationShine *anim = g_malloc0(sizeof(AnimationShine)); - anim->anim.type = ANIM_SHINE; - anim->anim.paint = (DrawFunc)shine_paint; - anim->duration = duration; - return (gpointer)anim; + AnimationShine *shine = g_malloc0(sizeof(AnimationShine)); + shine->anim.type = ANIM_SHINE; + shine->anim.paint = (DrawFunc)shine_paint; + shine->duration = duration; + + // TODO: Change it depending on container size + shine->width = 20; + + shine->gradient = cairo_pattern_create_linear(0, 0, shine->width, 0); + cairo_pattern_add_color_stop_rgba(shine->gradient, 0, 1, 1, 1, 0); + cairo_pattern_add_color_stop_rgba(shine->gradient, 0.5, 1, 1, 1, 0.333); + cairo_pattern_add_color_stop_rgba(shine->gradient, 1, 1, 1, 1, 0); + + return (gpointer)shine; } +//XXX void animation_destroy(Animation *anim) { - //XXX + if (anim == NULL) return; + + if (anim->type == ANIM_SHINE) + cairo_pattern_destroy(CAST(anim, AnimationShine)->gradient); + g_free(anim); } |
