OpenHarmony开发者论坛
标题:
【闲谈鸿蒙三方库】动画库@ohos/lottie
[打印本页]
作者:
马迪
时间:
6 天前
标题:
【闲谈鸿蒙三方库】动画库@ohos/lottie
[md]## 三方库背景
在移动设备开发场景,很多大厂都在用lottie来渲染[动画](
https://airbnb.design/lottie/
)。所以在鸿蒙应用中,各厂都有相同的诉求:使用相同的lottie动画资源,实现相同的动画效果。
@ohos/lottie是一个解析Lottie格式的JSON动画,并以鸿蒙原生方式进行渲染的开源库。
其主要特性包括:
越来越多的应用选择Lottie动画,主要有以下原因:
1.Lottie动画支持Android、iOS、React Native、Web和Windows等多个平台,这意味着开发者只需创建一次动画文件,就可以在多个平台上无缝运行,极大地节省了开发资源和时间。这种跨平台特性使得Lottie动画成为构建跨平台应用时的理想选择。
2.Lottie动画通常使用美工擅长的Adobe After Effects工具制作,并通过Bodymovin插件导出为JSON格式,并且能精准还原美工的设计。
3.Lottie动画的JSON文件格式体积小,加载速度快。
4.Lottie提供了简单易用的API接口,前端可以控制动画的播放、暂停、循环、速度调整等操作,甚至播放特定的动画片段。这种易于集成与控制的特点使得Lottie动画在应用中具有更大的灵活性和可扩展性。
5.Lottie是一个开源项目,同时也有商业支持,确保项目的持续发展和改进。
开源代码地址:
https://gitcode.com/openharmony-tpc/lottieArkTS

## 快速上手方法
#### 1.下载安装
```
ohpm install @ohos/lottie
```
当前稳定版本2.0.16 和 3.0.0(多线程并行加载版本)
#### 2.设计动画
lottie动画文件是由设计人员使用Adobe After Effects软件通过bodymovin插件导出json格式的文件。
#### 3.將动画需要的json文件放到pages同级别目录下,然后引用。
注意:json文件路径不能使用 ./ 或者 ../ 等相对路径,相对路径获取不到动画源数据,会导致动画加载不出来,
传递给loadAnimation 方法的路径是相对于pages父文件夹为基准的,而index页面内引入的相对路径的动画是以index.ets文件为基准的,两者基准不一致。
所以如果json文件放置在pages文件夹下,路径应为 'pages/common/data.json' 样式
#### 4.关联Canvas画布
由于Lottie需要使用Canvas渲染,首选需要创建Canvas需要的渲染上下文CanvasRenderingContext2D:
```
mainRenderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
mainCanvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mainRenderingSettings)
```
其次CanvasRenderingContext2D需要跟对应的Canvas关联起来
```
Canvas(this.mainCanvasRenderingContext)
.width('50%')
.height(360 + 'px')
.backgroundColor(Color.Gray)
.onReady(()=>{
//抗锯齿的设置
this.mainCanvasRenderingContext.imageSmoothingEnabled = true;
this.mainCanvasRenderingContext.imageSmoothingQuality = 'medium'
})
```
#### 5.使用CanvasRenderingContext2D对象加载动画
```
animationItem = lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
name: '2016', // 动画名称
contentMode: 'Contain', // 填充的模式
frameRate: 30, //设置animator的刷帧率为30
imagePath: 'lottie/images/', // 加载读取指定路径下的图片资源
path: this.path, // json路径
initialSegment: [10,50] // 播放的动画片段
})
```
## 更多功能展示
#### 示例1 播放动画
```
lottie.play() //所有动画播放
或
animationItem.play() //当前指定animationItem动画播放
```
#### 示例2 停止动画
```
lottie.stop() //所有动画停止
或
animationItem.stop() //当前指定animationItem动画停止
```
#### 示例3 暂停动画
```
lottie.pause() //所有动画暂停
或
animationItem.pause() //当前指定animationItem动画暂停
```
#### 示例4 设置播放速度
注意:speed>0正向播放, speed<0反向播放, speed=0暂停播放, speed=1.0/-1.0正常速度播放
```
lottie.setSpeed(1) //所有动画设置播放速度
或
animationItem.setSpeed(1) //当前指定animationItem动画设置播放速度
```
#### 示例5 设置动画播放方向
注意:direction 1为正向,-1为反向
```
lottie.setDirection(1) //所有动画设置播放方向
或
animationItem.setDirection(1) //当前指定animationItem动画设置播放方向
```
#### 示例6 控制动画停止在某一帧或某一时刻
注意:根据第二个参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false
```
animationItem.goToAndStop(250,true)
或
animationItem.goToAndStop(5000,false)
```
#### 示例7 添加侦听事件
```
AnimationEventName = 'drawnFrame' | 'enterFrame' | 'loopComplete' | 'complete' | 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready' | 'DOMLoaded' | 'error' | 'data_failed' | 'loaded_images';
animationItem.addEventListener("enterFrame",function(){
// TODO something
})
```
#### 示例8 获取动画时长/帧数
```
animationItem.getDuration();
```
#### 示例9 更改动画渲染颜色
注意:第一个参数颜色是RGB/RGBA值,第二个参数是动画的层次 可不填,第三个参数是对应动画层次的元素的下标值 可不填
```
animationItem.changeColor([255,150,203,0.8]) //修改整个动画的颜色
或
animationItem.changeColor([255,150,203,0.8],2) //修改该动画第二层的颜色
或
animationItem.changeColor([255,150,203,0.8],2,2) //修改该动画第二层第二个元素的颜色
```
#### 示例10 设置动画的刷帧率
设置动画animator的刷帧率,范围是1~120 帧率越大,功耗越严重
```
animationItem.setFrameRate(30);
```
## 实现原理
#### 1.动画核心加载流程
- Lottie:全局控制入口
- AnimationManager:管理所有的动画
- AnimationItem:每个动画对象
- DataManager:读取json数据
- CanvasRendererBase:解析和渲染lottie动画

#### 2.核心设计点
- 基于LottieWeb移植适配,将调用canvas的接口从web canvas移植修改成鸿蒙canvas。
- 监听canvas对象的可见性回调,当动画处于隐藏状态或完全不可见时,当前动画将自动暂停其向canvas底层发送绘制指令,以此优化性能并减少功耗。
## 局限性
1.该库基于LottieWeb js版本移植适配,当动画较多或较复杂时,由于都在主线程加载和渲染动画,可能会导致应用卡顿和丢帧,目前正在使用C版本重构实现,且需要实现多个动画在子线程中并行加载,孵化项目在[这里](
https://gitee.com/openharmony-tpc-incubate/lottie-c
)。
2.该库没有封装自定义UI组件,导致把canvas的实现暴露给应用开发者,需要应用开发者手工创建和销毁CanvasRenderingContext2D和Canvas,使用方式较不友好,与应用耦合度较高。
## 结束语
随着越来越多的鸿蒙应用上线,各种开源的闭源的,开发者自发的和大厂贡献的库也正在逐步涌现出来,同时也有一些早期的库已被淘汰。今年我将抽空基于HarmonyOS 5.0+试试水,根据实际效果和下载量筛选在[awesome-harmony-library](
https://github.com/Madixin/awesome-harmony-library
),帮助大家快速找到合适的三方库,也请大家也帮忙Star下这个仓库
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5