HarmonyNote.TOP鸿蒙开发笔记

鸿蒙组件transform变形及animateTo动画效果实践

鸿蒙ArkUI里的组件可以实现各种各样的变形及动画效果,比如我想将一张图片进行缩放操作,可以在 X、Y、Z 轴上独立设置缩放比例,示例代码如下:

@Entry
@Component
struct EffectDemo {
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        .transform({ scale: { x: 1.5, y: 1.0, z: 0.8 } })
    }
  }
}

可在真机上运行的时候发现并没有达到预期的图片缩放效果,查看SDK源码得知,要实现缩放操作,还可以直接调用scale方法,将上述代码改变如下:

@Entry
@Component
struct EffectDemo {
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        .scale({ x: 1.5, y: 1.0, z: 0.8 })
    }
  }
}

在真机上运行就能看到图片已经按照给定参数实现缩放变形了,也就是说调用transform方法并不能实现平移(Translate)、2. 旋转(Rotate)、3. 缩放(Scale)等变形效果了,需要调用对应的专用方法translate、rotate及scale方法名。下面再举例一个rotate旋转变形代码如下:

@Entry
@Component
struct EffectDemo {
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        // 没有效果
        // .transform({ rotate: { angle: 45 } })
        // 有效果
        .rotate({ angle: 45 })
    }
  }
}

一、animateTo实现单个动画效果

复用上面的例子,用animateTo实现单个scale缩放动画,示例代码如下:

@Entry
@Component
struct EffectDemo {
  @State
  scaleX: number = 1
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        .scale({x: this.scaleX})
        .onClick(()=>{
          animateTo({
            duration: 10000,
          }, () => {
            this.scaleX = 2;
          })
        })
    }
  }
}

用animateTo实现单个rotate旋转动画,示例代码如下:

@Entry
@Component
struct EffectDemo {
  @State
  angle: number = 0
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        .rotate({angle: this.angle})
        .onClick(()=>{
          animateTo({
            duration: 1000,
          }, () => {
            this.angle = 45;
          })
        })
    }
  }
}

二、animateTo实现串行动画效果

使用animateTo实现单个动画都没问题,那么如何使用animateTo实现串行动画效果呢?答案就在animateTo的第一个参数AnimateParam里面,AnimateParam是一个接口类型,它里面有一个属性onFinish可以接受一个回调函数用于在动画结束后执行,我们可以用给onFinish传回调函数的方式实现串行动画,示例代码如下:

@Entry
@Component
struct EffectDemo {
  @State
  scaleX: number = 1
  @State
  angle: number = 0
  build() {
    Column(){
      Image($r('app.media.startIcon'))
        .width(200)
        .height(200)
        .scale({x: this.scaleX})
        .rotate({angle: this.angle})
        .onClick(()=>{
          animateTo({
            duration: 10000,
            onFinish: ()=>{
              animateTo({
                duration: 1000,
              }, () => {
                this.angle = 45;
              })
            }
          }, () => {
            this.scaleX = 2;
          })
        })
    }
  }
}