HarmonyOS鸿蒙Next中json动画用啥方便一点
HarmonyOS鸿蒙Next中json动画用啥方便一点
开发者你好,加载json动画可以使用lottie三方库。
【背景知识】 [@ohos/lottie](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie)提供了使用JSON动画文件的解决方案,具有一套完整的API控制动画的行为,可以让动画更具有交互性。
【解决方案】
参考点赞弹出动画实现:
- 通过overlay构建中间图片
- 通过isLiked来控制点击之后图标颜色的切换的效果。
- 通过lottie三方库加载json动画,在动画完成一次之后销毁页面的动画。
参考示例代码:
import lottie, { AnimationItem } from '[@ohos](/user/ohos)/lottie';
@Entry
@Component
export struct Page25051301 {
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
private canvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings)
private mainRenderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
private mainCanvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mainRenderingSettings)
private animateItem: AnimationItem | null = null;
private mianItem: AnimationItem | null = null;
@State imageSrcList: ResourceStr = $r('app.media.like')
// 未点赞时的颜色(灰色)
@State unlikeColor: string = '#757575'
// 点赞后的颜色(蓝色)
@State likeColor: string = '#ff4eb1e6'
// 是否已点赞状态
@State isLiked: boolean = false
// 控制Image组件和Canvas的切换
@State isVisibility:boolean=true
// 防止动画过程中点去除颜色
@State isFlag:boolean=false
// 第一个canvas动画的名称
@State animateName:string='animateName'
// 第二个canvas动画的名称
@State mainNme:string='mainNme'
// 控制图片显示和隐藏
@State visibilityType:Visibility=Visibility.Visible
onPageHide(): void {
lottie.destroy()
}
@Builder
OverlayNode() {
Canvas(this.mainCanvasRenderingContext)
.width(200)
.aspectRatio(1)
.onReady(() => {
this.mianItem?.resize();
})
}
build() {
Column() {
Stack({alignContent:Alignment.Center}) {
Image(this.imageSrcList)
.width(100+'px')
.aspectRatio(1)
.fillColor(this.isLiked ? this.likeColor : this.unlikeColor)// 图片要求svg格式
.visibility(this.isVisibility?Visibility.Visible:Visibility.None)
Column() {
Canvas(this.canvasRenderingContext)
.width(100)
.aspectRatio(1)
.backgroundColor(Color.Transparent)
.onReady(() => {
this.animateItem?.resize();
})
}
}
.onClick(()=>{
// 防止动画过程中填充色的消除
if(this.isFlag) return
// 点击时切换点赞状态
this.isLiked = !this.isLiked
if(this.isLiked) {
this.isVisibility=false
this.onLoadAnimation()
this.mianOnLoadAnimation()
}
})
.width(200)
.height(200)
}
.overlay(this.OverlayNode(), { align: Alignment.Center })
.width('100%')
.height('100%')
.backgroundColor('#f1f1f1')
}
// 点赞动图加载
onLoadAnimation() {
lottie.destroy(this.animateName)
this.isFlag=true
this.animateItem = lottie.loadAnimation({
container: this.canvasRenderingContext, // 渲染上下文
renderer: 'canvas', // canvas 渲染模式
loop:true,
name: this.animateName,
frameRate: 30,
contentMode: 'Cover',
path: "lottie/like.json", // 路径加载动画只支持entry/src/main/ets 文件夹下的相对路径
})
// 监听完成一次动画
this.animateItem.addEventListener('loopComplete', (args: Object): void => {
if( this.animateItem?.playCount==1) {
lottie.destroy(this.animateName)
this.isVisibility=true
this.isFlag=false
}
});
}
mianOnLoadAnimation() {
lottie.destroy(this.mainNme)
this.mianItem = lottie.loadAnimation({
container: this.mainCanvasRenderingContext, // 渲染上下文
renderer: 'canvas', // canvas 渲染模式
autoplay: true,
loop:true,
name: this.mainNme,
frameRate: 30,
contentMode: 'Contain',
path: "lottie/like.json", // 路径加载动画只支持entry/src/main/ets 文件夹下的相对路径
})
// 监听完成一次动画
this.mianItem.addEventListener('loopComplete', (args: Object): void => {
if( this.mianItem?.playCount==1) {
lottie.destroy(this.mainNme)
}
});
}
}
更多关于HarmonyOS鸿蒙Next中json动画用啥方便一点的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
JSON 动画一版都采用 Lottie 动画库,能高效实现复杂动画效果且开发便!!
步骤一:先通过命令 ohpm install @ohos/lottie 安装。再添加 Lottie 依赖:
"dependencies": {
"[@ohos](/user/ohos)/lottie": "2.0.20"
}
步骤二:将 JSON动画 文件放置在项目目录下
步骤三:通过 Canvas 组件绑定 Lottie 动画:
Canvas(this.canvasContext)
.onReady(() => {
lottie.loadAnimation({
container: this.canvasContext, // 绑定画布
renderer: 'canvas',
loop: true,
autoplay: true,
path: 'common/lottie/animation.json' // 第二步你放置的JSON 文件路径
});
})
Lottie
库地址
[https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie)
import lottie, { AnimationItem } from '[@ohos](/user/ohos)/lottie';
@Entry
@Component
struct Index {
// 构建上下文
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true);
private canvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings);
private animateItem: AnimationItem | null = null;
private animateName: string = 'animation';
// 页面销毁时释放动画资源
aboutToDisappear(): void {
console.info('aboutToDisappear');
lottie.destroy();
}
build() {
Row() {
// 关联画布
Canvas(this.canvasRenderingContext)
.width(200)
.height(200)
.backgroundColor(Color.Gray)
.onReady(() => {
// 加载动画
if (this.animateItem != null) {
// 可在此生命回调周期中加载动画,可以保证动画尺寸正确
this.animateItem?.resize();
} else {
// 抗锯齿的设置
this.canvasRenderingContext.imageSmoothingEnabled = true;
this.canvasRenderingContext.imageSmoothingQuality = 'medium';
this.loadAnimation();
}
})
}
}
loadAnimation() {
this.animateItem = lottie.loadAnimation({
container: this.canvasRenderingContext,
renderer: 'canvas', // canvas 渲染模式
loop: true,
autoplay: false,
name: this.animateName,
contentMode: 'Contain',
path: 'common/animation.json',
})
// 因为动画是异步加载,所以对animateItem的操作需要放在动画加载完成回调里操作
this.animateItem.addEventListener('DOMLoaded', (args: Object): void => {
this.animateItem.changeColor([225, 25, 100, 1]);
this.animateItem.play();
});
}
destroy() {
this.animateItem.removeEventListener('DOMLoaded');
lottie.destroy(this.animateName);
this.animateItem = null;
}
}
在HarmonyOS Next中,推荐使用Lottie或SVGA实现JSON动画。Lottie通过解析JSON格式的Bodymovin文件高效渲染矢量动画,SVGA则支持跨平台高性能动画播放。两者均兼容鸿蒙的ArkUI框架,可直接在组件中调用,无需依赖Java或C语言。
在HarmonyOS Next中,推荐使用Lottie库来处理JSON动画。Lottie支持解析和渲染由After Effects导出的JSON动画文件,集成简单且性能优秀。可以通过ohpm安装lottie-ohos
包,并直接加载JSON文件实现流畅动画效果。