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

鸿蒙进阶-属性动画

hello大家好啊,这里是鸿蒙开天组,今天我们来学习鸿蒙中的动画属性。

先来说说动画~

属性值的变化,通常会引发 UI 的变化,结合动画可以让这个变化过程【更为流畅】,反之这个过程将在一瞬间完成,用户体验不好,观感突兀。这就是动画的作用:链接

HarmonyOS 中的动画主要分为:

  1. 属性动画
  2. 转场动画
  3. 组件动画

这么三类,一些和动画相关的其他细节咱们接着往下学。

今天咱们主要来学习属性动画。

属性动画-animation

接下来看看如何让咱们的应用动起来

组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。

基本使用

使用动画的核心步骤如下:

  1. 声明相关状态变量
  2. 将状态变量设置到相关可动画属性方法上
  3. 通过属性动画接口开启属性动画(在属性动画上面的属性会应用动画)
  4. 通过状态变量改变UI界面
// 最核心写法,相关动画属性后续展开
组件
  .属性1()
  .属性2()
  // .... animation 必须在需要动画的属性的后面 
  .animation({})

看完了概念,让我们来试一下~

基础模板

@Entry
@Component
struct Page01_animation {
  // 1. 声明相关状态变量
  @State translateY: number = 1
  @State bgColor: ResourceColor = Color.Pink
  @State fontColor: ResourceColor = '#0094ff'
  @State fontWeight: number = 100

