How does theming work?
How does the themeing works
I'll explore the codebase to understand how theming works in the dotlottie-web repository.
Now let me look at the core implementation of theming:
Let me check the core implementation and how it interacts with the theme:
Let me check the core directory structure:
Let me read the dotlottie-player.types.ts to understand the WASM bindings:
Perfect! Now let me check how themes are defined in the manifest and look at some examples:
Now let me check the documentation or README for more context on theming:
Let me check the packages/web README:
Let me look at how themes are accessed and structured in more detail:
Excellent! Now let me create a comprehensive summary. Let me also check the manifest property to understand the structure better:
Perfect! Now I have a comprehensive understanding. Let me create a detailed summary for the user.
##How Theming Works in dotlottie-web
Based on my exploration of the source code, here's how theming works in this library:
###Core Concepts
Theming in dotlottie-web is centered around two main approaches:
- Named Themes - Pre-defined themes bundled in the dotLottie file
- Theme Data - Custom theme colors provided as JSON at runtime
###Architecture
The theming system is built on several layers:
####1. Manifest-Level Themes
Themes are declared in the .dotlottie file's manifest, which you can access via:
const themes = dotLottie.manifest?.themes ?? [];
// Returns: Array<{ id: string }>
Each animation within a dotLottie can have multiple themes:
const animation = dotLottie.manifest?.animations[0];
const animationThemes = animation?.themes ?? []; // Theme IDs for this animation
####2. Setting Themes
By Theme ID:
// Load a theme from the manifest
const result = dotLottie.setTheme('theme_id');
// Returns: boolean (true if successful)
With Custom Data:
const themeData = {
c0: { // Color slot ID
p: {
a: 0,
k: [1, 0, 1], // RGB color values
},
},
};
const result = dotLottie.setTheme(JSON.stringify(themeData));
Reset to Default:
dotLottie.resetTheme();
####3. Configuration
You can set a theme during initialization:
const dotLottie = new DotLottie({
canvas,
src: 'animation.lottie',
themeId: 'initial_theme',
});
Or as a prop in framework wrappers (React, Vue, Solid):
// React
<DotLottie src="animation.lottie" themeId="theme_id" />
// Vue
<DotLottie src="animation.lottie" themeId="theme_id" />
// Solid
<DotLottie src="animation.lottie" themeId={themeId()} />
###Core Implementation Details
The implementation uses:
- WASM Core: All theme operations are delegated to the WASM module (
dotlottie-player.wasm) - Render Cycle: When a theme is set, the player automatically:
- Calls
_dotLottieCore.setTheme(themeId) - Invokes
_dotLottieCore.render() - Triggers
_draw()to update the canvas
- Calls
public setTheme(themeId: string): boolean {
if (this._dotLottieCore === null) return false;
const themeLoaded = this._dotLottieCore.setTheme(themeId);
if (themeLoaded) {
this._dotLottieCore.render();
this._draw();
}
return themeLoaded;
}
###Getting Active Theme
const currentTheme = dotLottie.activeThemeId;
###Theme Transformation (Advanced)
There's a static utility to transform theme data:
DotLottie.transformThemeToLottieSlots(theme: string, slots: string): string
This is a WASM binding that converts theme data to Lottie slot format.
###Practical Example
const dotLottie = new DotLottie({
canvas: document.getElementById('canvas'),
src: 'multi_theme_animation.lottie',
});
dotLottie.addEventListener('load', () => {
// Get available themes
const themes = dotLottie.manifest?.themes ?? [];
// Show theme selector
themes.forEach(theme => {
const option = document.createElement('option');
option.value = theme.id;
option.textContent = theme.id;
themeSelect.appendChild(option);
});
// Set theme on selection
themeSelect.addEventListener('change', (e) => {
if (e.target.value) {
dotLottie.setTheme(e.target.value);
} else {
dotLottie.resetTheme();
}
});
});
This is how the demo example works - it dynamically populates a theme selector from the manifest and applies the selected theme when the user changes the selection.
Can I dynamically generate themes.
Let me search for information about dynamic theme generation in the codebase.
Perfect! Let me search for more examples and understand the theme data structure better:
Let me check if there are any documentation or examples about the theme data structure:
Great! Now I have comprehensive information. Let me provide a detailed answer about dynamic theme generation.
##Yes! You Can Dynamically Generate Themes
Based on the source code and documentation, you absolutely can dynamically generate themes at runtime using the setThemeData() method. This allows you to create custom themes on-the-fly without needing them pre-bundled in the dotLottie file.
###How It Works
The key is using setThemeData() which accepts a JSON object that defines color overrides for animation properties:
const themeData = {
slot_id_1: {
p: {
a: 0,
k: [r, g, b, a] // RGB/RGBA values in 0-1 range
}
},
slot_id_2: {
p: {
a: 0,
k: [r, g, b, a]
}
}
};
const result = dotLottie.setThemeData(JSON.stringify(themeData));
###Theme Data Structure
The theme data structure follows the Lottie animation format:
- Slot ID: The identifier of the animated property you want to override (e.g.,
c0,ball_color,background_color) pobject: Contains the property valuea: Animation flag (0 = static, 1 = animated)k: The value array- For colors:
[r, g, b]or[r, g, b, a]where values are 0-1 range (not 0-255)
- For colors:
###Example: Creating a Dynamic Color Theme
import { DotLottie } from '@lottiefiles/dotlottie-web';
const dotLottie = new DotLottie({
canvas: document.getElementById('canvas'),
src: 'animation.lottie'
});
dotLottie.addEventListener('load', () => {
// Create a theme dynamically at runtime
const dynamicTheme = {
ball_color: {
p: {
a: 0,
k: [0.1, 1, 0.5] // Light green (RGB normalized 0-1)
}
},
background_color: {
p: {
a: 0,
k: [1, 1, 1] // White
}
}
};
// Apply the dynamic theme
const result = dotLottie.setThemeData(JSON.stringify(dynamicTheme));
if (result) {
console.log('Theme applied successfully!');
}
});
###Practical Example: Color Picker
Here's a complete example of dynamically generating themes from user input:
import { DotLottie } from '@lottiefiles/dotlottie-web';
const dotLottie = new DotLottie({
canvas: document.getElementById('canvas'),
src: 'animation.lottie'
});
// Utility: Convert hex color to 0-1 RGB
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [
parseInt(result[1], 16) / 255,
parseInt(result[2], 16) / 255,
parseInt(result[3], 16) / 255
] : [0, 0, 0];
}
// Listen for color changes
document.getElementById('colorPicker').addEventListener('change', (e) => {
const hex = e.target.value;
const [r, g, b] = hexToRgb(hex);
// Create and apply dynamic theme
const themeData = {
ball_color: {
p: {
a: 0,
k: [r, g, b]
}
}
};
dotLottie.setThemeData(JSON.stringify(themeData));
});
###Important Considerations
-
Slot IDs Must Exist: You need to know the slot ID of properties you want to theme. These must be defined in the animation's JSON.
-
Color Range: Colors must be in 0-1 range, not 0-255:
- RGB(255, 255, 255) → [1, 1, 1]
- RGB(0, 128, 255) → [0, 0.5, 1]
-
Animation Flag: The
aproperty indicates if the value is animated:a: 0= static valuea: 1= animated value
-
Return Value: Both
setTheme()andsetThemeData()return a boolean:true= theme applied successfullyfalse= failed (invalid format or slot IDs not found)
-
Reactive Updates: When applied, the theme automatically:
- Renders the animation with new values
- Updates the canvas
###Advanced: Multiple Color Slots
const multiSlotTheme = {
primary_color: { p: { a: 0, k: [1, 0, 0] } }, // Red
secondary_color: { p: { a: 0, k: [0, 1, 0] } }, // Green
accent_color: { p: { a: 0, k: [0, 0, 1] } }, // Blue
background: { p: { a: 0, k: [0.1, 0.1, 0.1] } } // Dark gray
};
dotLottie.setThemeData(JSON.stringify(multiSlotTheme));
###Finding Slot IDs in Your Animation
If you're unsure what slot IDs are available:
- Open the animation in the Lottie JSON Editor
- Search for properties with
"sid"(slot ID) fields - The value of
"sid"is what you use in your theme data
This makes theming extremely flexible—you can generate themes based on user preferences, time of day, system theme, or any other runtime data!
END OF POST
Claude Haiku 4.5