属性动画

  • 属性动画是通过设置组件的animation属性来给组件添加动画,当组件的widthheightOpacitybackgroundColorscalerotatetranslate等属性变更时,可以实现渐变过度效果。
名称 参数类型 必填 描述
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
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
Image($r('app.media.ultramanIcon'))  
.position({x: this.ultraX, y: this.ultraY}) //x轴坐标,Y轴坐标
.rotate({
angle: this.ultraA, //旋转角度
centerX: '50%', //旋转中心横坐标
centerY: '50%'}) //旋转中心纵坐标
.width(60)
.height(60)
.animation({duration: 500}) //添加属性动画,在上表,设置动画时长为500ms

Row(){ //四个方位的按钮
Button('←').backgroundColor('#36D')
.onClick(() => {
this.ultraX -= 10
})
Column({space: 40}){
Button('↑').backgroundColor('#36D')
.onClick(() => {
this.ultraY -= 10
})
Button('↓').backgroundColor('#36D')
.onClick(() => {
this.ultraY += 10
})
}
Button('→').backgroundColor('#36D')
.onClick(() => {
this.ultraX += 10
})
}

image.png

显式动画

  • 显式动画是通过全局animateTo函数来修改组件属性,实现属性变化时的渐变过度效果。
  • 不需要在组件后添加animation属性,可以直接在触发事件处添加animateTo函数。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Button('←').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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//触发事件处添加animateTo函数
animateTo(
{duration: 1000}, //动画参数
() => {
this.iconFlag = true
}
)

if(this.iconFlag){
Image($r('app.media.ultramanIcon'))
.position({x: this.ultraX, y: this.ultraY})
.rotate({angle: this.ultraA, centerX: '50%', centerY: '50%'})
.width(60)
.height(60)
.transition({ //转场动画参数
type: TransitionType.Insert, //设置为入场
opacity: 0, //设置入场时透明度为0
translate: {y: -200} //设置从设定位置Y轴-200处平移入场
})
}

实例:摇杆控制方向

  • 实现一个摇杆控制移动方向
  • 图为静态效果
    image.png
    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
    //声明变量
    @State ultraX: number = 150 //图标的x轴
    @State ultraY: number = 250 //图标的y轴
    @State ultraA: number = 0 //图标的角度
    @State iconFlag: boolean = false //是否出现图标
    private centerX: number = 120 //摇杆的中心x轴
    private centerY: number = 120 //摇杆的中心y轴
    private maxR: number = 100 //摇杆外围半径
    private minR: number = 20 //摇杆小半径
    @State positionX: number = this.centerX //摇杆位置x轴
    @State 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)
    }