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.

Switching animations clears the theme

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 typeFunctionValues
colordotlottie_set_color_slot()Three floats, 0.01.0
scalardotlottie_set_scalar_slot()One float
textdotlottie_set_text_slot()A null-terminated string
vectordotlottie_set_vector_slot()Two floats
positiondotlottie_set_position_slot()Two floats
imagedotlottie_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);
Slot colors are floats, background is bytes

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:

FunctionEffect
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

Last updated: August 25, 2026 at 6:23 AMEdit this page