Gama C Library
Gama C API Documentation
animate.h
Go to the documentation of this file.
1/**
2 * @file animate.h
3 * @brief Provides utility functions for animating numerical values using various easing effects.
4 *
5 * This file contains a collection of inline functions designed to smoothly
6 * transition a `double` `value` towards a `target` value over time,
7 * using different animation curves (easing functions). These are commonly
8 * used for UI transitions, movement, and other visual effects.
9 *
10 * General notes on animation functions:
11 * - `value`: A pointer to the variable to be animated. This variable is modified directly.
12 * - `target`: The target value that `value` will animate towards.
13 * - `t`: The approximate time constant for the animation (in seconds).
14 * A smaller `t` generally results in a faster or more "springy" animation.
15 */
16#pragma once
17
18#include "_math.h"
19#include "gapi.h"
20#include <stdlib.h>
21
22/**
23 * @brief Animates a value towards a target with a smooth, ease-out effect.
24 *
25 * This function creates a spring-like motion that quickly moves towards the
26 * target and then gradually settles. The `t` parameter controls the speed
27 * and "stiffness" of the spring.
28 *
29 * @param value A pointer to the double value to animate. This value is updated in place.
30 * @param target The target value to animate towards.
31 * @param t The animation's approximate duration (time constant). A smaller 't' results in a
32 * faster, more immediate animation.
33 */
34void gm_anim_spring(double *value, double target, double t) {
35 if (value == NULL || t <= 0)
36 return;
37 double difference = target - *value;
38 double move = (gm_dt() * difference) / t;
39 if (fabs(move) >= fabs(difference)) {
40 *value = target;
41 } else {
42 *value += move;
43 }
44}
45
46/**
47 * @brief Animates a value towards a target with a quadratic ease-out effect.
48 *
49 * The animation starts fast and decelerates quadratically as it approaches
50 * the target.
51 *
52 * @param value A pointer to the double value to animate.
53 * @param target The target value to animate towards.
54 * @param t The animation's approximate duration (time constant).
55 */
56void gm_anim_ease_out_quad(double *value, const double target, double t) {
57 if (value == NULL || t <= 0)
58 return;
59 double difference = target - *value;
60 double speed_factor = 1.0 + sqrt(fabs(difference));
61 double move = (gm_dt() * difference * speed_factor) / t;
62
63 if (fabs(move) >= fabs(difference)) {
64 *value = target;
65 } else {
66 *value += move;
67 }
68}
69
70/**
71 * @brief Animates a value towards a target with a cubic ease-out effect.
72 *
73 * The animation starts very fast and decelerates cubically as it approaches
74 * the target, providing a more pronounced ease-out than `gm_anim_ease_out_quad`.
75 *
76 * @param value A pointer to the double value to animate.
77 * @param target The target value to animate towards.
78 * @param t The animation's approximate duration (time constant).
79 */
80void gm_anim_ease_out_cubic(double *value, double target, double t) {
81 if (value == NULL || t <= 0)
82 return;
83 double difference = target - *value;
84 double speed_factor = 1.0 + fabs(difference);
85 double move = (gm_dt() * difference * speed_factor) / t;
86
87 if (fabs(move) >= fabs(difference)) {
88 *value = target;
89 } else {
90 *value += move;
91 }
92}
93
94/**
95 * @brief Animates a value towards a target with a quadratic ease-in effect.
96 *
97 * The animation starts slow and accelerates quadratically as it approaches
98 * the target.
99 *
100 * @param value A pointer to the double value to animate.
101 * @param target The target value to animate towards.
102 * @param t The animation's approximate duration (time constant).
103 */
104void gm_anim_ease_in_quad(double *value, double target, double t) {
105 if (value == NULL || t <= 0)
106 return;
107 double difference = target - *value;
108 if (fabs(difference) < 0.0001) {
109 *value = target;
110 return;
111 }
112 double speed_factor = 1.0 / (1.0 + sqrt(fabs(difference)));
113 double move = (gm_dt() * difference * speed_factor) / t;
114
115 // For ease-in, it's possible for the calculated move to be tiny, so we ensure
116 // minimum progress.
117 if (fabs(move) < 0.0001) {
118 move = 0.0001 * (difference > 0 ? 1 : -1);
119 }
120
121 if (fabs(move) >= fabs(difference)) {
122 *value = target;
123 } else {
124 *value += move;
125 }
126}
127
128/**
129 * @brief Returns a sinusoidal animation value based on the global engine time (`gm_t()`).
130 * @param center The center value around which the animation oscillates.
131 * @param radius The amplitude of the oscillation.
132 * @param speed The speed of the oscillation.
133 * @param offset The phase offset for the oscillation.
134 * @return The current animated value based on a sine wave.
135 */
136static inline double gm_anim_sin(double center, double radius, double speed,
137 double offset) {
138 return center + (radius * sin(speed * (gm_t() + offset) * M_PI * 2));
139}
140
141/**
142 * @brief Returns a cosine animation value based on the global engine time (`gm_t()`).
143 * @param center The center value around which the animation oscillates.
144 * @param radius The amplitude of the oscillation.
145 * @param speed The speed of the oscillation.
146 * @param offset The phase offset for the oscillation.
147 * @return The current animated value based on a cosine wave.
148 */
149static inline double gm_anim_cos(double center, double radius, double speed,
150 double offset) {
151 return center + (radius * cos(speed * (gm_t() + offset) * M_PI * 2));
152}
void gm_anim_spring(double *value, double target, double t)
Animates a value towards a target with a smooth, ease-out effect.
Definition animate.h:34
void gm_anim_ease_in_quad(double *value, double target, double t)
Animates a value towards a target with a quadratic ease-in effect.
Definition animate.h:104
void gm_anim_ease_out_cubic(double *value, double target, double t)
Animates a value towards a target with a cubic ease-out effect.
Definition animate.h:80
void gm_anim_ease_out_quad(double *value, const double target, double t)
Animates a value towards a target with a quadratic ease-out effect.
Definition animate.h:56
Graphics API (GAPI) abstraction layer for Gama.
double cos(double x)
Calculates the cosine of an angle (in radians).
Definition math.h:105
double fabs(double x)
Calculates the absolute value of a double.
Definition math.h:369
double sin(double x)
Calculates the sine of an angle (in radians).
Definition math.h:128
double sqrt(double x)
Calculates the square root of x.
Definition math.h:339
#define M_PI
Alias for the mathematical constant Pi (π).
Definition math.h:16