Control playback
Drive a dotLottie animation from C with a tick loop, control speed, direction and looping, jump to frames, and play segments or named markers.
Playback in the native runtime is driven by you. There is no internal timer — you decide when the animation advances and when it draws, which makes it straightforward to integrate with an existing game loop, render loop, or frame callback.
The tick loop
dotlottie_tick() advances the animation by an elapsed time and redraws only if the visible frame changed. It reports whether it drew, so you can skip presenting a frame identical to the last one.
bool rendered = false;
dotlottie_tick(player, dt, &rendered);
if (rendered) {
present(buffer, width, height);
}Pass the time elapsed since your previous tick in seconds. A 60 fps frame is 0.0167, not 16.7. The example in
the generated dotlottie_player.h derives dt from a millisecond clock without converting, which runs the animation
1000× too fast — if your timer reports milliseconds, divide by 1000.
A complete loop using a monotonic clock:
#include <time.h>
static double now_seconds(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec + ts.tv_nsec / 1e9;
}
double last = now_seconds();
for (;;) {
double current = now_seconds();
float dt = (float)(current - last);
last = current;
bool rendered = false;
dotlottie_tick(player, dt, &rendered);
if (rendered) {
present(buffer, width, height);
}
}Passing a dt of 0.0 renders nothing new, and negative values are clamped to zero. Pass NULL for rendered if you always present regardless.
Redrawing without advancing
dotlottie_render() draws the current frame without moving time forward. Use it after changing something that affects appearance but not position — a theme, a slot, the background, the layout — or to repaint a paused animation after a resize.
dotlottie_set_frame(player, 42.0f);
dotlottie_render(player);Transport controls
dotlottie_play(player);
dotlottie_pause(player);
dotlottie_stop(player);dotlottie_pause() freezes at the current frame; dotlottie_stop() also resets to the beginning. Enabling autoplay before loading starts playback automatically:
dotlottie_set_autoplay(player, true);Read the current state with dotlottie_status():
| Status | Numeric | Meaning |
Idle | 0 | Created, nothing loaded yet |
Playing | 1 | Advancing on each tick |
Paused | 2 | Holding the current frame |
Stopped | 3 | Reset to the start |
Tweening | 4 | Interpolating between two frames |
Speed and direction
dotlottie_set_speed(player, 2.0f); /* double speed */
dotlottie_set_mode(player, Reverse);| Mode | Numeric | Behavior |
Forward | 0 | Start to end |
Reverse | 1 | End to start |
Bounce | 2 | Forward, then back, repeating |
ReverseBounce | 3 | Backward, then forward, repeating |
Speed is a plain multiplier: 0.5 is half speed, 2.0 is double. A speed of 0.0 stops the animation advancing while leaving it in the Playing state.
Looping
dotlottie_set_loop(player, true);
dotlottie_set_loop_count(player, 3); /* 0 means loop forever */dotlottie_set_loop_count() only applies when looping is enabled. Track progress with:
uint32_t completed = 0;
dotlottie_get_current_loop_count(player, &completed);
bool finished = dotlottie_is_complete(player);With infinite looping, dotlottie_is_complete() never returns true.
Frames and timing
float total = 0.0f, duration = 0.0f, current = 0.0f;
dotlottie_get_total_frames(player, &total);
dotlottie_get_duration(player, &duration); /* seconds */
dotlottie_get_current_frame(player, ¤t);Jump directly to a frame — fractional values are allowed, which is what makes scrubbing smooth:
dotlottie_set_frame(player, total * 0.75f);
dotlottie_render(player);Frames outside the playable range are rejected with InvalidParameter.
Frame interpolation
By default the player renders at sub-frame positions, producing smoother motion at high refresh rates. Turning it off snaps to whole frames and reduces rendering work:
dotlottie_set_use_frame_interpolation(player, false);Segments
A segment restricts playback to a frame range. Pass a two-element array of [start, end]:
float segment[2] = { 30.0f, 90.0f };
dotlottie_set_segment(player, &segment);Clear it by passing NULL to return to the full animation:
dotlottie_set_segment(player, NULL);Read the active segment back into an array you own:
float current_segment[2];
if (dotlottie_get_segment(player, ¤t_segment) == DOTLOTTIE_SUCCESS) {
printf("playing %.0f to %.0f\n", current_segment[0], current_segment[1]);
}This returns InvalidParameter when no segment is set.
Markers
Markers are named frame ranges defined in the animation, and they are usually a better choice than hardcoded frame numbers — the designer can move them without you changing code.
dotlottie_set_marker(player, "walk-cycle");Setting a marker applies its range as the current segment. Pass NULL to clear it.
Enumerate the markers a file defines:
uint32_t count = 0;
dotlottie_get_markers_count(player, &count);
for (uint32_t i = 0; i < count; i++) {
const char *name = NULL;
float start = 0.0f, end = 0.0f;
if (dotlottie_get_marker(player, i, &name, &start, &end) == DOTLOTTIE_SUCCESS) {
printf("%s: %.0f to %.0f\n", name, start, end);
}
}name points into memory the library owns — do not free it. Pass NULL for start or end if you only want the name.
To read the marker currently in effect, use the two-call string pattern:
size_t size = 0;
if (dotlottie_get_active_marker(player, NULL, &size) == DOTLOTTIE_SUCCESS) {
char *active = malloc(size);
dotlottie_get_active_marker(player, active, NULL);
/* ... */
free(active);
}Background color
dotlottie_set_background(player, 255, 255, 255, 255); /* opaque white */
dotlottie_set_background(player, 0, 0, 0, 0); /* transparent */Channels are 8-bit 0–255. Note that colors in the slot API use floats from 0.0 to 1.0 instead.
Audio
For animations with embedded audio, built with the audio feature:
dotlottie_set_audio_volume(player, 0.5f); /* 0.0 silent to 1.0 full */Both audio functions return FeatureNotEnabled in a build without the feature. On Android, call dotlottie_init_android() with your JavaVM and context once before loading an animation with audio.
Learn more
Handle events — react to loops completing and frames rendering
Apply themes and slots — change appearance at runtime
C API reference — full signatures