# Animation System Source: `src/dusk/animation/` ## Overview The animation system provides time-based keyframe interpolation with pluggable easing functions. It is intentionally minimal -- no skeleton, no blending, no state machine. Animations produce a single `float_t` value at a given time, which callers apply to whatever property they are animating. ## Keyframes (`keyframe.h`) ```c typedef struct { float_t time; // time in seconds this keyframe is at float_t value; // the value at this keyframe easingtype_t easing; // easing applied between this frame and the next } keyframe_t; ``` ## Animation (`animation.h`) ```c typedef struct { keyframe_t *keyframes; // caller-owned array uint16_t keyframeCount; } animation_t; void animationInit( animation_t *anim, keyframe_t *keyframes, uint16_t keyframeCount ); float_t animationGetValue(animation_t *anim, float_t time); // Returns the interpolated value at the given time. // Before the first keyframe: returns the first keyframe's value. // After the last keyframe: returns the last keyframe's value. ``` ## Easing functions (`easing.h`) ```c typedef float_t (*easingfn_t)(float_t t); // t in [0, 1], out in [0, 1] extern const easingfn_t EASING_FUNCTIONS[EASING_COUNT]; float_t easingApply(easingtype_t type, float_t t); ``` Available easing types: ``` EASING_LINEAR EASING_IN_SINE EASING_OUT_SINE EASING_IN_OUT_SINE EASING_IN_QUAD EASING_OUT_QUAD EASING_IN_OUT_QUAD EASING_IN_CUBIC EASING_OUT_CUBIC EASING_IN_OUT_CUBIC EASING_IN_QUART EASING_OUT_QUART EASING_IN_OUT_QUART EASING_IN_BACK EASING_OUT_BACK EASING_IN_OUT_BACK ``` ## Usage pattern ```c // Declare keyframes statically (no allocation): static keyframe_t kfs[] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_OUT_CUBIC }, { .time = 1.0f, .value = 1.0f, .easing = EASING_LINEAR }, }; animation_t anim; animationInit(&anim, kfs, 2); // In update loop: float_t alpha = animationGetValue(&anim, TIME.time); // Apply alpha to whatever is being animated. ``` ## Design notes - Keyframe arrays are caller-owned and not copied. Use static or long-lived arrays; do not allocate per-frame. - The system has no notion of looping -- wrap `time` with `fmodf` if you need a repeating animation. - For multi-property animations, use multiple `animation_t` instances sharing the same time source.