blob: fe2848efd1a49f4cbddde6e5b72dde1b7f8ed6e4 [file] [log] [blame]
import { LottieAnimation, LottieAsset, LottieLayer } from '../types';
export interface ExtraLayerData {
layer: LottieLayer;
parentId: string;
precompName: string;
}
export interface TextData {
id: string;
name: string;
text: string;
maxChars?: number; // If not defined, we don't constrain the <textarea>
precompName: string;
items: ExtraLayerData[];
}
export const replaceTexts = (texts: TextData[], currentAnimation: LottieAnimation): LottieAnimation => {
const animation = JSON.parse(JSON.stringify(currentAnimation)) as LottieAnimation;
texts.forEach((textData) => {
textData.items.forEach((item: ExtraLayerData) => {
let layers;
// Searches for composition that contains this layer
if (!item.parentId) {
layers = animation.layers;
} else {
const asset = animation.assets.find((assetItem: LottieAsset) => assetItem.id === item.parentId);
layers = asset ? asset.layers : [];
}
// Replaces current animation layer with new layer value
layers.forEach((layer: LottieLayer, index: number) => {
if (layer.ind === item.layer.ind && layer.nm === item.layer.nm) {
layers[index] = item.layer;
}
});
});
});
return animation;
};
const replaceTextsInLayers = (textsDictionary: Record<string, string>, layers: LottieLayer[]) => {
const LAYER_TEXT_TYPE = 5;
layers.forEach((layer: LottieLayer) => {
if (layer.ty === LAYER_TEXT_TYPE && textsDictionary[layer.nm]) {
// It's read as: Layer > Text Element > Text document > First Keyframe > Start Value > Text
const textElement: any = layer.t;
textElement.d.k[0].s.t = textsDictionary[layer.nm];
}
});
};
export const replaceTextsByLayerName = (texts: TextData[], currentAnimation: LottieAnimation): LottieAnimation => {
if (!texts) {
return currentAnimation;
}
// Make a copy of the original animation.
const animation: LottieAnimation = JSON.parse(JSON.stringify(currentAnimation)) as LottieAnimation;
// Create dictionary to access data by name instead of iterating on every layer
const textsDictionary = texts.reduce((dict: Record<string, string>, text: TextData) => {
dict[text.name] = text.text;
return dict;
}, {});
replaceTextsInLayers(textsDictionary, animation.layers);
animation.assets
.filter((asset: LottieAsset) => asset.layers)
.forEach((asset: LottieAsset) => replaceTextsInLayers(textsDictionary, asset.layers));
return animation;
};