如何使用属性动画实现简单属性变化的动画效果

一、简介
继《openharmony有氧拳击设备端的开发》后,本次为大家带来酷炫的应用端开发。如下视频,开发者伴随着音乐,律动出拳后,那开发板屡屡播放“挨打”效果,这究竟是怎么一回事?让我们一探背后原理。     这款拳击游戏开始时会播放音乐,然后以随机速度下落“击拳方块”。当小哥哥在击拳区域内挥拳时,游戏会判断方块的位置,根据不同位置确定播放普通击中或完美击中的动画效果。
二、动画
游戏中一共使用两种动画:属性动画和lottie动画,分别实现下落和击中的效果。“击拳方块”下落效果是利用属性动画进行修改偏移量来实现。游戏同时设置定时器,定时获取挥拳状态和“击拳方块”的所处位置,用于判断当前挥拳是否得分。若得分则根据击中区间来播放不同效果的lottie动画。  
三、“下落”动画
1、属性动画介绍
从上图可以看到,游戏中“击拳方块”是自上而下匀速移动。这种简单控制通用属性进行动画变化的动画,便很适合使用属性动画来实现。属性动画是指组件的通用属性发生变化时,会根据开始状态和通用属性改变后的状态作为动画关键帧,在指定时间内实现渐变效果。换言之我们只需要确定设置好组件在动画结束时的组件属性,然后调用animateto(value: animationoptions, event: ()=> void),即可创建属性动画。
animationoptions对象说明
● 属性
● 接口
2、动画实现
编写“击拳方块”ui组件,并将组件的相对布局偏移量offset属性,绑定到@state lefty1变量中,那么通过修改lefty1的值即可实现修改组件所在位置。
@state lefty1: string = '50%' @builder leftboxing(offsety: string) { image($r('app.media.icon_boxing_left')) .width(144) .height(110) .offset({ x: -30%, y: offsety }) .touchable(true) } build() { stack() { // ..... // 左侧 this.leftboxing(this.lefty1) // .....    }
3、创建动画
调用animateto显式动画来播放动画实现单个“击拳方块”自上而下地移动,再通过设置delay参数实现4个“击拳方块”按顺序分别移动。
async leftanimate(){ // 设置图标下滑动画 // 动画持续时间 let leftduration = this.getrandomduration() this.leftduration = leftduration // 延迟时长 let leftdelay = leftduration / (this.boxingcount - 1) // 设置开始时间 let now = new date this.animatelefttimestamp = now.gettime() // 左侧animateto动画 animateto({ duration: leftduration, curve: curve.linear,delay:0 * leftdelay ,iterations: 1 }, () => { this.lefty1 = 50% }) animateto({ duration: leftduration, curve: curve.linear,delay:1 * leftdelay, iterations: 1 }, () => { this.lefty2 = 50% }) animateto({ duration: leftduration, curve: curve.linear,delay:2 * leftdelay, iterations: 1 }, () => { this.lefty3 = 50% }) animateto({ duration: leftduration, curve: curve.linear,delay:3 * leftdelay, iterations: 1 }, () => { this.lefty4 = 50% }) let totaltime = leftduration + 3 * leftdelay await this.sleep(totaltime) this.resetanimate(true) this.leftanimate()    }
4、设置击中区域监听
设置定时器定时查询当前是否挥拳,若检测到挥拳再通过计算当前动画运行时间来判断“击拳方块”位置,从而执行击中或完美击中的逻辑,以下为监听逻辑。
setscorelisten(){ this.intervalnumber = setinterval(async()=>{ let res = await boxinggamenapi.recvmsg(); if(res?.message.length > 0){ if(res.message.includes('left') && !this.leftanimatelock){ // 检测到左手挥拳 this.judgeleft() } } },200) } judgeleft(){ let nowtime = new date().gettime() // 首次抵达目标顶部时间 let firsttime = this.animatelefttimestamp + (this.percenttopoint(this.targetoffsety)+this.percenttopoint('50%') - this.percenttopoint('10%')) * this.leftduration // 结束时间 let endtime = this.animatelefttimestamp + this.leftduration * 2 if(nowtime > firsttime - 200 && nowtime < endtime){ // 得分时间界限 let leftdelay = this.leftduration /(this.boxingcount -1 ) let handletime = (nowtime - firsttime) % leftdelay let judgetime = this.leftduration /6 commonlog.info(tag,`leftdelay:${leftdelay},handletime:${handletime},judgetime:${judgetime}`) // 完美击中 if (judgetime/4 < handletime && handletime < (judgetime *(3/4))) { }else if(handletime { }) animator('__lottie_ets') // declare animator('__lottie_ets') when use lottie }.height('100%').width(220)    }设置lottie动画参数:
setlottie(controller:canvasrenderingcontext2d,lottiename:string,animatepath:string){ lottie.loadanimation({ container: controller, renderer: 'canvas', loop: false, autoplay: false, name: lottiename, path: animatepath, }) lottie.setspeed(1,lottiename)    }在“下落”动画击拳监听中加入播放不同效果的lottie动画逻辑:
judgeleft(){ ...... if(nowtime > firsttime - 200 && nowtime < endtime){ ...... // 完美击中 if (judgetime/4 < handletime && handletime { lottie.stop() lottie.destroy('animate_left') this.leftanimatelock = false },this.lottieduration) }else if(handletime { lottie.stop() lottie.destroy('animate_left') this.leftanimatelock = false },this.lottieduration) } }    }   
五、总结
本文主要讲述了拳击互动游戏中,如何使用属性动画实现简单属性变化的动画效果,如游戏中“击拳方块”自上往下移动;使用lottie组件实现复杂绚丽的动画效果,如游戏中的击拳效果。
本样例是openharmony知识体系工作组(相关链接在文章末尾)为广大开发者分享的样例。知识体系工作组结合日常生活,给开发者规划了各种场景的demo样例,如智能家居场景、影音娱乐场景、运动健康场景等。欢迎广大开发者一同参与openharmony的开发,更加完善样例,相互学习,相互进步。


液晶彩电高压板电路构成方案揭秘
风力发电机多少钱一台
笔记本电池电路及保护电路的作用
2021年是5G toB的元年吗?
数字电源开发板设计方案,可二次开发
如何使用属性动画实现简单属性变化的动画效果
Advanced Simulation高级图形仿真
国产激光器关注度明显升温 国产激光器速度加快
2017款长安福特翼虎车发动机故障灯异常点亮
采购弹簧疲劳试验机有什么注意事项?
提升画质的利器 投影幕选购指导
5G网络时代将要来临,各大巨头都在蠢蠢欲动
奥迪前三季度财报显示营收为413亿欧元同比下降6.8%
中国政府将在2018年7月份同意LGD在广州建设OLED面板工厂的投资案
磁力启动器工作原理_磁力启动器作用
云端XR平台提供商GridRaster完成250万美元融资
利用HFSS设计毫米波圆极化介质复合波导缝隙天线
是什么烧坏了你的处理器?
华为呼吁在网络攻击日益加剧的情况下增加对5G技术的采用
2020年人工智能行业的那些槽点