Gama C Library
Gama C API Documentation
Loading...
Searching...
No Matches
animate.h
Go to the documentation of this file.
1#pragma once
2
3#include "gapi.h"
4#include <math.h>
5#include <stdio.h>
6
7/**
8 * @file animate.h
9 * @brief Functions for animating values with various easing functions.
10 *
11 * General notes on animation functions:
12 * - value: A pointer to the variable to be animated.
13 * - target: The target value to animate towards.
14 * - t: The approximate time the animation should take (in seconds). It
15 * acts as a time constant.
16 */
17
18/**
19 * @brief Moves a value towards a target with spring-like motion (exponential
20 * ease-out).
21 * @param value A pointer to the double value to animate.
22 * @param target The target value to animate towards.
23 * @param t The animation's approximate duration. A smaller 't' results in a
24 * faster animation.
25 */
26void gm_anim_spring(double *value, double target, double t) {
27 if (value == NULL || t <= 0)
28 return;
29 double difference = target - *value;
30 double move = (gm_dt() * difference) / t;
31 if (fabs(move) >= fabs(difference)) {
32 *value = target;
33 } else {
34 *value += move;
35 }
36}
37
38/**
39 * @brief Starts fast and decelerates quadratically to the target. More
40 * pronounced than spring.
41 * @param value A pointer to the double value to animate.
42 * @param target The target value to animate towards.
43 * @param t The animation's approximate duration.
44 */
45void gm_anim_ease_out_quad(double *value, const double target, double t) {
46 if (value == NULL || t <= 0)
47 return;
48 double difference = target - *value;
49 double speed_factor = 1.0 + sqrt(fabs(difference));
50 double move = (gm_dt() * difference * speed_factor) / t;
51
52 if (fabs(move) >= fabs(difference)) {
53 *value = target;
54 } else {
55 *value += move;
56 }
57}
58
59/**
60 * @brief Starts very fast and decelerates cubically to the target. More
61 * pronounced than quad.
62 * @param value A pointer to the double value to animate.
63 * @param target The target value to animate towards.
64 * @param t The animation's approximate duration.
65 */
66void gm_anim_ease_out_cubic(double *value, double target, double t) {
67 if (value == NULL || t <= 0)
68 return;
69 double difference = target - *value;
70 double speed_factor = 1.0 + fabs(difference);
71 double move = (gm_dt() * difference * speed_factor) / t;
72
73 if (fabs(move) >= fabs(difference)) {
74 *value = target;
75 } else {
76 *value += move;
77 }
78}
79
80/**
81 * @brief Starts slow and accelerates quadratically towards the target.
82 * @param value A pointer to the double value to animate.
83 * @param target The target value to animate towards.
84 * @param t The animation's approximate duration.
85 */
86void gm_anim_ease_in_quad(double *value, double target, double t) {
87 if (value == NULL || t <= 0)
88 return;
89 double difference = target - *value;
90 if (fabs(difference) < 0.0001) {
91 *value = target;
92 return;
93 }
94 double speed_factor = 1.0 / (1.0 + sqrt(fabs(difference)));
95 double move = (gm_dt() * difference * speed_factor) / t;
96
97 // For ease-in, it's possible for the calculated move to be tiny, so we ensure
98 // minimum progress.
99 if (fabs(move) < 0.0001) {
100 move = 0.0001 * (difference > 0 ? 1 : -1);
101 }
102
103 if (fabs(move) >= fabs(difference)) {
104 *value = target;
105 } else {
106 *value += move;
107 }
108}
109
110/**
111 * @brief Returns a sinusoidal animation value based on time.
112 * @param center The center value around which the animation oscillates.
113 * @param radius The amplitude of the oscillation.
114 * @param speed The speed of the oscillation.
115 * @param offset The phase offset for the oscillation.
116 * @return The current animated value based on a sine wave.
117 */
118static inline double gm_anim_sin(double center, double radius, double speed,
119 double offset) {
120 return center + (radius * sin(speed * (gm_t() + offset) * M_PI * 2));
121}
122
123/**
124 * @brief Returns a cosine animation value based on time.
125 * @param center The center value around which the animation oscillates.
126 * @param radius The amplitude of the oscillation.
127 * @param speed The speed of the oscillation.
128 * @param offset The phase offset for the oscillation.
129 * @return The current animated value based on a cosine wave.
130 */
131static inline double gm_anim_cos(double center, double radius, double speed,
132 double offset) {
133 return center + (radius * cos(speed * (gm_t() + offset) * M_PI * 2));
134}
void gm_anim_spring(double *value, double target, double t)
Moves a value towards a target with spring-like motion (exponential ease-out).
Definition animate.h:26
void gm_anim_ease_in_quad(double *value, double target, double t)
Starts slow and accelerates quadratically towards the target.
Definition animate.h:86
void gm_anim_ease_out_cubic(double *value, double target, double t)
Starts very fast and decelerates cubically to the target. More pronounced than quad.
Definition animate.h:66
void gm_anim_ease_out_quad(double *value, const double target, double t)
Starts fast and decelerates quadratically to the target. More pronounced than spring.
Definition animate.h:45