鸿蒙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)
}
评论