aboutsummaryrefslogtreecommitdiff
path: root/src/effects/shine.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-09-21 01:26:52 +0200
committerFederico Angelilli <code@fedang.net>2024-09-21 01:26:52 +0200
commitb1bde5b6fe35f9ff94ae480d37c365410b94a43b (patch)
treee24b7b95d3049824a38a91a07b07ef98ae7d54bc /src/effects/shine.c
parent09190056721872069a82db51d97de6ab60f73a40 (diff)
Add shine effect
Diffstat (limited to 'src/effects/shine.c')
-rw-r--r--src/effects/shine.c83
1 files changed, 83 insertions, 0 deletions
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 <string.h>
+#include <math.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#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,
+};
+