HarmonyOS鸿蒙Next中使用animateTo实现流畅的多属性组合动画?

HarmonyOS鸿蒙Next中使用animateTo实现流畅的多属性组合动画? 我想实现一个点击按钮后,一个圆形组件同时改变大小、颜色和透明度的效果。如果我用if/else控制组件显示,切换会很生硬。有没有一种方法可以让我平滑地控制多个UI属性的变化,并且能精确控制动画的时长、缓动曲线等细节?

3 回复

场景

比如一个音乐播放器的“播放/暂停”按钮, 初始状态(暂停):按钮背景是一个较小的绿色圆形,中间是播放图标。点击后(播放):背景需要平滑地:变大(表示激活状态)。变色(从绿色变为红色)。中间的图标从“播放”变为“暂停”。

实现思路

使用**animateTo** 来实现,animateTo是一个全局的动画执行函数。它的核心思想是:将状态变量的修改过程包裹起来,系统会自动为这些状态变化所引起的UI属性变化生成一个平滑的过渡动画。

实现效果

首次显示如下,当点击时自动旋转动画显示。

cke_2983.png

完整代码

@Entry
@Component
struct Index {
  // 1. 定义控制所有动画状态的“总开关”
  @State isPlaying: boolean = false;
  // 定义旋转角度,用于图标旋转动画
  @State rotationAngle: number = 0;

  build() {
    Column() {
      Text('显式动画 animateTo 演示')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50, bottom: 100 })

      // 2. 构建UI,并将UI属性与状态变量绑定
      Stack() {
        // 背景圆形
        Circle({ width: 100, height: 100 })
          .fill(this.isPlaying ? '#FF4444' : '#44FF44') // 根据状态改变颜色

        // 播放/暂停图标
        Image($r('app.media.foreground')) // 假设你有一个包含播放和暂停图图的媒体资源
          .width(50)
          .height(50)
          .interpolation(ImageInterpolation.High)
            // 使用三元运算符根据状态切换图标显示的源
            // 注意:实际项目中,你可能需要两个独立的图片资源,这里用opacity模拟
          .opacity(this.isPlaying ? 0 : 1) // 简化示例:用透明度模拟图标切换

        Image($r('app.media.foreground'))
          .width(50)
          .height(50)
          .interpolation(ImageInterpolation.High)
          .opacity(this.isPlaying ? 1 : 0)
      }
      .onClick(() => {
        // 3. 在事件处理中,使用 animateTo 包裹状态变更
        animateTo({
          // 动画配置
          duration: 800, // 持续时间800毫秒
          curve: Curve.EaseInOut, // 缓动曲线:先加速后减速
          delay: 0, // 无延迟
          onFinish: () => {
            console.info('动画结束!')
          }
        }, () => {
          // 动画回调:在这里修改状态
          this.isPlaying = !this.isPlaying; // 翻转播放状态
          this.rotationAngle += 180; // 旋转180度
        })
      })
      .rotate({ angle: this.rotationAngle }) // 将旋转角度绑定到Stack组件

      Blank()

      Text(`当前状态: ${this.isPlaying ? '播放中' : '已暂停'}`)
        .fontSize(18)
        .fontColor('#666666')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('#F1F3F5')
  }
}

更多关于HarmonyOS鸿蒙Next中使用animateTo实现流畅的多属性组合动画?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用animateTo实现多属性组合动画,可通过在闭包内同时修改多个组件的状态属性(如位置、大小、透明度)来实现。这些属性变化会自动组合成流畅的动画。开发者需在animateTo的参数中配置动画选项,如时长和曲线。

在HarmonyOS Next中,使用animateTo是实现多属性组合动画的推荐方式。它能将多个状态变化封装进一个动画帧,实现平滑过渡。

核心实现:

  1. 定义状态变量:使用@State装饰器定义控制组件大小、颜色和透明度的变量。
  2. animateTo中更新状态:在按钮的点击事件中,调用animateTo函数,在其闭包内同步更新所有目标状态变量。
  3. 配置动画参数:通过animateTo的第二个参数,可以精确设置动画时长(duration)和缓动曲线(curve)。

示例代码:

// 引入必要模块
import { View, Button, Circle } from '@kit.ArkUI';
import { animateTo, Easing } from '@kit.ArkUI';

@Entry
@Component
struct AnimateExample {
  // 1. 定义状态变量
  @State size: number = 100; // 初始大小
  @State color: Color = Color.Blue; // 初始颜色
  @State opacityValue: number = 1.0; // 初始透明度

  build() {
    Column() {
      // 2. 应用状态的圆形组件
      Circle({
        width: this.size,
        height: this.size
      })
        .fill(this.color)
        .opacity(this.opacityValue)

      // 3. 触发动画的按钮
      Button('点击动画')
        .onClick(() => {
          // 使用animateTo组合动画
          animateTo({
            duration: 1000, // 动画时长1000ms
            curve: Easing.InOut // 缓动曲线:先加速后减速
          }, () => {
            // 在闭包内同步更新所有属性
            this.size = this.size === 100 ? 200 : 100; // 切换大小
            this.color = this.color === Color.Blue ? Color.Red : Color.Blue; // 切换颜色
            this.opacityValue = this.opacityValue === 1.0 ? 0.5 : 1.0; // 切换透明度
          })
        })
    }
  }
}

关键点说明:

  • 流畅性animateTo会将闭包内所有状态变化识别为同一动画帧,系统自动计算中间值并逐帧渲染,因此多个属性的变化是同步且平滑的,避免了if/else切换的生硬感。
  • 参数控制
    • duration:动画总时长,单位毫秒。
    • curve:缓动曲线,如Easing.Linear(线性)、Easing.In(加速)、Easing.Out(减速)、Easing.InOut(先加速后减速)等,用于控制动画的速度变化。
  • 性能animateTo通过声明式UI的响应式变化驱动动画,系统会进行优化,确保动画性能。

此方法适用于需要对布局属性(宽高、位置)、渲染属性(颜色、透明度、边框等)进行同步动画的场景。

回到顶部