01. WHY

不少动画中,会带有一些业务数字,比如之前文章中提到的这段动画

动态文案 Lottie 动画示例https://www.zhihu.com/video/1199488346264825856

这里的「3.39%」「2.43%」以及「1000 万」都属于业务数字,所以这段动画用 gif/apng/视频都不合适,因为数字有变动时候需要重新生成,而像余额宝的七日年化可是每天都会变化的,Lottie 真是这种场景下的最佳方案

02. HOW

要实现 Lottie 的文本动态修改,需要对 Lottie 的运行机制有一定了解
简单来说,运行前设计师导出的 lottie.json 对象,会被 lottie-web 解析之后产生相应的 JS 对象,并在动画播放期间,由 JS 对象计算并修改 HTML 中相应的 svg 元素属性,从而实现动画播放

因此如果要做文本动态修改,理论上在这 3 个阶段都是可以「动手脚」的注: 这里暂时忽略了 lottie canvas 模式,最后一节会补充说明
先给出一个简单的示例,看下本人自学三天 AE 导出的一个土味 lottie 动画

一则土味 lottie 动画https://www.zhihu.com/video/1199487982731988992

可以通过我们团队自制的 lottie 编辑器预览下效果

Alipay Design​sage.alipay.com

lottie.json 文件​gw.alipayobjects.com

03.A. 修改 lottie.json

这是最容易想到的办法,lottie.json 内部描述了动画的所有细节,自然也就包含了动画中的那段文本,如果我们能找到相应的字段进行修改,也就可以实现文本替换了,简单看下 json 就能找到重点(虽然你可能完全不知道这些 key 是什么鬼)

找到 lottie.json 中的「占位符」

查找下 lottie-web api 可以发现是支持直接传入 json 对象的,那么我们在外部自己发 ajax 请求获取 json 然后替换即可,代码如下