  build() {
    Column() {
      Text('C')
        .width(100)
        .height(100)
        .opacity(1)
        .textAlign(TextAlign.Center)
         // 2.将状态变量设置到相关可动画属性接口
        .fontWeight(this.fontWeight)
        .backgroundColor(this.bgColor)
        .translate({ y: this.translateY })
      Button('修改状态变量')
        .onClick(() => {
          // 4. 通过状态变量改变UI界面
          this.bgColor = '#0094ff'
          this.translateY = 100
          this.fontColor = Color.Pink
          this.fontWeight = 900
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.SpaceAround)
  }
}

在上面的模板代码中,我们需要为容器添加动画,也就是给text的变量改变添加一个过渡。

为了方便理解,接下来的参考代码将变量改变的部分进行了函数封装,这样我们就可以得到这样一个结果 :

@Entry
@Component
struct Page01_animation {
  // 1. 声明相关状态变量
  @State translateY: number = 1
  @State bgColor: ResourceColor = Color.Pink
  @State fontColor: ResourceColor = '#0094ff'
  @State fontWeight: number = 100
  @State isOrNot: boolean = false

  onclickEventEnd() {
    // 4. 通过状态变量改变UI界面
    this.bgColor = '#0094ff'
    this.translateY = 100
    this.fontColor = Color.Pink
    this.fontWeight = 900
  }

  onclickEventStart() {
    // 4. 通过状态变量改变UI界面
    this.bgColor = Color.Pink
    this.translateY = 1
    this.fontColor = Color.Pink
    this.fontWeight = 100
  }

  build() {
    Column() {
      Text('C')
        .width(100)
        .height(100)
        .opacity(1)// 2.将状态变量设置到相关可动画属性接口
        .fontWeight(this.fontWeight)
        .backgroundColor(this.bgColor)
        .textAlign(TextAlign.Center)
        .translate({ y: this.translateY })
      // 3.通过属性动画接口开启属性动画
        .animation({})
      Button('修改状态变量')
        .onClick(() => {
          if (this.isOrNot) {
            this.onclickEventStart()
            this.isOrNot = !this.isOrNot
          } else {
            this.onclickEventEnd()
            this.isOrNot = !this.isOrNot
          }
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.SpaceAround)
  }
}

常用属性

可以通过动画参数(以对象的形式传递)来定制动画效果

组件
  .animation({ 动画参数 })

名称

参数类型

必填

描述

duration

number

动画时长,单位为毫秒。

默认值:1000

curve

string | Curve

| ICurve

设置动画曲线。

默认值:Curve.EaseInOut

delay

number

动画延迟播放时间。单位为毫秒,默认不延时播放。

默认值:0

取值范围:(-∞, +∞)

iterations

number

动画播放次数。

默认值:1

取值范围:[-1, +∞)

说明:

设置为-1时表示无限次播放。设置为0时表示无动画效果。

playMode

PlayMode

动画播放模式,默认播放完成后重头开始播放。

默认值:PlayMode.Normal

onFinish

() => void

结束回调,动画播放完成时触发。

从API version 9开始,该接口支持在ArkTS卡片中使用。

动画曲线枚举值:

名称

描述

Linear

表示动画从头到尾的速度都是相同的。

Ease

表示动画以低速开始,然后加快,在结束前变慢,CubicBezier(0.25, 0.1, 0.25, 1.0)。

EaseIn

表示动画以低速开始,CubicBezier(0.42, 0.0, 1.0, 1.0)。

EaseOut

表示动画以低速结束,CubicBezier(0.0, 0.0, 0.58, 1.0)。

EaseInOut

表示动画以低速开始和结束,CubicBezier(0.42, 0.0, 0.58, 1.0)。

FastOutSlowIn

标准曲线,CubicBezier(0.4, 0.0, 0.2, 1.0)。

LinearOutSlowIn

减速曲线,CubicBezier(0.0, 0.0, 0.2, 1.0)。

FastOutLinearIn

加速曲线,CubicBezier(0.4, 0.0, 1.0, 1.0)。

ExtremeDeceleration

急缓曲线,CubicBezier(0.0, 0.0, 0.0, 1.0)。

Sharp

锐利曲线,CubicBezier(0.33, 0.0, 0.67, 1.0)。

Rhythm

节奏曲线,CubicBezier(0.7, 0.0, 0.2, 1.0)。

Smooth

平滑曲线,CubicBezier(0.4, 0.0, 0.4, 1.0)。

Friction

阻尼曲线,CubicBezier(0.2, 0.0, 0.2, 1.0)。

playMode 播放模式枚举值

名称

描述

Normal

动画正向播放。

Reverse

动画反向播放。

Alternate

先正向播放,再反向播放。

AlternateReverse

先反向播放,后正向播放。

非常多的属性值,这里就不逐个尝试啦~有兴趣的可以自己尝试一下。

案例-折扣信息

接下来咱们来写一个小小的案例

需求:

动画效果:

  • 元素大小切换
  • 动画次数无限,元素【加载之后】开启动画

点击按钮触发

咱们先考虑如何实现点击开启动画,元素加载之后涉及到一个还未学习的知识点

核心步骤:有布局,有逻辑

1.布局:用 Text 方便调整实现布局

2.动画:animation

        a.次数无限次

        b.动画线性:匀速

        c.改变的是缩放

                 i.宽高,定义在@State

3.如何触发:

        a.点击触发

模板代码

@Entry
@Component
struct Page02_animationDemo1 {
  build() {
    Column({ space: 50 }) {
      Text('全场低至一分购')
        .fontSize(30)
        .fontWeight(900)
        .fontColor(Color.Red)
        .backgroundColor('#e8b66d')
        .padding(10)
        .borderRadius(20)
    }
    .width('100%')
    .height('100%')
    .padding(20)

  }

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

参考代码

@Entry
@Component
struct Page02_animationDemo1 {
  // 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
        })
        // 3. 通过属性动画接口开启属性动画
        .animation({
          duration: 1000,
          curve: Curve.Ease,
          playMode: PlayMode.Alternate,
          iterations: -1
        })
        .onClick(() => {
          // 4.通过状态变量改变UI界面
          this.scaleX = 1.3
          this.scaleY = 1.3
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)

  }

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

组件加载自动触发事件

如果要实现元素加载的时候就开始动画,可以使用挂载事件来实现,这是一个通用事件

链接

名称

功能描述

onAppear(event: () => void)

组件挂载显示时触发此回调。

从API version 9开始,该接口支持在ArkTS卡片中使用。

onDisAppear(event: () => void)

组件卸载消失时触发此回调。

从API version 9开始,该接口支持在ArkTS卡片中使用。

如何理解软件开发中的事件: 框架提供给开发者,在特定时机注册自定义逻辑的一种机制

接下来进行一个测试~

@Entry
@Component
struct Page03_appearAnddisAppear {
  @State isShow: boolean = false

  build() {
    Column({ space: 50 }) {
      Button('切换显示')
        .onClick(() => {
          this.isShow = !this.isShow
        })

      if (this.isShow) {
        Text('我是文本')
          .width('100%')
          .onAppear(() => {
            console.log('加载了')
          })
          .onDisAppear(() => {
            console.log('卸载了')
          })
      }

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

案例调整后的效果

@Entry
@Component
struct Page04_animationDemo1_event {
  // 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
        })// 3. 通过属性动画接口开启属性动画
        .animation({
          duration: 1000,
          curve: Curve.EaseInOut,
          playMode: PlayMode.Alternate,
          iterations: -1
        })
        .onAppear(() => {
          // 4.通过状态变量改变UI界面
          this.scaleX = 1.3
          this.scaleY = 1.3
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)

  }

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

今天的文章就到这里啦!这里是鸿蒙开天组,感谢大家的关注,咱们下篇文章再见!


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

相关文章:

  • linux系统上SQLPLUS的重“大”发现
  • nvidia docker, nvidia docker2, nvidia container toolkits区别
  • 第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书正式赛题
  • EasyExcel 模板+公式填充
  • StarRocks一次复杂查询引起的Planner超时异常
  • 企业数字化转型中的“烟囱效应”:从小烟囱到大烟囱的折中之道
  • 移远通信亮相骁龙AI PC生态科技日,以领先的5G及Wi-Fi产品革新PC用户体验
  • 【缓存策略】你知道 Cache Aside(缓存旁路)这个缓存策略吗
  • 在JPA和EJB中用乐观锁解决并发问题
  • 前端模拟面试:7个JavaScript数组进阶面试题
  • 为什么go语言使用log.Fatalf打印日志导致程序退出
  • 第二天python笔记
  • 「实战应用」如何用图表控件LightningChart .NET在WPF中制作表格?(二)
  • 如何查看电脑关机时间
  • 《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>
  • Redis7:商户查询缓存1
  • 【Linux-进程信号】信号入门介绍
  • 网络安全CTF竞赛模式、题目类别、所用工具小结
  • 比 PyTorch 更快的嵌入Python库:FastEmbed
  • django入门【05】模型介绍——字段选项(二)
  • 算法——移除元素(leetcode27)
  • el-input 正则表达式校验输入框不能输入汉字
  • 工位管理现代化:Spring Boot企业级框架
  • WPF 应用程序中使用 Prism 框架时,有多种方式可以注册服务和依赖项
  • 最大子数组和
  • vector和docker的区别?