鸿蒙HarmonyOS 4-动画
属性动画
- 属性动画是通过设置组件的animation属性来给组件添加动画,当组件的width、height、Opacity、backgroundColor、scale、rotate、translate等属性变更时,可以实现渐变过度效果。
| 名称 | 参数类型 | 必填 | 描述 | 
|---|---|---|---|
| duration | number | 否 | 设置动画时长 默认值:1000,单位:毫秒 | 
| tempo | number | 否 | 动画播放速度。数值越大,速度越快。 默认值:1 | 
| curve | string | Curve | 否 | 设置动画曲线。 默认值:Curve.EaselnOut,平滑开始和结束 | 
| delay | number | 否 | 设置动画延迟执行的时长 默认值:0,单位:毫秒 | 
| iterations | number | 否 | 设置播放次数。 默认值:1,取值范围:[-1,+o) 说明:设置为-1时表示无限次播放。 | 
| playMode | PlayMode | 否 | 设置动画播放模式,默认播放完成后重头开始播放 默认值:PlavMode.Normal | 
| onFinish | ()=> void | 否 | 状态回调,动画播放完成时触发。 | 
| 1 | Image($r('app.media.ultramanIcon')) | 

显式动画
- 显式动画是通过全局animateTo函数来修改组件属性,实现属性变化时的渐变过度效果。
- 不需要在组件后添加animation属性,可以直接在触发事件处添加animateTo函数。1 
 2
 3
 4
 5
 6
 7
 8
 9
 10Button('←').backgroundColor('#36D') //以←为例 
 .onClick(() => { //添加点击事件
 //this.ultraX -= 10
 animateTo(
 {duration: 500}, //动画参数,与animation相同
 () => { //修改组件属性关联的状态变量
 this.ultraX -= 10
 }
 )
 })
组件转场动画
- 组件转场动画是在组件插入或移除时的过渡动画,通过组件的transition属性来配置。
| 参数名称 | 参数类型 | 必填 | 参数描述 | 
|---|---|---|---|
| type | TransitionType | 否 | 类型,默认包括组件新增和删除。默认是ALL | 
| opacity | number | 否 | 不透明度,为插入时起点和删除时终点的值 默认值:1,取值范围:[0,1] | 
| translate | { x? : number | string, y? : number | string, z? : number | string } | 否 | 平移效果,为插入时起点和删除时终点的值。 -x:横向的平移距离 -y:纵向的平移距离 -z:竖向的平移距离 | 
| scale | { x? : number, y? : number, z? : number, centerX? : number|string, centerY? : number]string } | 否 | 缩放效果,为插入时起点和删除时终点的值。 -x:横向放大倍数(或缩小比例)。 -y:纵向放大倍数(或缩小比例)。 -z:当前为二维显示,该参数无效。 - centerX、centerY指缩放中心点。 - centerX和centerY默认值是”50%”。 - 中心点为0时,默认的是组件的左上角。 | 
| rotate | { x?: number, y?: number, z?: number, angle: number | string, centerX?: number| string, centerY?: numberl string } | 否 | 旋转效果: angle是旋转角度,其它参数与scale类似 | 
| 1 | //触发事件处添加animateTo函数 | 
- 更多转场动画可以参考鸿蒙开发文档
实例:摇杆控制方向
- 实现一个摇杆控制移动方向
- 图为静态效果 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83//声明变量 
 ultraX: number = 150 //图标的x轴
 ultraY: number = 250 //图标的y轴
 ultraA: number = 0 //图标的角度
 iconFlag: boolean = false //是否出现图标
 private centerX: number = 120 //摇杆的中心x轴
 private centerY: number = 120 //摇杆的中心y轴
 private maxR: number = 100 //摇杆外围半径
 private minR: number = 20 //摇杆小半径
 positionX: number = this.centerX //摇杆位置x轴
 positionY: number = this.centerY //摇杆位置y轴
 sin: number = 0 //摇杆位置对于中心点的sin值
 cos: number = 0 //摇杆位置对于中心点的cos值
 speed: number = 0 //图标移动的速度
 taskId: number = -1 //定时任务id
 //摇杆的外形,两个圆
 Row(){
 Circle({width: this.maxR * 2, height: this.maxR * 2})
 .fill('#20101010')
 .position({x: this.centerX - this.maxR, y: this.centerY - this.maxR}) //减去半径就是原点位置
 Circle({width: this.minR * 2, height: this.minR * 2})
 .fill('#403A3A3A')
 .position({x: this.positionX - this.minR, y:this.positionY - this.minR})
 }
 .height(240)
 .width(240)
 .justifyContent(FlexAlign.Center)
 .onTouch(this.handleTouchEvent.bind(this)) //代入获取手指触控数据的函数
 //摇杆数据计算和处理
 handleTouchEvent(event: TouchEvent){ //获取手指触控数据函数
 switch (event.type){ //判断手指触摸屏幕的状态
 case TouchType.Up: //离开屏幕
 this.speed = 0 //重置速度
 clearInterval(this.taskId) //重置定时任务
 animateTo( //摇杆复位动画
 {curve: curves.springMotion()}, //缓慢复位
 () => {
 this.positionX = this.centerX
 this.positionY = this.centerY
 }
 )
 break
 case TouchType.Down: //按住屏幕
 //开始定时任务
 this.taskId = setInterval(() => {
 this.ultraX += this.speed * this.cos
 this.ultraY += this.speed * this.sin
 }, 40) //每40ms一次,相当于25帧
 break
 case TouchType.Move: //在屏幕上移动
 //获取手指位置坐标
 let x = event.touches[0].x
 let y = event.touches[0].y
 //计算手指与中心点的坐标差值
 let vx = x - this.centerX
 let vy = y - this.centerY
 //计算手指与中心点连线和x轴正半轴的夹角弧度
 let angle = Math.atan2(vy, vx)
 //计算手指与中心点的距离
 let distance = this.getDistance(vx, vy)
 //计算摇杆小球的坐标
 this.sin = Math.sin(angle)
 this.cos = Math.cos(angle)
 animateTo( //图标移动动画
 {curve: curves.responsiveSpringMotion()}, //跟手的平滑动画
 () => {
 this.positionX = this.centerX + distance * this.cos
 this.positionY = this.centerY + distance * this.sin
 //修改移动坐标
 this.speed = 5 //设置移动速度
 }
 )
 break
 }
 }
 //计算摇杆与中心点的位置,不超出外圈
 getDistance(x: number, y: number){
 let d = Math.sqrt(x * x + y * y)
 return Math.min(d, this.maxR)
 }
 评论
