# LottieC **Repository Path**: wurep/lottie-c ## Basic Information - **Project Name**: LottieC - **Description**: lottie是一个适用于OpenHarmony的动画库,它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画,并在移动设备上进行本地渲染。该库基于rlottie及c++实现 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 17 - **Created**: 2025-02-07 - **Last Updated**: 2025-04-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # lottieC ## 简介 lottieC是一个适用于OpenHarmony的动画库,它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画,并在移动设备上进行本地渲染。 ## 下载安裝 ``` ohpm install @ohos/lottiec ``` OpenHarmony ohpm 环境配置等更多内容,请参考[如何安装 OpenHarmony ohpm 包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_har_usage.md) ## 快速上手 ### 示例 ``` import { LottieView, LottieController, LottieListener, lottie } from '@ohos/lottiec'; @Entry @Component struct Index { @State cacheKeyOne:string = 'animation1' //缓存键 private controller: LottieController = new LottieController(); //动画控制器 private listener: LottieListener | null = new LottieListener({ onEnterFrame: (args: ESObject) => { //播放帧回调 this.updateAllStates() }, onLoopComplete: (args: ESObject) => { //动画循环播放一轮完成时 console.info("lottie complete"); this.playCount = this.controller?.playCount; this.totalPlayedCount += 1; }, onComplete: (args: object) => { //动画播放结束时调用 this.log += "lottie1 event complete\r\n" }, onDestroy: (args: ESObject) => { //动画删除后回调 console.info("lottie destroy"); }, onDOMLoaded: (args: ESObject) => { //动画加载完成,播放之前触发回调 console.info("lottie DOMLoaded"); }, onDataReady: (args: object) => { //动画数据初始化完成时调用 this.log += "lottie1 event data_ready\r\n" }, }) build() { ... LottieView({ loop: true, //是否循环 autoplay: true, //自动播放 lottieId: "lottie1" + this.getUniqueId(),//id contentMode: 'Contain', //填充模式 path: $rawfile('common/lottie/animation.json'), //动画路径 frameRate: 30,//播放帧率 controller: this.controller, //动画控制器 initialSegment: [30, 150],//初始化动画资源播放时的整体帧范围 listener: this.listener //监听事件容器 }) Button("全局控制") .onClick(() => { lottie.play(); //全局播放 lottie.pause(); //全局暂停 lottie.stop(); //全局停止 lottie.destroy(); //全局暂停 lottie.togglePause();//全局切换暂停/播放 lottie.setSpeed(1); //设置全局播放速度 lottie.setDirection(1); //设置全局播放方向 1代表正向 -1代表方向 lottie.setFrameRate(30)//全局设置播放帧率 lottie.clearFileCache("");//清除单个文件缓存 不传参数为清除所有文件缓存 lottie.clearCache();//清除内存缓存 lottie.containsCache("")//判断缓存是否存在 lottie.resizeCache(10, 10 * 1024 * 1024);//重置内存缓存大小 lottie.resizeFileCache(10, 1024*1024)//重置文件缓存大小 lottie.removeCache("path")//通过key删除内存缓存 }) Button("单个控制") .onClick(() => { this.controller.play(); //播放 this.controller.stop(); //停止 this.controller.pause(); //暂停 this.controller.destroy(); //销毁 this.controller.setSpeed(1); //设置播放速度 this.controller.setDirection(1); //设置播放方向 1代表正向 -1代表方向 this.controller.setSegment(350, 0); //限定动画资源播放时的整体帧范围 this.controller.changeColor("**", [255, 0, 0]); //修改动画颜色 this.controller.togglePause()//切换暂停/播放 this.controller.setFrameRate(30)//设置播放帧率 //重载动画 this.controller.reload({ loop: true, autoplay: true, path: "https://kjstorage.360buyimg.com/cms-file/1_eec97231.zip" }) //添加监听事件 this.controller.addEventListener('drawFrame', (args: Object): void => { this.log += "add lottie event " + eventName + "\r\n" }); //移除监听事件 this.controller.removeEventListener(‘drawFrame’); // }) ... } aboutToDisappear(): void { lottie.destroy(); } } ``` ### 注意事项 - 1.建议在页面销毁或卸载时,将页面上所有的动画进行销毁,确保页面资源得到妥善管理和释放。 - 2.如果需要在不同ability使用lottieC加载动画,要注意lottieId的唯一性,可调用this.getUniqueId()确保唯一性。 ## 使用说明 前提:数据准备 lottie动画文件是由设计人员使用Adobe After Effects软件通过bodymovin插件导出json格式的文件。 AE软件创建动画时需要设置动画的宽(w)、高(h)、bodymovin插件的版本号(v)、帧率(fr)、开始帧(ip)、结束帧(op)、静态资源信息(assets)、图层信息(layers)等重要信息。 如果仅是用于demo测试,可以使用[工程示例中的json文件] 。 1.引入组件: ``` import lottie from '@ohos/lottiec' ``` 2.动画资源位置 注意:json文件路径不能使用 ./ 或者 ../ 等相对路径,相对路径获取不到动画源数据,会导致动画加载不出来, 在build()方法中添加自定义组件添加LottieView,通过path属性去定义资源路径。 ``` LottieView({ loop: true, //是否循环 autoplay: true, //自动播放 lottieId: "lottie1" + this.getUniqueId(),//id contentMode: 'Contain', //填充模式 path: $rawfile('common/lottie/animation.json'), //动画路径 frameRate: 30,//播放帧率 controller: this.controller, //动画控制器 initialSegment: [30, 150],//初始化动画资源播放时的整体帧范围 listener: this.listener //监听事件容器 }) ``` path属性可设置为: - $rawfile('common/lottie/animation.json')//Resource 类型 - "https://assets7.lottiefiles.com/packages/lf20_sF7uci.json" // 网络资源类型的 的字符串 - 其他har包下的resource资源 - 图库资源 - 沙箱路径资源 3.使用组件 参考快速上手中示例 4.控制动画 - 播放动画 ``` lottie.play() //所有动画播放 或 lottie.play('animation1') //animation1动画播放 或 this.controller.play() //this.controller绑定的动画播放 ``` - 停止动画 ``` lottie.stop() //所有动画停止 或 lottie.stop('animation1') //animation1动画停止 或 this.controller.stop() //this.controller绑定的动画停止 ``` - 暂停动画 ``` lottie.pause() //所有动画暂停 或 lottie.pause('animation1') //animation1动画暂停 或 this.controller.pause() //this.controller绑定的动画暂停 ``` - 切换暂停/播放 ``` lottie.togglePause() //所有动画切换暂停/播放 或 lottie.togglePause('animation1') //animation1动画切换暂停/播放 或 this.controller.togglePause() //this.controller绑定的动画切换暂停/播放 ``` - 设置播放速度 > 注意:speed>0正向播放, speed<0反向播放, speed=0暂停播放, speed=1.0/-1.0正常速度播放 ``` lottie.setSpeed(1) //所有动画设置播放速度 或 lottie.setSpeed(1,'animation1') //animation1动画设置播放速度 或 this.controller.setSpeed(1) //this.controller绑定的动画设置播放速度 ``` - 设置动画播放方向 > 注意:direction 1为正向,-1为反向 ``` lottie.setDirection(1) //所有动画设置播放方向 或 lottie.setDirection(1,'animation1') //animation1动画设置播放方向 或 this.controller.setDirection(1) ///this.controller绑定的动画设置播放方向 ``` - 销毁动画 > 注意:页面不显示或退出页面时,需要销毁动画; 可配合页面生命周期aboutToDisappear()及onPageHide() ``` lottie.destroy() //销毁所有动画 或 lottie.destroy('animation1') //销毁animation1动画 或 this.controller.destroy('animation1') //销毁指定name动画 ``` - 控制动画停止在某一帧或某一时刻 > 注意:根据第二个参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false ``` this.controller.goToAndStop(250,true) 或 this.controller.goToAndStop(5000,false) ``` - 控制动画从某一帧或某一时刻开始播放 > 注意:根据第二参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false ``` this.controller.goToAndPlay(250,true) 或 this.controller.goToAndPlay(12000,false) ``` - 限定动画资源播放时的整体帧范围,即设置动画片段 ``` this.controller.setSegment(5,15); ``` - 播放动画片段 > 注意:第二参数值为true立刻生效, 值为false循环下次播放的时候生效 ``` this.controller.playSegments([[5,15],[20,30]],true) ``` - 重置动画播放片段,使动画从起始帧开始播放完整动画 > 注意:参数值为true立刻生效, 值为false循环下次播放的时候生效 ``` this.controller.resetSegments(5,15); ``` - 获取动画时长/帧数 > 注意:参数值为true时获取帧数,值为false时获取时间(单位ms) ``` this.controller.getDuration(); ``` - 添加侦听事件 > 注意:添加和移除的事件监听,回调函数需是同一个,需预先定义,否则将不能正确移除 ``` AnimationEventName = 'enterFrame' | 'loopComplete' | 'complete' | 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready' | 'DOMLoaded' | 'error' | 'data_failed' | 'loaded_images'; this.controller.addEventListener('loopComplete', (args: Object): void => { console.info("loopComplete"); }) ``` - 更改动画渲染颜色 > 注意:第一个参数代码图层名称,第二个参数是颜色的RGB或者RGBA值 ``` this.controller.changeColor(**.Layer 1 Outlines.**,[255,150,203]) //修改某一个元素的颜色,不带透明度 或 this.controller.changeColor(**.Layer 1 Outlines.**,[255,150,203,10]) //修改某一个元素的颜色,带透明度 ``` - 移除侦听事件 ``` this.controller.removeEventListener('loopComplete') ``` - 刷新动画布局 ``` this.controller.resize(200, 200) ``` - 动画填充模式 > 注意:动画填充模式共有5种:Fill,Cover,Top,Bottom,Contain,其中默认的填充模式是:Contain ``` this.controller.setContentMode('Fill'); ``` - 设置动画的刷帧率 > 注意:设置动画animator的刷帧率,范围是1~120 帧率越大,功耗越严重 ``` this.controller.setFrameRate(30); ``` - 清除缓存文件 > 注意:container是与canvas组件绑定的上下文CanvasRenderingContext2D,用于本地资源路径json文件 ``` lottie.clearFileCache() //清除所有动画缓存文件 或 lottie.clearFileCache('https://p3-dcd.byteimg.com/obj/motor-mis-img/5ec2c8af22bc17aedafe147a1d38f21d.json') //清除指定动画缓存文件 或 lottie.clearFileCache('common/lottie/data_url.json') //清除指定本地动画中网络资源缓存文件 ``` 5.HSP场景 - 在HSP场景下,lottie加载动画json资源文件需通过animationData方式加载,需把动画json资源文件放在rawfile下进行读取加载: ``` LottieView({ loop: true, //是否循环 参数为numer类型时,表示循环次数 autoplay: true, //自动播放 contentMode: 'Contain', //填充模式 animationData: this.jsonData, // json对象数据 controller: this.controller, //动画控制器 listener: this.listener //监听事件容器 }) ``` - 读取文件部分 ``` try { let rawFile = getContext(this).resourceManager.getRawFileContentSync('animation.json'); let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }); let rawFileString = textDecoder.decodeToString(rawFile, { stream: false }); console.info("test---"+JSON.stringify(rawFileString)) } catch (error) { let code = (error as BusinessError).code; let message = (error as BusinessError).message; console.error(`getRawFileContentSync failed, error code: ${code}, message: ${message}.`); } ``` 6.混淆 - 混淆导致编译报错,请在对应的模块下的obfuscation-rules.txt文件里配置一下:-keep ./oh_modules/@ohos/lottiec ,这样就解决使用混淆编译导致的报错 ## LottieController内接口说明 | 使用方法 | 类型 | 相关描述 | |-----------------------|---------------------------------|-----------| | play() | | 播放 | | stop() | | 停止 | | pause() | | 暂停 | | togglePause() | | 切换暂停 | | destroy() | | 销毁动画 | | goToAndStop() | value, isFrame? | 跳到某一时刻并停止 | | goToAndPlay() | value, isFrame? | 跳到某一时刻并播放 | | setSegment() | init,end | 设置动画片段 | | playSegments() | arr, forceFlag | 播放指定片段 | | resetSegments() | forceFlag | 重置动画 | | resize() | width?: number, height?: number | 重设动画大小 | | setSpeed() | speed | 设置播放速度 | | setDirection() | direction | 设置播放方向 | | getDuration() | isFrames? | 获取动画时长 | | triggerEvent() | name: string | 触发时间回调 | | addEventListener() | eventName,callback | 添加监听状态 | | removeEventListener() | name,callback? | 移除监听状态 | | changeColor() | color, layer?, index? | 更改动画颜色 | | setContentMode() | contentMode | 设置填充模式 | | setFrameRate() | frameRate | 设置动画刷帧率 | | reload() | config: ConfigType | 重载动画 | ## lottie全局api说明 | 使用方法 | 参数类型 | 相关描述 | |-----------------------------|------------------------------------------------------|------------------------------------------------------------------------------------------------------------| | lottie.play() | lotteId ?: string (动画名) | 播放动画,可通过设置lotteId 指定动画操作 | | lottie.stop() | lotteId ?: string (动画名) | 停止动画,可通过设置lotteId 指定动画操作 | | lottie.pause() | lotteId ?: string (动画名) | 暂停动画,可通过设置lotteId 指定动画操作 | | lottie.togglePause() | lotteId ?: string (动画名) | 切换暂停动画,可通过设置lotteId 指定动画操作 | | lottie.destroy() | lotteId ?: string (动画名) | 销毁动画,可通过设置lotteId e指定动画操作 | | lottie.setSpeed() | speed: number (播放方向) , lotteId ?: string (动画名) | 全局动画播放方向控制,speed>0正向播放, speed<0反向播放, speed=0暂停播放, speed=1.0/-1.0正常速度播放 | | lottie.setDirection() | direction: 1 或 -1, lotteId ?: string (动画名) | 全局设置播放方向,可通过设置lotteId 指定动画操作; 1为正向, -1为反向; 当设置为反向时, 从当前播放进度开始回播直到首帧, loop值为true时可无限倒放, speed<0叠加时也是倒放 | | lottie.setFrameRate(20) | frameRate: number | 全局设置播放帧率 | | lottie.clearFileCache() | url?: string (路径path或者网络uri) | 全局文件缓存清除 ,可通过设置url指定清除文件. | | lottie.resizeCache() | size: number, capacity: number (缓存总量大小) | 设置内存缓存容器大小 | | lottie.configureCacheSize() | size: numbe | 设置缓存大小 | | lottie.resizeFileCache() | size: number, capacity: number (缓存总量大小) | 设置文件缓存容器大小 | | lottie.clearCache() | 无 | 清空缓存容器 | | lottie.removeCache() | key: string (缓存键) | 通过缓存键移除缓存 | | lottie.containsCache() | key: string (缓存键) | 通过缓存键查询缓存是否存在 返回布尔值 true存在 false不存 | ## 与LottieArkts特性对比 - 方法对比 | 方法 | **lottieArkTS**(js api) | lottie-c(js api) | lottie-c(c api) | |-----------------------------------------------------------|-------------------------------------------|------------------------------------------------------------|----------------------------------------------------| | 播放 | play() | 一致 | 一致 | | 停止 | stop() | 一致 | 一致 | | 暂停 | pause() | 一致 | 一致 | | 切换暂停 | togglePause() | 一致 | 一致 | | 销毁动画 | destroy() | 一致 | 一致 | | 跳到某一时刻并停止 | goToAndStop() | 一致 | 一致 | | 跳到某一时刻并播放 | goToAndPlay() | 一致 | 一致 | | 设置动画片段 | setSegment() | 一致 | 一致 | | 播放指定片段 | playSegments() | 一致 | 一致 | | 重置动画 | resetSegments() | 一致 | 一致 | | 设置播放速度 | setSpeed() | 一致 | 一致 | | 设置播放方向 | setDirection() | 一致 | 一致 | | 获取动画时长 | getDuration() | 一致 | 一致 | | 添加监听状态 | addEventListener() | 一致 | 一致 | | 移除监听状态 | removeEventListener() | 一致 | 一致 | | 更改动画颜色 | changeColor() | 不一致 (layer?: string, Color: number[]) layer表示图层,Color 代表颜色 | ChangeColor(napi_env env, napi_callback_info info) | | 设置填充模式 | setContentMode() | 一致 | 一致 | | 设置动画刷帧率 | setFrameRate() | 一致 | 一致 | | 清除文件缓存 | cacheFileClear() | 一致 | 一致 | | 跟踪 lottie动画, CanvasRenderingContext2D, Canvas 三者之间的动态关联关系 | bindContext2dToCoordinator() | 废弃 | 废弃 | | 解除追踪关系 | unbindContext2dFromCoordinator() | 废弃 | 废弃 | | 支持强制修正context2d所关联的canvas节点状态 | setAttachedCanvasHasVisibleArea() | 废弃 | 废弃 | - 属性对比 | 属性 | **lottieArkTS**(js api) | lottie-c(js api) | lottie-c(c api) | |---------------------------|-------------------------|------------------|-----------------| | 动画名称 | animationID | 不一致 使用lottieId | 不一致 使用lottieId | | 动画是否已加载 | isLoaded | 一致 | 一致 | | 当前帧 | currentFrame | 一致 | 一致 | | 当前帧数(浮点) | currentRawFrame | 一致 | 一致 | | 第一帧索引 | firstFrame | 一致 | 一致 | | 总帧数 | totalFrames | 一致 | 一致 | | 帧率 frame/s | frameRate | 一致 | 一致 | | 帧率 frame/ms | frameMult | 一致 | 一致 | | 播放速度 | playSpeed | 一致 | 一致 | | 播放方向 | playDirection | 一致 | 一致 | | 完成播放的次数 | playCount | 一致 | 一致 | | 是否暂停 | isPaused | 一致 | 一致 | | 是否网络加载 | isNetLoad | 废弃 | 废弃 | | 自动播放 | autoplay | 一致 | 一致 | | 是否循环 | loop | 一致 | 一致 | | 当前动画片段完成单次播放的帧数 | timeCompleted | 一致 | 一致 | | 当前动画片段序号 | segmentPos | 一致 | 一致 | | 是否尽可能更新动画帧率 | isSubframeEnabled | 一致 | 一致 | | 当前动画播放片段 | segments | 一致 | 一致 | | 包名 | packageName | 废弃 | 废弃 | | 当动画不可见时,是否跳过绘制:设为true则跳过绘 | autoSkip | 一致 | 一致 | | 网络资源加载路径 | uri | 不一致 (合并到path) | 不一致 (合并到path) | | 初始化动画资源播放时的整体帧范围 | initialSegment | 一致 | 一致 | | json格式的动画数据 | animationData | 一致 | 一致 | | 动画填充模式 | contentMode | 一致 | 一致 | | 设置Assets资源替换功能 | imageAssetDelegate | 一致 | 一致 | ## 约束与限制 在下述版本验证通过: - DevEco Studio: DevEco Studio 5.0.1 Release(5.0.5.306), SDK: API13(5.0.1.112) - DevEco Studio: NEXT Developer Beta3(5.0.3.524), SDK: API12(5.0.0.25) ## 目录结构 ```` /lottie-c # 项目根目录 ├── entry # 示例代码文件夹 ├── library # lottie-c库文件夹 │ └─ src/main │ └─ cpp/types │ └─ napi_init.cpp # │ └─ ets │ ├── components # LottieView组件 │ ├── model # 类型定义 │ ├── utils # 工具 │ ├── Lottie.ets # lottieC全局lottie声明 ├── README.md # 安装使用方法 ├── README_zh.md # 安装使用方法 ```` ## 贡献代码 使用过程中发现任何问题都可以提交 [Issue](https://gitee.com/openharmony-tpc-incubate/lottie-c/issues),当然,也非常欢迎提交 [PR](https://gitee.com/openharmony-tpc-incubate/lottie-c/pulls) 。 ## 开源协议 本项目遵循 [MIT License](https://gitee.com/openharmony-tpc-incubate/lottie-c/blob/master/LICENSE)。 ## 不支持能力 1. 不支持"ef"字段 2. 修改关键帧的颜色