鸿蒙HarmonyOS开发:如何灵活运用动画效果提升用户体验

文章目录

一、动画概述

动画的原理是在一个时间段内,多次改变UI外观,由于人眼会产生视觉暂留,所以最终看到的就是一个"连续"的动画。UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率FPS(Frame Per Second),即每秒的动画帧数,帧率越高则动画就会越流畅。

ArkUI中,产生动画的方式是改变属性值且指定动画参数。动画参数包含了如动画时长、变化规律(即曲线)等参数。当属性值发生变化后,按照动画参数,从原来的状态过渡到新的状态,即形成一个动画。

UI(用户界面)中包含开发者与设备进行交互时所看到的各种组件(如时间、壁纸等)。属性作为接口,用于控制组件的行为。例如,开发者可通过位置属性调整组件在屏幕上的位置。

属性值的变化,通常会引起UI的变化。动画可在UI发生改变时,添加流畅的过渡效果。如果不加入动画,属性将在一瞬间完成变化。造成突兀感的同时,容易导致用户失去视觉焦点。

1、动画的目的
  • 使界面的过渡自然流畅。
  • 增强用户从界面获得的反馈感和互动感。
  • 在内容加载等场景中,增加用户的耐心,缓解等待带来的不适感。
  • 引导用户了解和操作设备。

在需要为UI变化添加过渡的场景,都可以使用动画,如开机、应用启动退出、下拉进入控制中心等。这些动画可向用户提供关于其操作的反馈,并有助于让用户始终关注界面。

二、显式动画 (animateTo)

提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas的内容、linearGradient等,如果要内容跟随宽高变化,可以使用renderFit属性配置。

1、接口
animateTo(value: AnimateParam, event: () => void): void
2、参数
参数 类型 是否必填 描述
value AnimateParam 设置动画效果相关参数。
event () => void 指定动效的闭包函数,在闭包函数中导致的状态变化系统会自动插入过渡动画。
3、AnimateParam对象说明
名称 类型 是否必填 描述
duration number 动画持续时间,单位为毫秒。默认值:1000
tempo number 动画播放速度,值越大动画播放越快,值越小播放越慢,为0时无动画效果。默认值:1
curve Curve 、 ICurve9+ 、 string 动画曲线。默认值:Curve.EaseInOut
delay number 动画延迟播放时间,单位为ms(毫秒),默认不延时播放。默认值:0
iterations number 动画播放次数。默认播放一次,设置为-1时表示无限次播放。设置为0时表示无动画效果。默认值:1
playMode PlayMode 动画播放模式,默认播放完成后重头开始播放。默认值:PlayMode.Normal
onFinish () => void 动画播放完成回调。
4、示例
  • 实现应用欢迎页的动画效果
  • 延迟0.5s自动跳转到首页
  • @Styles装饰器、@Extend装饰器的使用
javascript 复制代码
import router from '@ohos.router'

@Entry
@Component
struct AnimateTo {
  @State isShow: boolean = false
  @State title: string = '快速单词记忆神器'
  @State message: string = "Falling in love with memorizing words"

  onPageShow() {
    animateTo({
      duration: 800,
      onFinish: () => {
        setTimeout(() => {
          router.replaceUrl({
            url: "pages/Index"
          })
        }, 500)
      }
    }, () => {
      this.isShow = true
    })
  }

  build() {
    Column() {
      if (this.isShow) {
        Image($r("app.media.logo"))
          .logoStyle()
          .transition({
            type: TransitionType.Insert,
            opacity: 0,
            translate: { x: -160 }
          })
        Text(this.title)
          .titleStyle()
          .transition({
            type: TransitionType.Insert,
            opacity: 0,
            translate: { x: 160 }
          })
      }
      Blank()
      Text(this.message)
        .footerStyle()
    }
    .bgStyle()
  }
}

@Styles function bgStyle() {
  .width('100%')
  .height('100%')
  .backgroundImage($r('app.media.img_splash_bg'))
  .backgroundImageSize({ width: '100%', height: '100%' })
}

@Extend(Text) function titleStyle() {
  .fontSize(20)
  .fontColor(Color.White)
  .fontWeight(FontWeight.Bold)
  .margin({ top: 30 })
}

@Extend(Image) function logoStyle() {
  .width(90)
  .height(90)
  .margin({ top: 120 })
}

@Extend(Text) function footerStyle() {
  .fontSize(12)
  .fontColor('#546B9D')
  .fontWeight(FontWeight.Bold)
  .margin({ bottom: 30 })
}
5、效果

三、属性动画 (animation)

组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas的内容、linearGradient等,如果要内容跟随宽高变化,可以使用renderFit属性配置。

1、接口
animation(value:AnimateParam)
2、参数
参数 类型 是否必填 描述
value AnimateParam 设置动画效果相关参数。
3、AnimateParam对象说明

同显式动画 (animateTo)

4、系统可动画属性
分类 说明
布局属性 位置、大小、内边距、外边距、对齐方式、权重等。
仿射变换 平移、旋转、缩放、锚点等。
背景 背景颜色、背景模糊等。
内容 文字大小、文字颜色,图片对齐方式、模糊等。
前景 前景颜色等。
Overlay Overlay属性等。
外观 透明度、圆角、边框、阴影等。
4、示例

只对写在animation之前的属性生效,而对写在animation之后的属性无效。

javascript 复制代码
@Entry
@Component
struct AnimationPage {
  @State message: string = 'Hello World'
  @State myWidth: number = 300;
  @State myHeight: number = 200;
  @State flag: boolean = false;
  @State myColor: Color = Color.Blue;
  build() {
    Column({space:20}) {
      Text(this.message)
        .textAlign(TextAlign.Center)
        .fontColor(Color.White)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .width(this.myWidth)
        .height(this.myHeight)
        .backgroundColor(this.myColor)
        .animation({ duration: 1000, curve: Curve.Linear })

      Button("属性动画")
        .fontSize(16)
        .width(200)
        .onClick(() => {
          if (this.flag) {
            this.myWidth = 300;
            this.myHeight = 200;
            this.myColor = Color.Blue;
          } else {
            this.myWidth = 200;
            this.myHeight = 100;
            this.myColor = Color.Pink;
          }
          this.flag = !this.flag;
        })
    }
    .padding(20)
    .width('100%')
    .height('100%')
  }
}
5、效果
相关推荐
Random_index5 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室8 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu710 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
zhangjr057513 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟46419 小时前
初识ArkUI
harmonyos
SameX20 小时前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
郭梧悠21 小时前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
郝晨妤1 天前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙
Peace*1 天前
HarmonyOs鸿蒙开发实战(16)=>沉浸式效果第一种方案一窗口全屏布局方案
harmonyos·鸿蒙·鸿蒙系统
howard20051 天前
鸿蒙实战:页面跳转传参
harmonyos·跳转·router·传参