From b1bde5b6fe35f9ff94ae480d37c365410b94a43b Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sat, 21 Sep 2024 01:26:52 +0200 Subject: Add shine effect --- src/effects/scheme.c | 2 ++ src/effects/shine.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/effects/shine.c (limited to 'src/effects') diff --git a/src/effects/scheme.c b/src/effects/scheme.c index 0d70dec..9de96a1 100644 --- a/src/effects/scheme.c +++ b/src/effects/scheme.c @@ -1,8 +1,10 @@ #include "scheme.h" extern const effect_scheme_t effect_pulse_scheme; +extern const effect_scheme_t effect_shine_scheme; const effect_scheme_t *effect_schemes[] = { &effect_pulse_scheme, + &effect_shine_scheme, NULL }; diff --git a/src/effects/shine.c b/src/effects/shine.c new file mode 100644 index 0000000..3a873fe --- /dev/null +++ b/src/effects/shine.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +#include "scheme.h" + +#include "../any_log.h" + +typedef struct { + effect_t effect; + unsigned int width; + cairo_pattern_t *gradient; +} effect_shine_t; + +extern double cubic_bezier(double x, double a, double b, double c, double d); + +static void effect_shine_post(effect_t *effect, layout_t *layout, cairo_t *cr) +{ + struct timespec now; + timespec_get(&now, TIME_UTC); + + struct timespec diff = timespec_diff(now, effect->start); + double t = (double)timespec_to_ms(diff) / timespec_to_ms(effect->info->duration); + double s = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0); + + effect_shine_t *shine = (effect_shine_t *)effect; + + unsigned int x = layout->x + s * layout->width - shine->width; + unsigned int y = layout->y; + + cairo_set_operator(cr, CAIRO_OPERATOR_ATOP); + cairo_set_source(cr, shine->gradient); + cairo_rectangle(cr, x, y - layout->height / 2, shine->width, layout->height); + cairo_fill(cr); +} + +static effect_t *effect_shine_allocate(const effect_info_t *info) +{ + effect_shine_t *effect = malloc(sizeof(effect_shine_t)); + effect_init((effect_t *)effect, info); + + effect->width = 20; + effect->gradient = cairo_pattern_create_linear(0, 0, effect->width, 0); + cairo_pattern_add_color_stop_rgba(effect->gradient, 1, 1, 1, 1, 0.1); + cairo_pattern_add_color_stop_rgba(effect->gradient, 0.5, 1, 1, 1, 0.8); + cairo_pattern_add_color_stop_rgba(effect->gradient, 1, 1, 1, 1, 0.1); + + return (effect_t *)effect; +} + +static void effect_shine_finalize(effect_shine_t *effect) +{ + cairo_pattern_destroy(effect->gradient); + free(effect); +} + +static bool effect_shine_validate(effect_info_t *info, const effect_scheme_t *scheme) +{ + return true; +} + +static const config_entry_t effect_shine_entries[] = { + { 0 }, +}; + +const effect_scheme_t effect_shine_scheme = { + .name = "shine", + .info = { + .duration = { + .tv_sec = 0, + .tv_nsec = 200000000, + }, + .allocate = effect_shine_allocate, + .finalize = (effect_finalize_t)effect_shine_finalize, + .post = effect_shine_post, + }, + .size = sizeof(unsigned int), + .entries = effect_shine_entries, + .validate = effect_shine_validate, +}; + -- cgit v1.2.3