Skip to main content

Easing Function (easing)

Easing animation module based on cubic Bezier curves, implementing various acceleration and deceleration effects by defining curve control points.

Bezier Curve

struct bezier_t {
float ax, bx, cx; /* Cubic polynomial coefficients for X component */
float ay, by, cy; /* Cubic polynomial coefficients for Y component */
};

A standard cubic Bezier curve is defined by 4 control points: P0=(0,0), P1=(x1,y1), P2=(x2,y2), P3=(1,1). bezier_init converts control points into polynomial coefficients, bezier_calc evaluates via Newton's method + bisection.

void bezier_init(struct bezier_t * b, float x1, float y1, float x2, float y2);

Initialize a Bezier curve, x1/y1 and x2/y2 are the two middle control points, range [0, 1].

float bezier_calc(struct bezier_t * b, float t);

Calculate the curve value at time t (0~1). Returns 0 for t <= 0, returns 1 for t >= 1.

Easing Animation

struct easing_t {
struct bezier_t bezier; /* Bezier curve */
float start; /* Start value */
float stop; /* End value */
float duration; /* Duration (seconds) */
float acc; /* Accumulated time */
};

API

void easing_init(struct easing_t * e, float start, float stop, float duration, float x1, float y1, float x2, float y2);

Initialize an easing animation. start/stop define the value range, duration is the total duration, x1/y1/x2/y2 are the Bezier control points.

float easing_calc(struct easing_t * e, float t);

Calculate the value at time t (seconds).

float easing_step(struct easing_t * e, float dt);

Advance by dt seconds and return the current value. Internal accumulated time is automatically incremented.

int easing_finished(struct easing_t * e);

Whether the animation has finished. Returns 1 when finished.

Common Curve Parameters

Effectx1y1x2y2
Linear0011
Ease In0.42011
Ease Out000.581
Ease In Out0.4200.581
Ease Out Elastic0.68-0.550.271.55

Usage Examples

Position Animation

struct easing_t e;
easing_init(&e, 0, 300, 0.5, 0.42, 0, 0.58, 1); /* ease in out, 0→300, 0.5s */

while(!easing_finished(&e))
{
float pos = easing_step(&e, 0.016); /* approximately 16ms per frame */
set_position(pos);
}

Direct Calculation at Specific Time

struct easing_t e;
easing_init(&e, 0, 100, 1.0, 0, 0, 0.58, 1);
float v = easing_calc(&e, 0.5); /* value at 0.5 seconds */

Using Bezier Curve Independently

struct bezier_t b;
bezier_init(&b, 0.42, 0, 0.58, 1);
float progress = bezier_calc(&b, 0.5); /* curve value at 50% progress */