【闲谈鸿蒙三方库】动画库@ohos/lottie 原创

马迪迪迪
发布于 2025-3-28 16:37
浏览
0收藏

三方库背景

在移动设备开发场景,很多大厂都在用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
【闲谈鸿蒙三方库】动画库@ohos/lottie-鸿蒙开发者社区

快速上手方法

1.下载安装

ohpm install @ohos/lottie
  • 1.

当前稳定版本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)
  • 1.
  • 2.

其次CanvasRenderingContext2D需要跟对应的Canvas关联起来

Canvas(this.mainCanvasRenderingContext)
.width('50%')
.height(360 + 'px')
.backgroundColor(Color.Gray)
.onReady(()=>{
//抗锯齿的设置
    this.mainCanvasRenderingContext.imageSmoothingEnabled = true;
    this.mainCanvasRenderingContext.imageSmoothingQuality = 'medium'
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

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.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

更多功能展示

示例1 播放动画

lottie.play() //所有动画播放
或
animationItem.play() //当前指定animationItem动画播放
  • 1.
  • 2.
  • 3.

示例2 停止动画

lottie.stop() //所有动画停止
或
animationItem.stop() //当前指定animationItem动画停止
  • 1.
  • 2.
  • 3.

示例3 暂停动画

lottie.pause() //所有动画暂停
或
animationItem.pause() //当前指定animationItem动画暂停
  • 1.
  • 2.
  • 3.

示例4 设置播放速度

注意:speed>0正向播放, speed<0反向播放, speed=0暂停播放, speed=1.0/-1.0正常速度播放

lottie.setSpeed(1) //所有动画设置播放速度
或
animationItem.setSpeed(1) //当前指定animationItem动画设置播放速度
  • 1.
  • 2.
  • 3.

示例5 设置动画播放方向

注意:direction 1为正向,-1为反向

lottie.setDirection(1) //所有动画设置播放方向
或
animationItem.setDirection(1) //当前指定animationItem动画设置播放方向
  • 1.
  • 2.
  • 3.

示例6 控制动画停止在某一帧或某一时刻

注意:根据第二个参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false

animationItem.goToAndStop(250,true)
或
animationItem.goToAndStop(5000,false)
  • 1.
  • 2.
  • 3.

示例7 添加侦听事件

AnimationEventName = 'drawnFrame' | 'enterFrame' | 'loopComplete' | 'complete' | 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready' | 'DOMLoaded' | 'error' | 'data_failed' | 'loaded_images';

animationItem.addEventListener("enterFrame",function(){
    // TODO something
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

示例8 获取动画时长/帧数

animationItem.getDuration();
  • 1.

示例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) //修改该动画第二层第二个元素的颜色
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

示例10 设置动画的刷帧率

设置动画animator的刷帧率,范围是1~120 帧率越大,功耗越严重

animationItem.setFrameRate(30);
  • 1.

实现原理

1.动画核心加载流程

  • Lottie:全局控制入口
  • AnimationManager:管理所有的动画
  • AnimationItem:每个动画对象
  • DataManager:读取json数据
  • CanvasRendererBase:解析和渲染lottie动画
    【闲谈鸿蒙三方库】动画库@ohos/lottie-鸿蒙开发者社区

2.核心设计点

  • 基于LottieWeb移植适配,将调用canvas的接口从web canvas移植修改成鸿蒙canvas。
  • 监听canvas对象的可见性回调,当动画处于隐藏状态或完全不可见时,当前动画将自动暂停其向canvas底层发送绘制指令,以此优化性能并减少功耗。

局限性

1.该库基于LottieWeb js版本移植适配,当动画较多或较复杂时,由于都在主线程加载和渲染动画,可能会导致应用卡顿和丢帧,目前正在使用C版本重构实现,且需要实现多个动画在子线程中并行加载,孵化项目在这里
2.该库没有封装自定义UI组件,导致把canvas的实现暴露给应用开发者,需要应用开发者手工创建和销毁CanvasRenderingContext2D和Canvas,使用方式较不友好,与应用耦合度较高。

结束语

随着越来越多的鸿蒙应用上线,各种开源的闭源的,开发者自发的和大厂贡献的库也正在逐步涌现出来,同时也有一些早期的库已被淘汰。今年我将抽空基于HarmonyOS 5.0+试试水,根据实际效果和下载量筛选在awesome-harmony-library,帮助大家快速找到合适的三方库,也请大家也帮忙Star下这个仓库:)

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-3-28 16:47:25修改
收藏
回复
举报
回复
    相关推荐
    这个用户很懒,还没有个人简介
    帖子
    视频
    声望
    粉丝
    社区精华内容