当前位置: 首页 > article >正文

鸿蒙进阶篇-属性动画-animateTo转场动画

大家好啊,这里是鸿蒙开天组,今天我们来学习属性动画-animateTo&转场动画,咱们先来学习属性动画-animateTo

属性动画-animateTo

属性动画 animation是作为属性使用,而animateTo显示动画是一个系统的内置函数,可以直接调用。功能上和 animation一致,适合于给多个元素应用同一套动画的场景

核心用法

和 animation 的核心用法步骤类似,第三步的语法需要调整

  1. 声明相关状态变量
  2. 将状态变量设置到相关可动画属性接口
  3. 通过属性动画接口开启属性动画(在属性动画上面的属性会应用动画)
  4. 通过状态变量改变UI界面
// 参数 1 动画选项 和 animation 相同
// 参数 2 箭头函数,状态变量的修改写在里面
animateTo({}, () => {
  // 第 4 步写到这里
})

来试一下

  1. 基于基础模版给页面中的尺寸添加旋转动画
  2. 思考如果用 animation 需要如何编码?

这里给出基础模板

@Entry
@Component
struct Page06_animateTo {
  // 1. 声明相关状态变量
  @State rotateAngle: number = 0

  build() {
    Column() {
      // 4个齿轮
      Flex({ wrap: FlexWrap.Wrap }) {
        Image($r('app.media.ic_gear1'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear2'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear3'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear4'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
      }

      Button('点击旋转齿轮')
        .onClick(() => {

        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Orange)
  }
}

tips:

绝大多数情况下 animation 和 animateTo可以互相替代,当多个元素应用同一个动画时,用 animateTo 会更为适合

来揭晓参考答案吧~

@Entry
@Component
struct Page06_animateTo {
  // 1. 声明相关状态变量
  @State rotateAngle: number = 0

  build() {
    Column() {
      // 4个齿轮
      Flex({ wrap: FlexWrap.Wrap }) {
        Image($r('app.media.ic_gear1'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear2'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear3'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
        Image($r('app.media.ic_gear4'))
          .width(150)// 2. 将状态变量设置到相关可动画属性接口
          .rotate({ angle: this.rotateAngle })
      }

      Button('点击旋转齿轮')
        .onClick(() => {
          // 3. 通过属性动画接口开启属性动画(在属性动画上面的属性会应用动画)
          animateTo({ iterations: -1, curve: Curve.Linear }, () => {
            // 4. 通过状态变量改变UI界面
            this.rotateAngle = 360
          })
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Orange)
  }
}

案例-折扣信息

还是之前的那个折扣信息案例,咱们通过 animateTo 来实现一次,来看看是否可以用 animateTo 一样的效果

需求:

  1. 将原模版中的 animation 替换为 animateTo

核心步骤:

  1. 将 animation 设置的动画属性,通过 animateTo 设置
  2. 调整状态变量的代码写到 animateTo 的回调函数中即可

基础代码前面的文章中已经给出,这里直接提供实现后的代码

@Entry
@Component
struct Page07_animateToDemo {
  // 1. 声明相关状态变量
  @State scaleX: number = 1
  @State scaleY: number = 1

  build() {
    Column({ space: 50 }) {
      Text('全场低至一分购')
        .fontSize(30)
        .fontWeight(900)
        .fontColor(Color.Red)
        .backgroundColor('#e8b66d')
        .padding(10)
        .borderRadius(20)// 2.将状态变量设置到相关可动画属性接口
        .scale({
          x: this.scaleX,
          y: this.scaleY
        })
        .onAppear(() => {
          // 3. 通过属性动画接口开启属性动画
          animateTo({
            duration: 1000,
            curve: Curve.EaseInOut,
            playMode: PlayMode.Alternate,
            iterations: -1
          }, () => {
            // 4.通过状态变量改变UI界面
            this.scaleX = 1.3
            this.scaleY = 1.3
          })

        })
    }
    .width('100%')
    .height('100%')
    .padding(20)

  }

  @Styles
  fullSize() {
    .width('100%')
    .height('100%')
  }
}

转场动画

转场动画是指对将要出现或消失的组件做动画,对始终出现的组件做动画应使用属性动画。

转场动画主要有如下分类:

  1. 出现/消失转场
  2. 导航转场(和路由相关-路由阶段讲解)
  3. 模态转场(全模态、半模态弹框,还有一些其他的弹出菜单-链接)
  4. 共享元素转场(和路由相关-路由阶段讲解)

出现消失转场-核心用法

比如点击关闭广告,添加或者删除元素。核心就是元素需要出现或者消失,都可以使用转场动画来添加过渡效果

核心步骤:

  1. 创建TransitionEffect
  2. 将转场效果通过transition接口设置到组件
  3. 新增或者删除组件触发转场
@State isPresent: boolean = true;
...
if (this.isPresent) {
  Text('test')
    .transition(effect)
}
...
// 控制新增或者删除组件
// 方式一:将控制变量放到animateTo闭包内,未通过animation接口定义动画参数的TransitionEffect将跟随animateTo的动画参数
animateTo({ curve: curves.springMotion() }, () => {
  this.isPresent = false;
})

// 方式二:直接控制删除或者新增组件,动画参数由TransitionEffect的animation接口配置
this.isPresent = false;

出现消失转场-转场效果

转场效果可以通过下列语法随意进行设置,支持通过点语法链式调用

// 设置多个效果 出现和消失均有转场
effect: object = TransitionEffect
    .OPACITY.animation({})
    .combine(TransitionEffect.scale({ x: 0, y: 0 }))// 组合 缩放效果
    .combine(TransitionEffect.rotate({ angle: 90 })) // 组合 旋转效果
    .combine(TransitionEffect.move(TransitionEdge.END)) // 组合 移动效果

// 出现没有转场
// 消失透明度转场
effect2: object = TransitionEffect.asymmetric(
  TransitionEffect.IDENTITY, // 出现转场
  TransitionEffect.OPACITY.animation({ // 消失转场
    duration: 300
  }))

静态方法:

接口名称

参数类型

是否静态函数

参数描述

opacity

number

设置组件转场时的透明度效果,为插入时起点和删除时终点的值。
取值范围: [0, 1]

translate

TranslateOptions

设置组件转场时的平移效果,为插入时起点和删除时终点的值。

scale

ScaleOptions

设置组件转场时的缩放效果,为插入时起点和删除时终点的值。

rotate

RotateOptions

设置组件转场时的旋转效果,为插入时起点和删除时终点的值。

move

TransitionEdge

指定组件转场时从屏幕边缘滑入和滑出的效果,本质为平移效果,为插入时起点和删除时终点的值。
从API version 10开始,该接口支持在ArkTS卡片中使用。

asymmetric

appear: TransitionEffect

,
disappear: TransitionEffect

指定非对称的转场效果。
第一个参数指定出现的转场效果,第二个参数指定消失的转场效果。
如不通过asymmetric函数构造TransitionEffect,则表明该效果在组件出现和消失时均生效。

combine

TransitionEffect

对TransitionEffect进行链式组合,以形成包含多种转场效果的TransitionEffect。

animation

AnimateParam

指定该TransitionEffect的动画参数。
该参数只用来指定动画参数,其入参AnimateParam的onFinish回调不生效。

静态成员:

静态成员名称

参数描述

IDENTITY

禁用转场效果。

OPACITY

指定透明度为0的转场效果。即相当于TransitionEffect.opacity(0)

SLIDE

指定出现时从左侧滑入、消失时从右侧滑出的转场效果。即相当于TransitionEffect.asymmetric(TransitionEffect.move(TransitionEdge.START), TransitionEffect.move(TransitionEdge.END))

SLIDE_SWITCH

指定出现时从右先缩小再放大侧滑入、消失时从左侧先缩小再放大滑出的转场效果。动画时长600ms,指定动画曲线曲线cubicBezierCurve(0.24f, 0.0f, 0.50f, 1.0f),最小缩放比例为0.8。

如果要组合多个动画效果,可以用如下的方式进行设置,之所以可以一路点下去,是因为这些设置动画的语法,设置之后返回的都是 TransitionEffect,所以继续链式调用

参考代码

@Entry
@Component
struct Page09_transitionEffect {
  @State isShow: boolean = false
  //  1. 定义转场效果
  effect: object = TransitionEffect
    .OPACITY.animation({})
    .combine(TransitionEffect.scale({ x: 0, y: 0 }))
    .combine(TransitionEffect.rotate({ angle: 90 }))
    .combine(TransitionEffect.move(TransitionEdge.END))

  build() {
    Column() {
      Button('切换元素')
        .onClick(() => {
          this.isShow = !this.isShow
        })
      // 3. 新增或者删除组件触发转场
      if (this.isShow) {
        Text('我是文本框')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)// 2. 添加转场效果
          .transition(this.effect)
      }
      // 我是底部的元素(
      // 元素是瞬间消失或出现的,所以这个输入框会瞬间上去或下去
      // 因为通过动画的方式让这一过程更为平滑,所以会出现 Text 上去了,但是消失、出现的动画还在播放
      // 如果要视觉效果更为美观,可以通过布局的方式让元素的出现或消失不影响布局
      Text('底部的文本框')
        .fontSize(40)


    }
    .width('100%')
    .height('100%')
  }
}

最后再给大家扩展一个帧动画

ImageAnimator 帧动画组件

供逐帧播放图片的能力,可以方便的控制播放状态:播放,暂停,停止..

核心用法:

ImageAnimator不是容器组件,也不需要传递参数,只需要设置属性即可

ImageAnimator()
  .属性()

用例

@Entry
@Component
struct Page12_ImageAnimator {
  // 需要动画的图片
  // 两套动画素材
  // ic_animator_coin1(1-6 硬币)
  // ic_animator_dog1(1-4 狗狗)
  images: ImageFrameInfo[] = [
    { src: $r('app.media.ic_animator_dog1') },
    { src: $r('app.media.ic_animator_dog2') },
    { src: $r('app.media.ic_animator_dog3') },
    { src: $r('app.media.ic_animator_dog4') },
  ]
  // 需要控制动画状态 定义状态变量 默认状态
  @State aniStatus: AnimationStatus = AnimationStatus.Initial

  build() {
    Column({ space: 10 }) {
      // 动画组件
      ImageAnimator()
        .animatorFancy()
        .iterations(-1)// 动画次数
        .duration(400)// 持续时间
        .height(150)
        .images(this.images)// 动画图片
        .state(this.aniStatus) // 动画抓个状态

      // 按钮控制区域
      Row({ space: 20 }) {
        Button('启动')
          .onClick(() => {
            this.aniStatus = AnimationStatus.Running // 播放
          })
        Button('暂停')
          .onClick(() => {
            this.aniStatus = AnimationStatus.Paused // 暂停:停在触发的瞬间
          })
        Button('停止')
          .onClick(() => {
            this.aniStatus = AnimationStatus.Stopped // 停止:直接到最后一张图
          })
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)

  }

  // 抽取的通用属性
  @Styles
  animatorFancy() {
    .width(300)
    .backgroundColor(Color.Gray)
    .padding(10)
    .borderRadius(10)
  }
}

参数名称

参数类型

参数描述

images

Array<ImageFrameInfo>

设置图片帧信息集合。
说明:
不支持动态更新。

state

AnimationStatus

默认为初始状态,用于控制播放状态。

duration

number

单位为毫秒,默认时长为1000ms;duration为0时,不播放图片;值的改变只会在下一次循环开始时生效;当images中任意一帧图片设置了单独的duration后,该属性设置无效。
默认值:1000
从API version 10开始,该接口支持在ArkTS卡片中使用。

iterations

number

默认播放一次,设置为-1时表示无限次播放。
默认值:1

。。。。

好啦,今天的内容就到这里了,这里是鸿蒙开天组~喜欢的话可以点点收藏!感谢大家~


http://www.kler.cn/a/393015.html

相关文章:

  • 数字孪生在智慧能源项目中的关键作用,你了解多少?
  • UDP协议和TCP协议之间有什么具体区别?
  • Nuxt 版本 2 和 版本 3 的区别
  • MacOS 本地生成SSH key并关联Github
  • 虚拟机安装Ubuntu 24.04服务器版(命令行版)
  • python: postgreSQL using psycopg2 or psycopg
  • K8S实现反向代理,负载均衡
  • java实际开发中,navicat连接Linux下的mysql服务
  • 数据结构小项目
  • 数据结构---详解栈
  • 「QT」几何数据类 之 QSize 尺寸类
  • 比ChatGPT更酷的AI工具
  • NVT新能德科技入职测评SHL题库更新:数字推理+演绎推理高分答案、真题解析
  • Pycharm PyQt5 环境搭建创建第一个Hello程序
  • AndroidStudio-滚动视图ScrollView
  • 光驱验证 MD5 校验和
  • Docker解决暴露2375端口引发的安全漏洞
  • 11.12 机器学习-特征工程
  • 工作和学习遇到的技术问题
  • OBOO鸥柏:旗下户外景区自助触摸查询一体机已布局智慧城市便民
  • 汇编分析C++class
  • 【征稿倒计时!华南理工大学主办 | IEEE出版 | EI检索稳定】2024智能机器人与自动控制国际学术会议 (IRAC 2024)
  • LabVIEW大数据处理
  • 网络学习第四篇
  • matlab建模入门指导
  • 【C++】用红黑树封装set和map