# General Translation Knowledge Base: 如何翻译 Lottie 动画？
URL: https://generaltranslation.com/zh/kb/translate-lottie-animations.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 翻译动画文本图层中的字符串（存储在 Lottie JSON 的 t.d.k[].s.t 中），然后检查每条译文能否放进对应的文本框、字体是否支持新的文字体系，以及是否有文本被导出成了形状。你可以按语言分别重新导出、在运行时替换文本，或用脚本修改 JSON；General Translation 的 CLI 可以翻译 dotLottie 1.0 .lottie 文件，并重新调整布局。
Category: 翻译
Last updated: 2026-10-28
Authors: General Translation Team
Published: 2026-10-28

Lottie 动画本质上就是 JSON，通常借助 Bodymovin 插件从 After Effects 导出。其中的文字位于文本图层内，而不是存放在单独的字符串文件中。翻译 Lottie 动画，就是在不破坏动画的前提下，按语言替换这些文本。文字本身并不难处理，真正的难点在于与之相关的固定文本框尺寸、内嵌字体和字形，以及从右到左书写的文字体系。

## Lottie 文件中文本的存储位置

图层通过 `ty` 区分类型，文本图层的类型为 `5`。每个文本图层都有一个 `t` 对象，其文档 `t.d` 将关键帧保存在 `k` 中；每个关键帧的 `s` 是一个文本文档，其中的 `t` 就是字符串本身，换行符写作 `\r`。文本文档还会指定字体 (`f`) 和字号 (`s`) ；如果是框式文本，还会指定文本框的大小 (`sz`) 和位置 (`ps`) 。如果文本在动画播放过程中发生变化，则每次变化对应一个关键帧 ([Lottie 文档：Text](https://lottiefiles.github.io/lottie-docs/text/)、[Layers](https://lottiefiles.github.io/lottie-docs/layers/)) ：

```json title="animation.json (excerpt)"
{
  "fonts": {
    "list": [
      { "fName": "Inter-Bold", "fFamily": "Inter", "fStyle": "Bold", "origin": 0 }
    ]
  },
  "layers": [
    {
      "ty": 5,
      "nm": "Headline",
      "t": {
        "d": {
          "k": [
            { "t": 0, "s": { "t": "Start your free trial", "f": "Inter-Bold", "s": 48, "sz": [600, 80], "ps": [-300, -40] } }
          ]
        }
      }
    }
  ]
}
```

另外还有三处需要注意：

* **预合成 (Precomps) 。** 嵌套合成的图层保存在 `assets[].layers` 中，因此文本图层也可能出现在这里，而不只是在顶层的 `layers` 数组中。
* **字体与字形。** `fonts.list` 列出了每种字体的名称。如果设计师开启了 Bodymovin 的 **Glyphs** 设置，文件中还会有一个 `chars` 数组，存放所用到的每个字符的轮廓；如果关闭该设置，播放器就需要字体文件本身 ([Lottie: After Effects export settings](https://lottie.airbnb.tech/#/after-effects)) 。字形可以在 Android 和 Web 上渲染，但在 iOS 上不行，iOS 需要字体文件 ([Lottie: Supported features](https://lottie.airbnb.tech/#/supported-features)) 。
* **已转为形状的文本。** 设计师在 After Effects 中转为形状的文本会变成形状图层 (`ty` 4) ，其中已没有可翻译的字符串。必须先在 After Effects 中将其改回文本图层。

`.lottie` 文件是一个 dotLottie 软件包，即一个 ZIP 压缩包，内含一个 `manifest.json` 和一个或多个动画 JSON 文件，还可以包含图片和字体 ([dotLottie 2.0 spec](https://dotlottie.io/spec/2.0/)) 。每个动画 JSON 中文本所在的位置都相同。

## 翻译动画时会出现哪些问题

* **文本膨胀。** 译文的长度很少与源文本一致。在 [General Translation 的网站](https://generaltranslation.com)上，“Save changes” 的德语版本比英语版本宽 63%。框式文本图层的 `sz` 是固定的，因此更长的文本会换行，多出设计时未预留的行数；而点文本 (无文本框) 则可能超出画面边界。
* **字符缺失。** 仅支持拉丁字母的字体不包含日文、中文或阿拉伯文字符。如果导出了字形，文件中只会包含英文文本所用字符的轮廓；lottie-web 的维护者指出，新文本所需的所有字形“必须已从 AE 导出” ([lottie-web wiki](https://github.com/airbnb/lottie-web/wiki/TextLayer.updateDocumentData)) 。
* **从右到左文本。** 各播放器的支持程度参差不齐。lottie-android 目前仍有未解决的问题，分别涉及从右到左文本 ([#1145](https://github.com/airbnb/lottie-android/issues/1145)) 和阿拉伯字母渲染时无法连写 ([#2279](https://github.com/airbnb/lottie-android/issues/2279)) 。 (动画所在页面的处理方式，请参阅[如何在 CSS 中支持 RTL (从右到左) 语言？](/kb/right-to-left-css)) 
* **由表达式驱动的文本。** After Effects 表达式是存储在文件中的 JavaScript (即 `x` 属性) 。如果文本图层的内容来自表达式，就会在动画播放时实时计算，因此没有可供翻译的固定字符串。

翻译前，请先用更长且带重音符号的文本测试源动画。 (请参阅[什么是伪本地化？](/kb/pseudo-localization))

## 翻译 Lottie 动画的几种方式

| 方式                        | 文本在哪里替换                                                                                                                              | 是否处理排版适配和字体                                        | 能否在每次发布时重复执行        | 留给你处理的工作                              |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | ------------------- | ------------------------------------- |
| 从 After Effects 按语言分别重新导出 | 设计师复制合成，逐个编辑文本图层，并为每种语言导出一个文件                                                                                                        | 由设计师凭肉眼逐个调整各版本                                     | 否；每次修改文案都要为每种语言重做一遍 | 每种语言各一个文件，且每个文件都要占用设计师工时              |
| 在运行时替换文本                  | 播放器在渲染动画时替换字符串                                                                                                                       | 部分处理；lottie-web 可以缩小文本框内的文字以适配尺寸，但字体、字形和周围图层不会随之调整 | 是；字符串来自应用自身的译文      | 各语言的排版适配、字体覆盖和字形，以及稳定的键 (源文本或图层名称)    |
| 用脚本编辑 JSON                | 由脚本替换每个 `s.t` 值，通常借助机器翻译或 LLM                                                                                                        | 否                                                  | 是                   | 换行、排版适配、字体、字形，以及重新打包 `.lottie` 文件     |
| General Translation CLI   | [`gt stage`](/docs/cli/reference/commands/stage) 和 [`gt download`](/docs/cli/reference/commands/download) 为每种语言生成一个翻译好的 `.lottie` 文件 | 布局处理会基于你上传的字体，重新适配文本及其邻近图层                         | 是                   | 审校每个动画、移除表达式，以及 布局处理 的用量 |

各播放器均内置了运行时替换功能。在 lottie-android 中，`TextDelegate` 负责将源文本映射为替换文本，再由 `LottieProperty.TEXT` 通过动态属性进行设置 ([Lottie for Android](https://lottie.airbnb.tech/#/android)) ：

```kotlin
// 将动画中的英文文本替换为本地化的字符串资源。
val textDelegate = TextDelegate(animationView)
textDelegate.setText("Start your free trial", getString(R.string.trial_cta))
animationView.setTextDelegate(textDelegate)
```

在 lottie-ios 中，将 `animationView.textProvider` 设置为一个 `DictionaryTextProvider`，并以文本图层的 keypath 作为键 ([lottie-ios 源码](https://github.com/airbnb/lottie-ios/blob/master/Sources/Public/TextProvider/AnimationTextProvider.swift)) 。在 lottie-web 中，对文本图层元素调用 `updateDocumentData`。dotLottie Web 播放器的 `setTextSlot` 可替换设计师以插槽形式公开的文本 ([dotLottie 插槽](https://docs.lottiefiles.com/en/runtimes/distributions/js/v0.x/core-concepts/slots)) 。lottie-web 还能自动缩小框内文本以适应文本框：[`canResizeFont(true)`](https://github.com/airbnb/lottie-web/wiki/TextLayer.canResizeFont) 会逐步减小文本图层的字号，直到字符串能放进框内，最小可缩至你通过 [`setMinimumFontSize`](https://github.com/airbnb/lottie-web/wiki/TextLayer.setMinimumFontSize) 设置的下限。不过，这些 API 都不会移动文本周围的图层或调整其大小，例如标签背后的按钮形状。

如果动画只以一两种语言发布，且设计师希望逐帧精调，请从 After Effects 重新导出。如果文字来自你的应用 (例如用户名) ，且文本框足以容纳最长的译文，请在运行时替换文本。如果动画需要以多种语言发布、会随版本迭代而变化，并且需要针对每种语言重新调整布局，请选择 General Translation。只有在你愿意自行负责适配和字体检查时，才建议自己编写脚本处理 JSON。

## 如何使用 General Translation 翻译 Lottie 文件

General Translation 的 CLI 工具 `gt` 支持通过 `lottie` 文件键翻译 dotLottie 文件 (需 `gt` 2.16.0 或更高版本) 。添加一个 `lottie` 条目，并在路径中加入 `[locale]` 占位符：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "ja"],
  "files": {
    "lottie": {
      "include": ["animations/[locale]/**/*.lottie"]
    }
  },
  "fonts": {
    "include": ["assets/fonts/**/*.{ttf,otf}"]
  }
}
```

源动画来自 `animations/en/`，译文则输出到 `animations/es/` 和 `animations/ja/`。Lottie 翻译是异步执行的，因此请先使用 [`npx gt stage`](/docs/cli/reference/commands/stage) 提交，然后反复运行 [`npx gt download`](/docs/cli/reference/commands/download)，直到所有区域设置都处理完毕；仍在处理中的区域设置会被跳过，留待后续运行时再获取。[`gt translate`](/docs/cli/reference/commands/translate) 无法在一次运行中完成未暂存的 Lottie 任务，会提示你先将其暂存。下载得到的是完整的 `.lottie` 文件，不会发布到 CDN。

General Translation 会从软件包的 `animations/` 文件夹 (即 dotLottie 1.0 布局) 读取动画 JSON。dotLottie 2.0 软件包将其存放在 `a/` 中，而普通的 `.json` 动画根本不是软件包。这两种情况都可以使用 [`@dotlottie/dotlottie-js`](https://github.com/dotlottie/dotlottie-js) 进行转换，其 `toDotLottieV1` 和 `DotLottieV1` 可生成 1.0 布局。

翻译完成后，布局处理会保留动画的字号，重新排布文本，并移动附近的图层，为每个标签腾出空间。如果标签仍然放不下，可能会在保留原意的前提下，用目标语言缩短或改写该标签，省略号则是最后的手段；等宽代码 token 永远不会被缩短。如果布局调整无法渲染和验证，你将得到仅经过翻译的原始动画。发布前，请逐一预览下载的每个动画。 (参见 [Lottie 参考](/docs/cli/reference/formats/lottie-files)。) 

顶层 [`fonts`](/docs/cli/reference/config#fonts) 设置会上传你的 `.ttf` 和 `.otf` 文件，让布局处理能够使用动画实际采用的字体；如果动画内嵌了字形，General Translation 会为每个译文所需的字符补充轮廓，只要你上传的字体包含这些字符，就会从中提取。字体属于组织资源，因此上传需要已保存的登录状态，或具有 `org:assets:write` 权限的组织 API 密钥；项目 API 密钥无法上传字体，此时翻译会改用后备字体继续进行，并给出警告。包含 After Effects 表达式的文件会被拒绝，因为表达式属于可执行代码；请移除表达式或将其烘焙为关键帧后重新导出。

### 布局处理在测试中带来了哪些变化

我们制作了一个 480 × 160 的胶囊按钮动画：左侧是一个 18px 的图标，右侧是 22px Arial Bold 字体的标签“Download invoice”，内边距为 16 到 18px。我们使用 `gt` 2.26.11 和项目 API 密钥将其翻译为德语、法语和日语，由于没有上传任何字体，布局处理使用的是其后备字体。我们在 lottie-web 5.13 的 SVG 渲染器中，使用浏览器字体测量了每个标签。表中“完整翻译”行是 General Translation 在动画之外将各标签作为普通字符串翻译的结果，放入原始按钮中以作对比：

| 版本                     | 标签文本                   | 标签宽度  | 按钮宽度  | 结果                        |
| ---------------------- | ---------------------- | ----- | ----- | ------------------------- |
| 英语源文本                  | Download invoice       | 187px | 251px | 可容纳，距图标 11px              |
| 德语，完整翻译                | Rechnung herunterladen | 260px | 251px | 遮挡图标 25px，并超出边缘 18px      |
| 德语，General Translation | Rechnung laden         | 171px | 251px | 可容纳                       |
| 法语，完整翻译                | Télécharger la facture | 229px | 251px | 遮挡图标 9px，并超出边缘 2px        |
| 法语，General Translation | Télécharger facture    | 204px | 273px | 可容纳；按钮向右加宽 22px，标签距图标 3px |
| 日语，完整翻译                | 請求書をダウンロード             | 220px | 251px | 遮挡图标 5px                  |
| 日语，General Translation | 請求書取得                  | 111px | 251px | 可容纳                       |

所有标签都保持了 22px 字号，且均能容纳。德语和日语没有加宽按钮，而是改用了更短的措辞：*Rechnung laden* (“加载发票”) 和 請求書取得 (“获取发票”) 都比常见标签更简练。法语保留了动词、省略了冠词，并加宽了按钮，但标签与图标的间距比源版本更小。更短的措辞或更紧凑的间距能否接受，需由审校人员判断，而且每次运行的结果都可能不同。

同一测试中的第二个动画包含一个 180px 宽的“Save changes”按钮。其译文分别为 *Speichern*、*Enregistrer* 和 保存，都是标准的简短标签，无需调整布局即可容纳。在同一次运行中，标题“Your changes are ready”被译为日语 変更内容を保存できます (“您可以保存更改”) ，这种含义上的变化只有人工阅读结果才能发现。

Lottie 翻译会额外收取布局处理费用，该费用与翻译本身分开计价，按动画中动画属性的数量计算 ([用量计量](/docs/platform/dashboard/guides/managing-billing#usage-metering)、[定价](https://generaltranslation.com/pricing)) 。[上下文分组](/docs/platform/dashboard/guides/defining-context-for-translations)中的词汇表术语和自定义提示词同样适用于动画文本，因此新手引导动画中的功能名称会与您的应用及 [JSON 区域设置文件](/kb/translate-json-files)保持一致。

## 常见问题

### 为什么翻译后的动画显示空白方框或缺失字符？

这是因为字体或嵌入的字形不支持新增的字符。请随附一款支持该文字体系的字体。如果采用字形导出方式，文件中必须包含译文用到的每个字符的轮廓，因此请先在 After Effects 中替换为译文，再重新导出该语言版本。

### 每种语言都需要单独的文件吗？

如果采用运行时替换，则不需要：一个文件即可适用于所有语言。而如果采用重新导出或 General Translation CLI，则每种语言会各生成一个文件，你需要按区域设置加载相应的文件。

### 已转换为形状的文本可以翻译吗？

不可以。形状中没有可替换的字符串，请在 After Effects 中重新创建文本图层，然后重新导出。

## 要点总结

* Lottie 文本位于文本图层 (`ty` 5) 的 `t.d.k[].s.t` 中，`assets` 下预合成内的文本图层也是如此。
* 字形导出仅包含源文本所用字符的轮廓，且 iOS 不渲染字形；每新增一种文字体系，都请检查字体是否支持。
* 运行时 API (`TextDelegate`、`DictionaryTextProvider`、`updateDocumentData`、`setTextSlot`) 可替换字符串；lottie-web 的 `canResizeFont` 能缩小文本框内的文字以适配尺寸，但这些 API 都不会移动周围的图层。
* General Translation 的 CLI 通过 [`gt stage`](/docs/cli/reference/commands/stage) 和 [`gt download`](/docs/cli/reference/commands/download) 翻译 dotLottie 1.0 `.lottie` 文件，使用你上传的字体重新调整布局，并会拒绝包含表达式的文件。
* 在我们的测试中，布局处理保持字号不变，通过加宽按钮或精简措辞让每个标签都完整显示；请审校每次下载结果的措辞和间距。
* Lottie 布局处理单独计费，价格取决于动画中的动画属性。

## Related questions

- [如何翻译 i18n JSON 文件？](https://generaltranslation.com/zh/kb/translate-json-files.mdx): 只翻译 JSON 区域设置文件中的字符串值。非复数键、{{name}} 之类的占位符以及标签都应保持不变，但复数键会因语言而异：例如波兰语需要 inbox_few 和 inbox_many。请使用能识别文件格式的工具或 API，然后先解析并验证输出，再进行审校。
- [如何在 CSS 中支持 RTL（从右到左）语言？](https://generaltranslation.com/zh/kb/right-to-left-css.mdx): 在 html 元素上同时设置 dir="rtl" 和 lang，因为仅设置 lang 并不会改变文本方向；然后将 margin-left 等物理 CSS 属性替换为 margin-inline-start 等逻辑属性。Flex 行、Grid 列和默认文本对齐会自动翻转，而 translateX()、left 和 right 不会。
- [什么是伪本地化？](https://generaltranslation.com/zh/kb/pseudo-localization.mdx): 伪本地化是一种测试方法：将源文本替换为改写后的版本——加上重音符号、长度扩充约 40%，并用方括号包裹——这样在还没有任何翻译之前，硬编码字符串、截断、字体显示异常和句子拼接等问题就会暴露出来。Android 为此内置了 en-XA 和 ar-XB 两个伪区域设置。
- [如何翻译 Google Slides？](https://generaltranslation.com/zh/kb/translate-google-slides.mdx): 为每种语言复制一份演示文稿，替换每个文本框、表格单元格和演讲者备注中的文本，并缩放溢出的文本。General Translation 的 Google Drive 集成会把每种语言分别写入源文件旁的独立副本，并执行一轮格式化处理，让新文本适配每张幻灯片。
- [如何在不破坏时间轴的情况下翻译 SRT 字幕？](https://generaltranslation.com/zh/kb/translate-srt-subtitles.mdx): 只翻译 SRT 文件中的字幕文本；字幕序号、时间码、空行分隔符和格式标签均与源文件保持一致。然后根据目标平台的要求检查每行长度和阅读速度：例如，Netflix 的英语字幕指南规定，成人节目每行最多 42 个字符，每秒最多 20 个字符。

## Previous and next questions

- Previous question: [如何翻译 Flask 或 FastAPI 应用？](https://generaltranslation.com/zh/kb/translate-python-app.mdx)
- Next question: [如何翻译 PO 和 POT 文件？](https://generaltranslation.com/zh/kb/translate-po-files.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/zh/kb/sitemap.md) for every article.
