| 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; |
| }; |