Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArkUI - 动画 #43

Open
cnwutianhao opened this issue Apr 5, 2024 · 0 comments
Open

ArkUI - 动画 #43

cnwutianhao opened this issue Apr 5, 2024 · 0 comments

Comments

@cnwutianhao
Copy link
Owner

利用属性动画显示动画组件转场动画实现组件动画效果。

一、属性动画

属性动画是通过设置组件的 animation 属性来给组件添加动画,当组件的 width、height、Opacity、backgroundColor、scale、rotate、translate 等属性变更时,可以实现渐变过渡效果。

以 Image 组件为例,给它添加动画,其实就是给它添加 animation 的属性:

Image($r('app.media.app_icon'))
  .position({
    x: 10, // x轴坐标
    y: 10  // y轴坐标
  })
  .rotate({
    angle: 0,       // 旋转角度
    centerX: '50%', // 旋转中心横坐标
    centerY: '50%'  // 旋转中心纵坐标
  })
  .animation({
    duration: 1000,
    curve: Curve.EaseInOut
  })

这时,ArkUI 就能帮我们监控组件的样式变化,我们只需要在与用户互动的事件当中去修改组件的样式,ArkUI 一旦发现组件的样式变化,就会自动填充起始样式和结束样式之间的每一帧画面,从而实现样式变化的渐变过渡效果。所以,一个动画就出来了。

注意:

  1. animation 属性一定要放在需要有动画属性的样式之后。就像上面的实例代码,animation 要放在 position 和 rotate 之后。如果把 animation 放在前面,然后再写 position 和 rotate,那么这俩就不会有任何的变化。

  2. animation 属性不是对所有样式都有效。

animation 可以传递的动画参数:

名称 参数类型 必填 描述
duration number 设置动画时长。
默认值:1000,单位:毫秒
tempo number 动画播放速度。数值越大,速度越快。
默认值:1
curve Curve 设置动画曲线。
默认值:Curve.EaseInOut,平滑开始和结束。
delay number 设置动画延迟执行的时长。
默认值:0,单位:毫秒
iterations number 设置播放次数。
默认值:1,取值范围:[-1, +∞)
说明:设置为 -1 时表示无限次播放。
playMode PlayMode 设置动画播放模式,默认播放完成后重头开始播放。
默认值:PlayMode.Normal
onFinish ()=> void 状态回调,动画播放完成时触发。

示例代码:

@Entry
@Component
struct Index {
  @State textX: number = 10
  @State textY: number = 10

  build() {
    Column() {
      Image($r('app.media.app_icon'))
        .position({
          x: this.textX,
          y: this.textY
        })
        .rotate({
          angle: 0,
          centerX: '50%',
          centerY: '50%'
        })
        .width(40)
        .height(40)
        .animation({
          duration: 500
        })

      Button('按钮')
        .position({
          x: 10,
          y: 100
        })
        .onClick(() => {
          this.textX += 20
        })
    }
  }
}

运行效果:

二、显示动画

显示动画是通过全局 animationTo 函数来修改组件属性,实现属性变化时的渐变过渡效果。

显示调用 animationTo 函数触发动画:

animateTo(
  { duration: 1000 }, // 动画参数
  () => {
    // 修改组件属性关联的状态变量
  })

示例代码:

@Entry
@Component
struct Index {
  @State textX: number = 10
  @State textY: number = 10

  build() {
    Column() {
      Image($r('app.media.app_icon'))
        .position({
          x: this.textX,
          y: this.textY
        })
        .rotate({
          angle: 0,
          centerX: '50%',
          centerY: '50%'
        })
        .width(40)
        .height(40)

      Button('按钮')
        .position({
          x: 10,
          y: 100
        })
        .onClick(() => {
          animateTo(
            { duration: 500 },
            () => {
              this.textX += 20
            }
          )
        })
    }
  }
}

三、组件转场动画

组件转场动画是在组件插入或移除时的过渡动画,通过组件的 transition 属性来配置。组件插入可以理解为组件从无到有,也就是一个入场的过程;组件移除可以理解为组件从有到无,也就是一个退场的过程。

语法:

Image($r('app.media.app_icon'))
  .transition({
    opacity: 0,
    rotate: { angle: -360 },
    scale: { x: 0, y: 0 }
  })

动画参数:

参数名称 参数类型 必填 参数描述
type TransistionType 类型,默认包含组件新增和删除。
默认是 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?: number或string
}
旋转效果:
angle 是旋转角度,其它参数与 scale 类似。

注意:transition 要结合 animateTo 去使用。

示例代码:

@Entry
@Component
struct Index {
  @State isBegin: boolean = false

  build() {
    Column() {
      if (this.isBegin) {
        Image($r('app.media.app_icon'))
          .position({
            x: 10,
            y: 10
          })
          .width(100)
          .height(100)
          .transition({
            type: TransitionType.Insert,
            opacity: 0,
            translate: { x: -100 }
          })
      }

      Button('按钮')
        .position({
          x: 10,
          y: 200
        })
        .onClick(() => {
          animateTo(
            { duration: 1000 },
            () => {
              this.isBegin = true
            })
        })
    }
  }
}

运行效果:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant