Apply themes and slots
Restyle a dotLottie animation at runtime from C - apply packaged or custom themes, and override colors, text, images, and numbers through slots.
Two mechanisms change how an animation looks without editing the animation itself. Themes apply a named set of overrides packaged in the .lottie file. Slots override individual named properties one at a time from your code.
Reach for a theme when a designer has already defined the variants you need, and for slots when the values come from your application — a user's accent color, a username, a score.
Both need a .lottie file. Plain Lottie JSON carries neither themes nor slot definitions.
Themes
Theming requires the theming feature, which is enabled by default.
Apply a theme packaged in the loaded file by its ID:
if (dotlottie_set_theme(player, "dark") != DOTLOTTIE_SUCCESS) {
/* no such theme, or the file has none */
}Return to the animation's original appearance:
dotlottie_reset_theme(player);Check which theme is active using the two-call string pattern:
size_t size = 0;
if (dotlottie_get_theme_id(player, NULL, &size) == DOTLOTTIE_SUCCESS) {
char *theme = malloc(size);
dotlottie_get_theme_id(player, theme, NULL);
/* ... */
free(theme);
}This returns InvalidParameter when no theme is applied.
Themes defined in your code
To supply a theme the file doesn't contain, pass its JSON directly:
const char *theme_json =
"{\"id\":\"brand\",\"rules\":["
"{\"id\":\"primary\",\"type\":\"Color\",\"value\":[0.1,0.4,0.9,1.0]}"
"]}";
dotlottie_set_theme_data(player, theme_json);The animation still has to define the slots the rules target, so this replaces the theme's values, not the animation's structure.
Calling dotlottie_load_animation() to switch to another animation in a multi-animation file resets the active theme.
Reapply it afterwards.
Slots
A slot is a named, overridable property that the animation's author exposed. Setting one replaces that property's value everywhere it appears.
Discover the available slots
Slot IDs come from the animation, so enumerate them rather than guessing:
uint32_t count = 0;
dotlottie_get_slot_ids_count(player, &count);
for (uint32_t i = 0; i < count; i++) {
size_t size = 0;
dotlottie_get_slot_id(player, i, NULL, &size);
char *id = malloc(size);
dotlottie_get_slot_id(player, i, id, NULL);
size_t type_size = 0;
dotlottie_get_slot_type(player, id, NULL, &type_size);
char *type = malloc(type_size);
dotlottie_get_slot_type(player, id, type, NULL);
printf("%s (%s)\n", id, type);
free(type);
free(id);
}Set a slot by type
Each slot has a type, and there is a typed setter for each:
| Slot type | Function | Values |
color | dotlottie_set_color_slot() | Three floats, 0.0–1.0 |
scalar | dotlottie_set_scalar_slot() | One float |
text | dotlottie_set_text_slot() | A null-terminated string |
vector | dotlottie_set_vector_slot() | Two floats |
position | dotlottie_set_position_slot() | Two floats |
image | dotlottie_set_image_slot_src() | A source string — see below |
dotlottie_set_color_slot(player, "accent", 0.1f, 0.4f, 0.9f);
dotlottie_set_scalar_slot(player, "stroke-width", 4.0f);
dotlottie_set_text_slot(player, "username", "Ada Lovelace");
dotlottie_set_position_slot(player, "badge-anchor", 120.0f, 48.0f);dotlottie_set_color_slot() takes floats from 0.0 to 1.0 and has no alpha parameter, while
dotlottie_set_background() takes four 8-bit values from 0 to 255. Passing 255.0f to a color slot does not
produce white.
Image slots
An image slot accepts three source forms:
dotlottie_set_image_slot_src(player, "avatar", "data:image/png;base64,iVBORw0KG...");
dotlottie_set_image_slot_src(player, "avatar", "https://example.com/avatar.png");
dotlottie_set_image_slot_src(player, "avatar", "profile.png"); /* from the file's i/ folder */A bare filename resolves against the i/ folder inside the loaded .lottie archive. Decoding the replacement needs the matching codec feature — tvg-png, tvg-jpg, or tvg-webp. Without it, the image silently fails to draw.
Setting many slots at once
For anything beyond simple static values — gradients, or keyframed values that animate — set slots from JSON:
const char *slots =
"{"
" \"accent\": {\"p\": {\"a\": 0, \"k\": [1.0, 0.0, 0.0]}},"
" \"caption\": {\"p\": {\"k\": [{\"t\": 0, \"s\": {\"t\": \"Hello\"}}]}}"
"}";
dotlottie_set_slots_str(player, slots);This is the most capable form of the slot API and matches the format used by the other dotLottie players. A single slot can be set the same way with dotlottie_set_slot_str().
Reading current values
size_t size = 0;
dotlottie_get_slots_str(player, NULL, &size);
char *json = malloc(size);
dotlottie_get_slots_str(player, json, NULL);
/* ... */
free(json);dotlottie_get_slot_str() does the same for one slot.
Removing overrides
Two functions undo slot changes, and the difference is bookkeeping rather than appearance:
| Function | Effect |
dotlottie_reset_slot() | Sets the slot back to the animation's original value, keeping it in the override set |
dotlottie_clear_slot() | Removes your override for the slot entirely |
dotlottie_reset_slots() | Resets every slot to its original value |
dotlottie_clear_slots() | Removes all overrides |
Either restores the animation's original look. Use clear when you want the slot to disappear from dotlottie_get_slots_str() output, and reset when you want it listed with its default. dotlottie_reset_slot() fails if the slot has no recorded default — usually a typo in the ID.
Redraw after changing appearance
Theme and slot changes take effect on the next render. A playing animation picks them up on its next tick, but a paused or stopped one needs an explicit redraw:
dotlottie_set_color_slot(player, "accent", 0.9f, 0.2f, 0.2f);
dotlottie_render(player);Learn more
Load animations — getting a
.lottiefile inState machines — drive theme and slot changes from interaction
C API reference — full signatures