HarmonyOS Next 属性动画和转场动画

HarmonyOS Next 属性动画和转场动画

在鸿蒙应用开发中,动画是提升用户体验的关键要素。通过巧妙运用动画,我们能让应用界面更加生动、交互更加流畅,从而吸引用户的注意力并增强其使用粘性。鸿蒙系统为开发者提供了丰富且强大的动画开发能力,其中属性动画是整个动画体系的核心基础。接下来,让我们深入探索鸿蒙动画。

鸿蒙动画体系概览

鸿蒙动画体系旨在为开发者打造全方位、多层次的动画创作环境。它不仅包含属性动画这种能够精确控制组件属性变化的基础类型,还拥有转场动画,用于实现界面间的平滑过渡,为用户带来自然且流畅的视觉切换体验。无论是组件的移动、旋转、缩放,还是界面的淡入淡出、滑动切换,鸿蒙动画体系都能轻松应对,助力开发者创建出极具吸引力的应用界面。

属性动画

可动画属性的多样选择

系统预定义可动画属性 :鸿蒙系统贴心地为组件提供了一系列内置的可动画属性接口。例如,position属性能够精准地调整组件在屏幕上的位置,使组件可以在不同坐标间平滑移动;scale属性用于控制组件的缩放比例,让组件能够自如地放大或缩小;opacity属性则决定了组件的透明度,实现淡入淡出等效果;blur属性可赋予组件模糊效果,为界面增添独特的视觉风格。这些系统预定义的可动画属性,极大地简化了开发者创建常见动画效果的过程。

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

自定义可动画属性拓展 :ArkUI 赋予开发者强大的自定义能力,通过@AnimatableExtend装饰器,开发者能够从自定义绘制的内容中抽象出可动画属性。设想在开发一个音乐应用时,需要自定义绘制一个音量图标,并且希望该图标能够根据音量大小动态改变其大小、颜色或形状。借助@AnimatableExtend装饰器,开发者就可以为这个原本不具备默认动画属性的自定义图标添加动画效果,从而满足特定的业务需求和创意设计。

丰富的属性动画接口

animateTo 接口 :该接口主要作用于闭包内改变属性引起的界面变化,尤其在组件出现和消失的转场场景中表现出色。其原理是通过对比闭包前界面和闭包中状态变量引起的界面之间的差异,然后依据设定的动画参数对这些差异进行动画处理。它支持多次调用以及嵌套使用,这为开发者在处理复杂动画逻辑时提供了极大的灵活性。例如,在一个需要让组件同时进行平移、旋转和缩放,并且这些动画都使用相同动画参数的场景中,animateTo就能发挥其优势,简洁高效地实现所需动画效果。

animation 接口animation接口作用于组件通过属性接口绑定的属性变化引起的界面变化。它能够敏锐地识别组件的可动画属性变化,当检测到绑定的可动画属性发生改变时,会自动为这些属性变化添加动画效果。值得注意的是,组件的接口调用遵循从下往上的执行顺序,animation只会作用于在其之上的属性调用。这意味着开发者可以根据组件属性的调用顺序,轻松地对多个属性设置不同的animation效果。比如,在一个组件既要移动又要改变透明度,且移动速度和透明度变化速度不同的场景中,通过animation接口分别为translate属性和opacity属性设置不同的动画参数,就能精准实现所需的动画效果。

代码示例

下面通过一个具体的代码示例,展示如何使用animateTo接口来实现属性动画。

复制代码
@Entry
@Component
@Preview
struct AnimPage {
  @State animate: boolean = false;
  // 第一步: 声明相关状态变量
  @State rotateValue: number = 0; // 组件一旋转角度
  @State translateX: number = 0; // 组件二偏移量
  @State opacityValue: number = 1; // 组件二透明度

