Managing Assets
Understand how dotlottie-js handles image and audio assets in Lottie animations, and learn to retrieve bundled assets.
Core Concepts: Managing Assets (Images & Audio)
Lottie animations often rely on external assets like images and audio files. dotlottie-js handles the bundling of these assets into the .lottie file primarily through the animations you add and the build() process.
How Assets are Handled
In dotlottie-js, you typically do not explicitly add individual image or audio files directly to the DotLottie instance. Instead, asset management works as follows:
Define Assets in Lottie JSON: Ensure the Lottie JSON data for your animations correctly defines the assets it uses within its
assetsarray.For images, this typically involves an entry with
id,w,h,u(path, often empty for embedded), andp(filename or Base64 data).For audio, similar entries exist, identified by specific properties (like
extra.audioparams).Crucially, if embedding assets, the
pproperty should contain the Base64 encoded data (e.g.,data:image/png;base64,...) or the filename that corresponds to an asset that will be discovered.
Add Animation: Add the Lottie animation(s) containing these asset definitions to your
DotLottieinstance usingdotlottie.addAnimation({ id: '...', data: yourLottieJsonWithAssets })ordotlottie.addAnimation({ id: '...', url: '...' }).Build Process: When you call
await dotlottie.build(), the library automatically:Discovers Assets: Scans the
assetsarrays of all added animations.Extracts Data: If assets are embedded (Base64 in
p), it extracts the data.Bundles Assets: Writes the extracted or discovered asset data into appropriate directories within the
.lottiearchive (e.g.,images/,audio/). It assigns filenames based on the asset definitions.Updates Lottie JSON: Modifies the
u(path) andp(filename) properties within the Lottie JSON files inside the archive to correctly reference the bundled asset paths (e.g.,u: 'images/', p: 'image_1.png').De-duplicates (Optional): If
enableDuplicateImageOptimization: truewas set in the constructor, it attempts to identify and store identical image assets only once.
In summary: Asset management is primarily implicit. You provide animations with correctly defined assets, and build() handles the bundling and linking.
Retrieving Bundled Assets
After loading a .lottie file (fromURL, fromArrayBuffer) or after calling build() on a new instance, you can access the discovered and bundled assets.
Retrieving All Images: dotlottie.getImages()
Returns an array of objects, each representing a bundled image asset.
// Assuming 'dotlottie' is a loaded or built instance
const allImages = dotlottie.getImages();
console.log(`Found ${allImages.length} images.`);
for (const image of allImages) {
console.log(`Image ID: ${image.id}, FileName: ${image.fileName}`);
// Access image data (async methods)
try {
// Get as ArrayBuffer
// const arrayBuffer = await image.toArrayBuffer();
// console.log(` ArrayBuffer size: ${arrayBuffer.byteLength}`);
// Get as Base64 string
// const base64 = await image.toBase64();
// console.log(` Base64 preview: ${base64.substring(0, 60)}...`);
// Get as Blob (Browser only)
// const blob = await image.toBlob();
// console.log(` Blob size: ${blob.size}, type: ${blob.type}`);
// const objectUrl = URL.createObjectURL(blob); // Create URL for <img> src
// console.log(` Object URL: ${objectUrl}`);
// URL.revokeObjectURL(objectUrl); // Clean up later
} catch (error) {
console.error(`Error getting data for image ${image.id}:`, error);
}
}Each object representing an image in the returned array provides access to:
id: The unique ID used in Lottie JSON assets.fileName: The filename within the.lottiearchive.Methods to retrieve the image data asynchronously, such as
toArrayBuffer(),toBase64(), andtoBlob().
Retrieving All Audio: dotlottie.getAudio()
Returns an array of objects, each representing a bundled audio asset. Works identically to getImages().
const allAudio = dotlottie.getAudio();
console.log(`Found ${allAudio.length} audio assets.`);
for (const audio of allAudio) {
console.log(`Audio ID: ${audio.id}, FileName: ${audio.fileName}`);
// Use await audio.toArrayBuffer(), await audio.toBase64(), await audio.toBlob()
}Each object representing an audio asset provides similar access to id, fileName, and data retrieval methods.
Finding Assets Used by a Specific Animation
To determine which assets belong to a particular animation, you need to:
Get the animation object (
await dotlottie.getAnimation(animId)).Get its Lottie JSON data (
await animation.toJSON()).Inspect the
assetsarray within the Lottie JSON data. Theidof assets listed there corresponds to theidof the objects returned bygetImages()andgetAudio().
async function findAnimationAssets(animationId) {
// Get the animation object - needs await
const animation = await dotlottie.getAnimation(animationId);
if (!animation) {
console.log(`Animation ${animationId} not found.`);
return;
}
const lottieJson = await animation.toJSON(); // Get the Lottie JSON data
if (!lottieJson.assets || lottieJson.assets.length === 0) {
console.log(`Animation ${animationId} has no assets defined.`);
return;
}
const imageAssets = dotlottie.getImages();
const audioAssets = dotlottie.getAudio();
console.log(`Assets used by animation ${animationId}:`);
lottieJson.assets.forEach((assetDef) => {
// Check if it's an image asset (has w, h)
if (typeof assetDef.w === "number" && typeof assetDef.h === "number") {
const foundImage = imageAssets.find((img) => img.id === assetDef.id);
if (foundImage) {
console.log(` - Image: ID=${foundImage.id}, FileName=${foundImage.fileName}`);
}
}
// Add similar check for audio assets if identifiable (e.g., by filename extension or specific properties)
// Example check based on structure often seen with audio assets:
else if (assetDef.extra && assetDef.extra.audioparams) {
const foundAudio = audioAssets.find((aud) => aud.id === assetDef.id);
if (foundAudio) {
console.log(` - Audio: ID=${foundAudio.id}, FileName=${foundAudio.fileName}`);
}
}
});
}
// findAnimationAssets('animation_1');Replacing/Modifying Assets
Since you cannot directly add or remove individual assets via the DotLottie API, modifying an asset involves modifying the Lottie JSON data of the animation(s) that use it:
Load: Load the
.lottiefile (fromURLorfromArrayBuffer). These methods return a new instance ofDotLottie.Get Animation Object: Retrieve the animation object you want to modify (
await dotlottie.getAnimation(animationId)).Get JSON: Get the Lottie JSON data for that animation (
await animation.toJSON()).Modify Assets in JSON: Find the asset entry in the
assetsarray of the JSON object.To replace an embedded asset (Base64), update the
pproperty with the new Base64 data string.To replace an asset that will be bundled, ensure the new asset data is available and the
idremains the same. (This workflow is less direct, as the bundling happens duringbuild). A safer approach might be to modify the source Lottie JSON before adding it todotlottie-js.
Remove Old Animation: Remove the original animation instance from the
DotLottieobject usingdotlottie.removeAnimation(animationId).Add Modified Animation: Add the animation back using
dotlottie.addAnimation()with the same ID but providing the modified Lottie JSON object in thedataproperty.Rebuild: Call
await dotlottie.build(). This will process the modified Lottie JSON, discover/bundle the (potentially new) asset data, and update references.Export: Export the modified
.lottiefile (toArrayBuffer,download, etc.).
// Conceptual Example: Replacing an embedded logo in an animation's JSON data
async function replaceEmbeddedLogo(dotLottieUrl, animationId, logoAssetId, newLogoBase64Data) {
try {
// 1. Load
const dotlottie = new DotLottie().fromURL(dotLottieUrl);
// 2. Get Animation Object
const animation = await dotlottie.getAnimation(animationId);
if (!animation) throw new Error(`Animation ${animationId} not found`);
// 3. Get JSON
const lottieJson = await animation.toJSON();
// 4. Modify Assets in JSON
let foundAsset = false;
if (lottieJson.assets) {
const assetIndex = lottieJson.assets.findIndex((asset) => asset.id === logoAssetId);
if (assetIndex !== -1) {
lottieJson.assets[assetIndex].p = newLogoBase64Data; // Update Base64 data
foundAsset = true;
console.log(`Updated asset ${logoAssetId} in Lottie JSON data.`);
}
}
if (!foundAsset) throw new Error(`Asset ${logoAssetId} not found in animation ${animationId}`);
// 5. Remove Old Animation
dotlottie.removeAnimation(animationId);
// 6. Add Modified Animation (pass other properties like name, loop etc. if needed)
dotlottie.addAnimation({
id: animationId,
data: lottieJson, // Use the modified JSON
name: animation.name,
loop: animation.loop,
// ... copy other relevant properties from original animation instance
});
console.log("Re-added animation with modified data.");
// 7. Rebuild
await dotlottie.build();
console.log("DotLottie rebuilt.");
// 8. Export
await dotlottie.download("updated-animation.lottie");
console.log("Exported updated dotLottie.");
} catch (error) {
console.error("Error replacing asset:", error);
}
}
// const newLogoBase64 = "data:image/png;base64,..." // Your new logo data
// replaceEmbeddedLogo('original.lottie', 'anim_1', 'logo_asset_id', newLogoBase64);This process is more involved than direct asset replacement but reflects the API's focus on managing assets through the animations that contain them.
By understanding how dotlottie-js handles assets implicitly via animation data and the build process, you can effectively bundle images and audio into your .lottie files.
Next up: Managing Themes