lottie是一个适用于OpenHarmony的动画库,它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画,并在移动设备上进行本地渲染。
ohpm install @ohos/lottie
OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包
前提:数据准备
lottie动画文件是由设计人员使用Adobe After Effects软件通过bodymovin插件导出json格式的文件。
AE软件创建动画时需要设置动画的宽(w)、高(h)、bodymovin插件的版本号(v)、帧率(fr)、开始帧(ip)、 结束帧(op)、静态资源信息(assets)、图层信息(layers)等重要信息。
如果仅是用于demo测试,可以使用工程示例中的json文件 。
1.在相应的类中引入组件:
import lottie from '@ohos/lottie'
2.构建渲染上下文
private mainRenderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
private mainCanvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mainRenderingSettings)
3.將动画需要的json文件放到资源目录resources/rawfile同级别目录下,然后引用。(json路径为resources/rawfile/common/lottie/data.json)
注意:json文件路径不能使用 ./ 或者 ../ 等相对路径,相对路径获取不到动画源数据,会导致动画加载不出来,
传递给loadAnimation 方法的路径是相对于pages父文件夹为基准的,而index页面内引入的相对路径的动画是以index.ets文件为基准的,两者基准不一致。
所以如果json文件放置在pages文件夹下,路径应为 'pages/common/data.json' 样式
private path:string = "common/lottie/data.json"
或
private jsonData:string = {"v":"4.6.6","fr":24,"ip":0,"op":72,"w":1000,"h":1000,"nm":"Comp 2","ddd":0,"assets":[],...}
4.关联画布
Canvas(this.mainCanvasRenderingContext)
.width('50%')
.height(360 + 'px')
.backgroundColor(Color.Gray)
.onReady(()=>{
//抗锯齿的设置
this.mainCanvasRenderingContext.imageSmoothingEnabled = true;
this.mainCanvasRenderingContext.imageSmoothingQuality = 'medium'
})
注意:canvas设置的宽高比例建议和动画json资源里面的宽高比例一致,如:json动画资源里的宽高比例是 1:2 ,则canvas设置的宽高也是 1:2
想要的抗锯齿效果:mainCanvasRenderingContext.imageSmoothingEnabled = true 与 mainCanvasRenderingContext.imageSmoothingQuality = 'medium'
动画绘制前会对canvas画布进行清空处理,画布清空后再绘制动画。
5.加载动画
lottie.destroy('2016'); //加载动画前先销毁之前加载的动画
this.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] // 播放的动画片段
})
或
lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
contentMode: 'Contain', // 填充的模式
frameRate: 30, //设置animator的刷帧率为30
animationData: this.jsonData, // json对象数据
initialSegment: [10,50] // 播放的动画片段
})
或
lottie.loadAnimation({
uri: "https://assets7.lottiefiles.com/packages/lf20_sF7uci.json", // uri网络资源
container: this.canvasRenderingContext, // 渲染上下文
renderer: 'canvas', // canvas 渲染模式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
name: this.animateName, // 动画名
})
6.HSP场景
let contexts = getContext(this).createModuleContext('library') as common.UIAbilityContext;
lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
animationData: this.jsonData, // json对象数据
context: contexts, // 当前场景上下文context
contentMode: 'Contain', // 填充的模式
initialSegment: [10,50] // 播放的动画片段
})
let resStr = new util.TextDecoder('utf-8',{ignoreBOM: true});
let context = getContext(this).createModuleContext('library') as common.UIAbilityContext
context.resourceManager.getRawFile('grunt.json',(err: Error,data: Uint8Array) =>{
if(data === null || data === undefined || data.buffer=== undefined){
return;
}
let lottieStr = resStr.decode(new Uint8Array(data.buffer));
this.jsonData = JSON.parse(lottieStr);
})
7.控制动画
播放动画
lottie.play() //所有动画播放
或
animationItem.play() //当前指定animationItem动画播放
停止动画
lottie.stop() //所有动画停止
或
animationItem.stop() //当前指定animationItem动画停止
暂停动画
lottie.pause() //所有动画暂停
或
animationItem.pause() //当前指定animationItem动画暂停
切换暂停/播放
lottie.togglePause() //所有动画切换暂停/播放
或
animationItem.togglePause() //当前指定animationItem动画切换暂停/播放
设置播放速度
注意:speed>0正向播放, speed<0反向播放, speed=0暂停播放, speed=1.0/-1.0正常速度播放
lottie.setSpeed(1) //所有动画设置播放速度
或
animationItem.setSpeed(1) //当前指定animationItem动画设置播放速度
设置动画播放方向
注意:direction 1为正向,-1为反向
lottie.setDirection(1) //所有动画设置播放方向
或
animationItem.setDirection(1) //当前指定animationItem动画设置播放方向
销毁动画
注意:页面不显示或退出页面时,需要销毁动画; 可配合页面生命周期aboutToDisappear()及onPageHide(),或者Canvas组件的onDisAppear()使用
lottie.destroy() //销毁所有动画
或
lottie.destroy('name') //销毁指定name动画
控制动画停止在某一帧或某一时刻
注意:根据第二个参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false
animationItem.goToAndStop(250,true)
或
animationItem.goToAndStop(5000,false)
控制动画从某一帧或某一时刻开始播放
注意:根据第二参数判断按帧还是按毫秒控制,true 按帧控制,false 按时间控制,缺省默认为false
animationItem.goToAndPlay(250,true)
或
animationItem.goToAndPlay(12000,false)
限定动画资源播放时的整体帧范围,即设置动画片段
animationItem.setSegment(5,15);
播放动画片段
注意:第二参数值为true立刻生效, 值为false循环下次播放的时候生效
animationItem.playSegments([5,15],[20,30],true)
重置动画播放片段,使动画从起始帧开始播放完整动画
注意:参数值为true立刻生效, 值为false循环下次播放的时候生效
animationItem.resetSegments(5,15);
获取动画时长/帧数
注意:参数值为true时获取帧数,值为false时获取时间(单位ms)
animationItem.getDuration();
添加侦听事件
注意:添加和移除的事件监听,回调函数需是同一个,需预先定义,否则将不能正确移除
AnimationEventName = 'enterFrame' | 'loopComplete' | 'complete' | 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready' | 'DOMLoaded' | 'error' | 'data_failed' | 'loaded_images';
animationItem.addEventListener("enterFrame",function(){
// TODO something
})
更改动画渲染颜色
注意:第一个参数颜色是RGB值,第二个参数是动画的层次 可不填,第三个参数是对应动画层次的元素的下标值 可不填
animationItem.changeColor([255,150,203]) //修改整个动画的颜色
或
animationItem.changeColor([255,150,203],2) //修改该动画第二层的颜色
或
animationItem.changeColor([255,150,203],2,2) //修改该动画第二层第二个元素的颜色
移除侦听事件
animationItem.removeEventListener("enterFrame",function(){
// TODO something
})
刷新动画布局
animationItem.resize()
动画填充模式
注意:动画填充模式共有5种:Fill,Cover,Top,Bottom,Contain,其中默认的填充模式是:Contain
animationItem.setContentMode('Cover');
设置动画的刷帧率
注意:设置动画animator的刷帧率,范围是1~120 帧率越大,功耗越严重
animationItem.setFrameRate(30);
8.动画销毁
执行this.animationItem.destroy(),只会销毁name为2016的动画,name为cat的动画不会被销毁。建议:动画销毁时,使用lottie.destroy方式进行销毁。
说明一:当同一个页面中存在多个动画,且动画实例赋值给同一个变量animationItem时,使用animationItem.destroy销毁动画时,只会销毁最后一个。如下代码示例,将name为cat和2016的动画同时赋值给this.animationItem,执行animationItem.destroy()销毁动画时,仅销毁最后加载的name为2016动画。name为cat的动画不会被销毁。
this.animationItem = lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
name: 'cat', // 动画名称
contentMode: 'Contain', // 填充的模式
path: this.path, // json路径
initialSegment: [10,50] // 播放的动画片段
})
this.animationItem = lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // 渲染方式
loop: true, // 是否循环播放,默认true
autoplay: true, // 是否自动播放,默认true
name: '2016', // 动画名称
contentMode: 'Contain', // 填充的模式
path: this.path, // json路径
initialSegment: [10,50] // 播放的动画片段
})
说明二:当lottie未加载完成前( lottie.loadAnimation方法和下述方法在同一代码块中同时使用),调用下述方法可能导致设置无效:stop、togglePause、pause、goToAndStop、goToAndPlay、setSegment、getDuration、changeColor、setContentMode。应将上述方法在动画加载完成之后再执行,通过animationItem.addEventListener('DOMLoaded')监听动画加载完成,示例如下:
// 动画未加载完成,changeColor和setContentMode设置无效
Button('加载2016')
.onClick(() => {
if (this.animationItem2 == null) {
this.animationItem2 = lottie.loadAnimation({
container: this.canvasRenderingContext,
renderer: 'canvas', // canvas 渲染模式
name: '2016',
path: "common/lottie/data.json",
})
this.animationItem2.changeColor([255, 203]);
this.animationItem2.setContentMode('Top');
}
})
// animationItem.addEventListener('DOMLoaded')监听后执行方法,changeColor和setContentMode设置有效
Button('加载2016')
.onClick(() => {
if (this.animationItem2 == null) {
this.animationItem2 = lottie.loadAnimation({
container: this.canvasRenderingContext,
renderer: 'canvas', // canvas 渲染模式
loop: true,
autoplay: false,
name: '2016',
contentMode: 'Contain',
path: "common/lottie/data.json",
})
this.animationItem2.addEventListener('DOMLoaded', (args: Object): void => {
this.animationItem2.changeColor([255, 203]);
// this.animationItem2.setContentMode('Top');
// ...
}); //动画加载完成,播放之前触发
}
})
9.缓存使用示例
//不使用缓存
if (this.animateItem2 == null) {
this.animateItem2 = lottie.loadAnimation({
container: this.canvasRenderingContext,
renderer: 'canvas', // canvas 渲染模式
loop: true,
autoplay: true,
name: '2016',
contentMode: 'Contain',
cacheKey: null, // 指定为null 不使用缓存
//cacheKey : '', // 指定为'' 不使用缓存
path: "common/lottie/data.json", // 加载路径
})
}
//使用缓存 不指定cacheKey或者指定cacheKey
if (this.animateItem2 == null) {
this.animateItem2 = lottie.loadAnimation({
container: this.canvasRenderingContext,
renderer: 'canvas', // canvas 渲染模式
loop: true,
autoplay: true,
name: '2016',
contentMode: 'Contain',
// cacheKey : 'testKey', // 指定缓存键值
path: "common/lottie/data.json", // 加载路径
})
}
//清除缓存
lottie.cacheClear();
//移除指定键缓存
lottie.cacheRemove('testKey')
//设置缓存容器大小
lottie.cacheReSize(10)
//检查是否存在指定key
lottie.cacheContains('testKey')
//设置任务缓存容器大小
lottie.resizeTaskCache(10)
使用方法 | 参数类型 | 相关描述 |
---|---|---|
play() | name? | 播放 |
stop() | name? | 停止 |
pause() | name? | 暂停 |
togglePause() | name? | 切换暂停 |
destroy() | name? | 销毁动画 |
goToAndStop() | value, isFrame?, name? | 跳到某一时刻并停止 |
goToAndPlay() | value, isFrame?, name? | 跳到某一时刻并播放 |
setSegment() | init,end | 设置动画片段 |
playSegments() | arr, forceFlag | 播放指定片段 |
resetSegments() | forceFlag | 重置动画 |
setSpeed() | speed | 设置播放速度 |
setDirection() | direction | 设置播放方向 |
getDuration() | isFrames? | 获取动画时长 |
addEventListener() | eventName,callback | 添加监听状态 |
removeEventListener() | name,callback? | 移除监听状态 |
changeColor() | color, layer?, index? | 更改动画颜色 |
setContentMode() | contentMode | 设置填充模式 |
setFrameRate() | frameRate | 设置动画刷帧率 |
cacheClear() | 清除缓存 | |
cacheRemove() | string | 移除指定键缓存 |
cacheReSize() | number | 设置缓存容器大小 |
cacheContains() | string | 检查是否存在指定key |
resizeTaskCache() | number | 设置任务缓存容器大小 |
支持canvas渲染模式下动画的高斯模糊效果
支持canvas渲染模式下加载外部资源图片
支持设置动画animator的刷帧率
支持加载网络资源和通过URI路径方式加载动画
在下述版本验证通过:
/lottie # 项目根目录
├── entry # 示例代码文件夹
├── library # lottie库文件夹
│ └─ src/main/js
│ └─ build/player
│ └─ lottie.js # 核心代码,包含json解析,动画绘制,操作动画
│ └─index.d.ts # 接口声明文档
├── README.md # 安装使用方法
使用过程中发现任何问题都可以提 Issue 给我们,当然,我们也非常欢迎你给我们发 PR 。
本项目基于 MIT License ,请自由地享受和参与开源。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。