鸿蒙(HarmonyOS)开发中属性动画深度解析

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、属性动画核心概念

1. 功能定位
  • 作用:通过平滑过渡改变组件的样式属性(如宽高、透明度、位置等)。
  • 与显式动画区别
    特性属性动画显式动画(animateTo)
    控制粒度精确到单个属性变化整体组件变化
    性能更高(底层属性驱动)依赖UI线程重绘
    适用场景复杂属性联动、精准控制简单过渡效果
2. 动画属性支持
属性类型示例备注
布局属性width, height, margin需启用动画过渡(animationMode)
外观属性opacity, backgroundColor颜色需用RGB或字符串格式
变换属性scale, rotate, translate支持3D变换(API 12+)

二、基础使用与常用API

1. 创建属性动画
import curves from '@ohos.curves';
import { Animator, AnimatorOptions } from '@ohos.animator';

// 定义动画参数
const options: AnimatorOptions = {
  duration: 1000, // 动画时长(ms)
  curve: curves.springMotion() // 弹性曲线(API 12+)
};

// 创建动画实例
const animator = new Animator(options);

// 绑定组件属性
animator.on('frame', (fraction: number) => {
  this.angle = fraction * 360; // 0~1映射到0~360度
});

// 启动动画
animator.start();

关键API

  • new Animator(options):创建动画控制器。
  • on('frame', callback):逐帧回调,fraction为0~1的进度值。
  • start()/stop()/pause():控制动画生命周期。
2. 直接驱动组件属性
// 旋转动画示例
@State angle: number = 0;

Button('旋转按钮')
  .rotate({ angle: this.angle })
  .onClick(() => {
    const animator = new Animator({ duration: 1000 });
    animator.on('frame', (fraction) => {
      this.angle = fraction * 180; // 0~180度旋转
    });
    animator.start();
  })

三、高级功能详解

1. 多属性联动动画
// 同时改变宽高和透明度
@State scale: number = 1;
@State alpha: number = 1;

Animator.runAnimator({
  duration: 800,
  onFrame: (fraction) => {
    this.scale = 1 + fraction * 0.5; // 放大1.5倍
    this.alpha = 1 - fraction * 0.5; // 透明度减半
  }
})

// 组件绑定
Image($r('app.media.logo'))
  .scale({ x: this.scale, y: this.scale })
  .opacity(this.alpha)

 2. 路径动画(API 12+)

import { PathAnimator } from '@ohos.animator';

// 定义贝塞尔曲线路径
const path = new Path();
path.moveTo(0, 0);
path.bezierCurveTo(100, 50, 200, -50, 300, 0);

// 沿路径移动
const pathAnimator = new PathAnimator({
  path: path,
  duration: 2000
});
pathAnimator.on('frame', (point) => {
  this.posX = point.x; // 更新X坐标
  this.posY = point.y; // 更新Y坐标
});
pathAnimator.start();

3. 动画曲线与缓动函数

import curves from '@ohos.curves';

// 使用内置曲线
const options = {
  curve: curves.cubicBezier(0.1, 0.8, 0.2, 1) // 自定义贝塞尔曲线
};

// 或使用预设曲线
const presetCurves = {
  linear: curves.linear,
  easeIn: curves.easeIn,
  spring: curves.springMotion(0.5, 100) // 弹性动画(刚度、质量)
};

四、案例:下拉刷新动画 

@Entry
@Component
struct RefreshExample {
  @State rotateAngle: number = 0;
  @State pullDistance: number = 0;
  private refreshAnimator: Animator | null = null;

  // 下拉时同步更新距离和旋转
  handlePull(dy: number) {
    this.pullDistance = Math.min(dy, 100);
    this.rotateAngle = (dy / 100) * 360;
  }

  // 释放时执行弹性动画
  handleRelease() {
    this.refreshAnimator = new Animator({
      duration: 1000,
      curve: curves.springMotion()
    });
    this.refreshAnimator.on('frame', (fraction) => {
      this.pullDistance = 100 * (1 - fraction); // 回弹到顶部
    });
    this.refreshAnimator.start();
  }

  build() {
    Column() {
      Image($r('app.media.arrow'))
        .rotate({ angle: this.rotateAngle })
        .margin({ top: this.pullDistance })

      List() {
        // 列表内容...
      }
      .onTouch((event) => {
        if (event.type === TouchType.Move) {
          this.handlePull(event.offsetY);
        } else if (event.type === TouchType.Up) {
          this.handleRelease();
        }
      })
    }
  }
}

五、调试与性能优化

1. 动画监控工具
// 打印动画帧率
animator.on('frame', (fraction) => {
  console.log(`Frame: ${Date.now()}, Progress: ${fraction}`);
});
2. 性能优化建议
场景优化方案
复杂动画使用Animator替代animateTo
多组件动画合并属性更新减少渲染次数
页面跳转时调用animator.stop()释放资源

六、总结对比

功能API/方法适用场景
基础属性动画Animator + on('frame')单个属性精细控制
路径动画PathAnimator(API 12+)复杂运动轨迹
物理动画curves.springMotion()弹性、惯性效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值