fetch('https://gw.alipayobjects.com/os/finxbff/2d0c4a95-568f-4923-bef0-e20fca6018ca/7abc1e3d-c381-49ed-ad54-3a48366f0180.json').then(resp => resp.text()).then(text => {// 简单演示替换const newJSON = text.replace('${文本}', '拾亿');lottie.loadAnimation({animationData: JSON.parse(newJSON),container: document.getElementById('app'),loop: true});});

https://codesandbox.io/s/lingering-microservice-fh4to?fontsize=14&hidenavigation=1&theme=dark​codesandbox.io

这种做法优点是简单粗暴,但是也有一些缺点

  • 文本替换存在一定不确定性,比如上面例子如果不是设计师在 AE 中写入 ${文本} 这样明确的占位符,这个方法可就没那么容易实现了,如果设计师配合度不高,那么这个方式可操作性就差了一些
  • 这种方式无法做到「运行时」修改,也就是 lottie 解析播放后就无法再修改文本了,比如某些场景下可能需要先播放 lottie 的前一部分,用户交互产生数据后,再替换文本播放后一部分,那么这种方式就无法满足了

03.B. 修改 JS 对象

通过修改 lottie 解析后的运行时 JS 对象,理论上一样可以修改文本,官方其实提供了相应的 API,仔细查找的话在 lottie-web 的官方文档里有提及,请看 https://github.com/airbnb/lottie-web/wiki/TextLayer.updateDocumentData
对于上面的 lottie 可以这样替换

anim.addEventListener('DOMLoaded', () => {  anim.renderer.elements[0].elements[0].updateDocumentData({t:'拾亿'},0);
});

  • 第一个参数表示如何替换文本,t 表示文本内容,这里还可以传入 s 修改大小,fc 修改颜色
  • 第二个参数表示替换指定关键帧的文本,文本可以有关键帧,在动画过程中展示不同的文本,如果没有关键帧可以省略这个参数

不过这个方式的麻烦之处在于,需要对解析出的 JS 对象比较了解,比如上面例子里需要知道 elements[0].elements[0] 对应的是那段文本,这里有一个人肉查找的过程
幸而我们发现官方还提供了 lottie-api 这样一个神奇的运行时修改 lottie 的库,可惜文档缺失、甚至打包有问题,导致用的人也少,这篇文章甚至可能是中文世界里第一个提到这个库的
但是这个库着实强大,比如要寻找相应的 JS 对象就很简单,示例如下

anim.addEventListener("DOMLoaded", () => {const api = lottie_api.createAnimationApi(anim);const elements = api.getKeyPath("comp1,textnode");  // 查找对象elements.getElements()[0].setText("拾亿");
});

这里 getKeyPath 的参数 comp1,textnode 是什么呢?看一下设计师的 AE 源文件就知道了

AE 截图
AE 截图

其实就是图层名称的拼接,这个 lottie 内部有两层结构,第一层是「合成」,名称叫 comp1,文本位于 comp1 的内部,名称叫做 textnode,于是逗号拼接下就可以找到了
elements.getElements() 可以获取到所有满足条件的 JS 对象,因为 lottie 中图层的名称并不唯一,有时候可能会找到多个对象,最后通过 setText 就可以简单修改文本了
这个方式我个人比较喜欢,因为通过看 AE 图层名称去拼接 keypath 比自己用 [0][1] 去一层层查找对象要方便和健壮很多,不过如果你没有 AE 怎么办?上面提到的我们团队的lottie 在线编辑器里,也是可以看到这些信息的,后续我们会再完善,提供一键查看 keypath 功能
最后图层名称其实也可以是中文,一样可以查找到

在线 Lottie 编辑器「洛丽塔」

完整代码示例

https://codesandbox.io/s/hardcore-goldwasser-e0el3?fontsize=14&hidenavigation=1&theme=dark​codesandbox.io

注意: 由于 lottie-api 1.0.2 build 的问题,导致 import 时需要这样写import * as lottieAPI from "lottie-api/dist/lottie_api";才能正确引入,而 codesandbox 并不支持所以示例里用了 script 引入
这种方法相比第一种要繁琐一些,但是我更偏好这种,因为能够做到「运行期」替换
另外如果文本图层存在多个关键帧的话,setText() 方法可以传入第二个入参替换指定关键帧中的文案,这与 updateDocumentData 一致,因为底层调用的就是 updateDocumentData

03.C. 修改 svg 元素

这里需要提到 Lottie 中的一个鲜为人知的黑科技,如果设计师在 AE 图层命名时尾部加入 #xxx ,那么生成的 svg 元素就会有一个 id 属性为 xxx,比如

AE 截图,图层名称增加 #
DOM 截图,svg 元素有 id 属性

于是根据这个黑科技,我们可以这么写

anim.addEventListener("DOMLoaded", () => {const element = document.getElementById("J_txt");element.querySelector("tspan").innerHTML = "拾亿";
});

代码示例

silly-water-woj0j - CodeSandbox​codesandbox.io

这个方式有些黑科技,但是却是简单有奇效,但是这种方式有一些缺点,如果文本图层存在多个关键帧,那么这种方式比较难解决

04. 比较

综合比较三种方式,我更喜欢修改 JS 对象,因为基于中间产物的修改方式扩展性是最强的,比如能够支持运行期,还可以修改大小、颜色、替换指定关键帧等等

05. canvas 模式的问题

最上面提到先忽略 canvas 模式,那么这个模式有什么问题吗?这里又涉及到 lottie 的底层实现了
由于在 canvas 模式下绘制文本是很慢的,作者考虑后放弃了 drawText 的实现(https://github.com/airbnb/lottie-web/issues/250),转而在导出 json 时抽取字体库中的字形(Glyphs)路径放入文件,canvas 模式下通过路径绘图来画出文本
所以上述方案中的 C 肯定无法支持 canvas 模式,而 A/B 要支持则依赖于导出 JSON 时,要替换的文本字形是否已经存在于 JSON 中,因此从实际出发,一般 canvas 模式下就比较难实现替换文本了(鬼知道产品经理要替换成什么)
另外根据上面的原理,上面所有例子中,从 AE 导出 lottie 时都记得去掉「Glyphs」这个选项,并且指定具体的 font family,记得把这件事告诉你的设计师小伙伴

AE bodymovin 插件选项
AE bodymovin 插件选项

最后,下一篇预告,相信你应该能想到,动态替换 Lottie 中的图片

c++ 获得文本修改时间_Aha Lottie | 动态修改 Lottie 中的文本相关推荐

  1. 修改mysql参数_mysql动态修改参数

    mysql数据库可以动态的修改参数,即可以修改会话级变量只对当前会话产生影响:又可以修改全局变量,对所有新连接的会话都产生影响. 1>修改全局变量 [root@admin root]# mysq ...

  2. linux 修改docker配置文件,dockerfile动态修改服务配置文件(示例代码)

    主要是利用命令envsubst能实现变量的替换并生成新得配置文件以及docker命令行的变量输入等. 本次实验主要是编写flume镜像,并在容器启动(docker run)时动态修改配置文件并启动,并 ...

  3. linux修改时间和日期,linux修改时间和日期的方法

    修改linux的时间可以使用date指令 时间设定成2009年5月10日的命令如下: #date -s 05/10/2009 修改时间: 将系统时间设定成上午10点18分0秒的命令如下. #date ...

  4. linux通过修改时间排序,linux按修改时间排序

    1.按文件大小查看文件 a.降序:ls -lsh moudaen@morton:~$ ls -lsh total 20M 20M -rw-r--r-- 1 moudaen 65536  20M Nov ...

  5. 动态修改el-input样式;动态修改elmentUI元素样式;css变量

    场景:正常我们动态修改div元素的样式,使用:style和:class即可:但是我们想要动态修改element的组件样式时候,例如el-input字体颜色,由于el-input的样式嵌套很深,我们需要 ...

  6. opencv python3 文本区域识别_使用等高线从图像中提取文本区域 - Opencv,Python

    我一直在使用python中的opencv开发名片的OCR项目 . 直到现在,我已经能够裁剪图像卡 . 我试图使用轮廓检测裁剪图像中的文本区域 . (即,拍摄Canny图像,从这些边缘找到轮廓并将它们扩 ...

  7. java 取pdf 文本域_java – 使用iText从pdf文件中提取文本列

    我需要使用iText从pdf文件中提取文本. 问题是:一些pdf文件包含2列,当我提取文本时,我得到一个文本文件,其中列被合并为结果(即同一行中两列的文本) 这是代码: public class pd ...

  8. python文本分类_手把手教你在Python中实现文本分类.pdf

    手把手教你在Python 中实现文本分类(附代码.数 据集) 引言 文本分类是商业问题中常见的自然语言处理任务,目标是自动将文本文件分到一个 或多个已定义好的类别中.文本分类的一些例子如下: • 分析 ...

  9. linux密码修改时间,linux 查看、修改用户及密码过期时间(示例代码)

    WARNING: Your password has expired. Password change required but no TTY available. 提示密码过期, 设置新用户密码的过 ...

最新文章

  1. pandas计算滑动窗口中的最大值实战(Rolling Maximum in a Pandas Column):计算单数据列滑动窗口中的最大值、计算多数据列滑动窗口中的最大值
  2. C++构造与析构(18) - 静态对象(static object)何时销毁
  3. 从零开始学ios开发(十):Multiview Applications(多个xib之前的切换)
  4. Linux 中如何安装卸载软件
  5. 比特币base58源码解析_中本聪源码早期版本流出:区块链原名时间链,比特币内置虚拟扑克游戏...
  6. 7-54 查验身份证 (15 分)
  7. JAVA 搭建基于SPRINGBOOT的SSM(SPRING + SPRINGMVC + MYBATIS)的MAVEN项目
  8. 蓝桥杯 ADV-157算法提高 现代诗如蚯蚓
  9. Oracle Goldengate在HP平台裸设备文件系统OGG-01028处理
  10. 企业微信oauth认证_企业微信开发之授权登录
  11. java分页 添加序号_java 分页
  12. 计算机有自带的拼音打字功能吗,搜狗拼音输入法 自带功能提升打字速度的技巧...
  13. 用javascript获取屏幕高度和宽度等信息
  14. ubuntu使用命令设置静态IP地址
  15. 骨头镇 BoneTown 破解+菜单汉化补丁
  16. 编程初学者(零基础如何入门),我适合这个行业么
  17. 07 Python数据类型详解
  18. 注意力机制--CBAM的研究
  19. 利用ruby演示程序执行
  20. python——字符串练习:句子反转

热门文章

  1. 大蟒蛇python头像_程序员用Python获取了自己以前的QQ历史头像,以前的非主流形象简直不忍直视...
  2. ArcGIS9.3的注册码
  3. 诺基亚android怎么解锁,诺基亚解锁教程Nokia unlock bootloader
  4. NCH PhotoPad Pro for Mac(轻量级照片编辑软件)
  5. 如何使用阿里云的短息服务
  6. Asp.Net C# - AES加密、解密
  7. c/c++ 标准日期和时间戳互相转化
  8. 契约锁助力仓库单据电子签:货物“入-检-调-提-出”再提速
  9. ConvLSTM:一种用于降水预报的机器学习方法
  10. The rollout of the Indian motorcycle brand continues apace