  build() {
    Column({ space: 20 }) {
      Row() {
        // 组件一
        Column() {
          Text("123")
        }
        .rotate({ angle: this.rotateValue })
        .backgroundColor('#317AF7')
        .justifyContent(FlexAlign.Center)
        .width(100)
        .height(100)
        .borderRadius(30)
        .onClick(() => {
          this.getUIContext()?.animateTo({ curve: curves.springMotion(), duration: 3500 }, () => {
            this.animate = !this.animate;
            // 第三步:闭包内通过状态变量改变UI界面
            // 这里可以写任何能改变UI的逻辑比如数组添加,显隐控制,系统会检测改变后的UI界面与之前的UI界面的差异,对有差异的部分添加动画
            // 组件一的rotate属性发生变化,所以会给组件一添加rotate旋转动画
            this.rotateValue = this.animate ? 90 : 0;
            // 组件二的透明度发生变化,所以会给组件二添加透明度的动画
            this.opacityValue = this.animate ? 0.6 : 1;
            // 组件二的translate属性发生变化,所以会给组件二添加translate偏移动画
            this.translateX = this.animate ? 50 : 0;
          })
        })

        // 组件二
        Column() {
          Text("456")
        }
        .justifyContent(FlexAlign.Center)
        .width(100)
        .height(100)
        .backgroundColor('#D94838')
        .borderRadius(30)
        .opacity(this.opacityValue)
        .translate({ x: this.translateX })
        .animation({ curve: curves.springMotion(), duration: 3500 })
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
  }
}

在上述代码中,当用户点击Column组件时,animate状态变量会发生改变。依据animate的值,rotateValue(旋转角度)、translateX(偏移量)和opacityValue(透明度)这三个状态变量会相应地改变。由于opacityrotate等属性绑定了animation接口,并且设置了弹簧曲线curves.springMotion(),所以当这些属性值发生变化时,会自动按照弹簧曲线的规律产生动画效果,使组件的旋转、平移和透明度变化呈现出自然的弹簧效果,为用户带来独特而生动的视觉体验。

效果如下:

转场动画

转场动画是指对将要出现或消失的组件做动画,对始终出现的组件做动画应使用属性动画。转场动画主要为了让开发者从繁重的消失节点管理中解放出来,如果用属性动画做组件转场,开发者需要在动画结束回调中删除组件节点。同时,由于动画结束前已经删除的组件节点可能会重新出现,还需要在结束回调中增加对节点状态的判断。

转场效果 说明 动画
IDENTITY 禁用转场效果。 无。
OPACITY 默认的转场效果,透明度转场。 出现时透明度从0到1,消失时透明度从1到0。
SLIDE 滑动转场效果。 出现时从窗口左侧滑入,消失时从窗口右侧滑出。
translate 通过设置组件平移创建转场效果。 出现时为translate接口设置的值到默认值0,消失时为默认值0到translate接口设置的值。
rotate 通过设置组件旋转创建转场效果。 出现时为rotate接口设置的值到默认值0,消失时为默认值0到rotate接口设置的值。
opacity 通过设置透明度参数创建转场效果。 出现时为opacity设置的值到默认透明度1,消失时为默认透明度1到opacity设置的值。
move 通过TransitionEdge创建从窗口哪条边缘出来的效果。 出现时从TransitionEdge方向滑入,消失时滑出到TransitionEdge方向。
asymmetric 通过此方法组合非对称的出现消失转场效果。 - appear:出现转场的效果。 - disappear:消失转场的效果。 出现时采用appear设置的TransitionEffect出现效果,消失时采用disappear设置的TransitionEffect消失效果。
combine 组合其他TransitionEffect。 组合其他TransitionEffect,一起生效。
animation 定义转场效果的动画参数: - 如果不定义会跟随animateTo的动画参数。 - 不支持通过控件的animation接口配置动画参数。 - TransitionEffect中animation的onFinish不生效。 调用顺序时从上往下,上面TransitionEffect的animation也会作用到下面TransitionEffect。

代码示例

typescript 复制代码
@Entry
@Component
@Preview
struct AnimPage {
  @State buttonScale: number = 1;
  @State buttonWidth: number = 100;

  @State showNewBtn: boolean = true

  // 创建默认透明度转场效果,并指定了springMotion(0.6, 0.8)曲线
  private opacityEffect: TransitionEffect = TransitionEffect.OPACITY.animation({ curve: curves.springMotion(0.6, 0.8) })

  // 创建默认平移转场效果, 左进右出
  private slideEffect: TransitionEffect = TransitionEffect.SLIDE.animation({ curve: curves.springMotion(0.6, 0.8) })

  private customEffect: TransitionEffect =
    // 创建默认透明度转场效果,并指定了springMotion(0.6, 0.8)曲线
    TransitionEffect.OPACITY.animation({ curve: curves.springMotion(0.6, 0.8) })
      // 通过combine方法,这里的动画参数会跟随上面的TransitionEffect,也就是springMotion(0.6, 0.8)
      .combine(TransitionEffect.scale({ x: 0, y: 0 }))
        // 添加旋转转场效果,这里的动画参数会跟随上面带animation的TransitionEffect,也就是springMotion(0.6, 0.8)
      .combine(TransitionEffect.rotate({ angle: 90 }))
        // 添加平移转场效果,这里的动画参数使用指定的springMotion()
      .combine(TransitionEffect.translate({ y: 150 }).animation({ curve: curves.springMotion() }))
        // 添加move转场效果,这里的动画参数会跟随上面的TransitionEffect,也就是springMotion()
      .combine(TransitionEffect.move(TransitionEdge.END))

  build() {
    Column({ space: 20 }) {
      Button("开始动画").onClick(() => {
        this.buttonScale = 1.5 / this.buttonScale
        this.buttonWidth = 300 - this.buttonWidth

        this.showNewBtn = !this.showNewBtn
      })
        .width(this.buttonWidth)
        .scale({ x: this.buttonScale, y: this.buttonScale })
        .animation({ curve: curves.springMotion() })

      if (this.showNewBtn) {
        Button("透明显隐(默认)").transition(this.opacityEffect)
      }

      if (this.showNewBtn) {
        Button("左进右出").transition(this.slideEffect)
      }

      if (this.showNewBtn) {
        Button("自定义").transition(this.customEffect)
      }
    }.width('100%')
  }
}

这段代码实现了一个包含按钮动画效果的界面。主要功能如下:

定义了按钮的缩放、宽度和显示状态。

创建了三种动画效果:透明度转场、平移转场和自定义组合转场。

点击"开始动画"按钮时,切换按钮的缩放和宽度,并切换新按钮的显示状态。

根据显示状态,动态展示三个带有不同动画效果的按钮。

运行效果:

通过以上对鸿蒙动画体系的介绍,特别是对属性动画和转场动画代码示例的实操,相信开发者们对鸿蒙动画开发有了更清晰的认识和更深入的理解。在实际开发中,充分利用这些动画特性,将为鸿蒙应用增添无限魅力,提升用户体验到新的高度。

#ArkTS UI

相关推荐
爱笑的眼睛112 天前
HarmonyOS Next 弹窗系列教程(5)
华为·harmonyos·harmonyos next
HarmonyOS小助手3 天前
【鸿蒙生态学堂04】ArkUI开发基础(上)
harmonyos·鸿蒙·harmonyos next·arkui(方舟ui框架)介绍·使用常用组件构建页面·harmonyos 5.0·鸿蒙5·鸿蒙课程·鸿蒙生态
枫叶丹43 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(三十)
华为·harmonyos·deveco studio·harmonyos next
IUings4 天前
【鸿蒙】HarmonyOS NEXT之如何正常加载地图组件
开发语言·华为·harmonyos·harmonyos next·地图服务·map kit
枫叶丹49 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十八) -> 开发云对象
华为·harmonyos·deveco studio·harmonyos next
枫叶丹411 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十七) -> 开发云函数
华为·harmonyos·deveco studio·harmonyos next
HarmonyOS小助手12 天前
鸿蒙版微信小程序不可用,一文告诉你10分钟修复
harmonyos·鸿蒙·harmonyos next
枫叶丹414 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十六) -> 创建端云一体化开发工程
华为·harmonyos·deveco studio·harmonyos next
枫叶丹417 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十五) -> 端云一体化开发 -> 业务介绍(二)
华为·harmonyos·deveco studio·harmonyos next