Skip to content

动画性能

鸿蒙动画性能:硬件加速、属性动画、动画性能优化。


1. 动画类型

类型说明性能适用场景
属性动画通过属性变化产生动画⚡⚡⚡ 最佳位移、缩放、透明度
帧动画逐帧播放图片⚡⚡ 中等复杂动画、特效
路径动画沿路径移动⚡⚡ 中等轨迹动画

2. 属性动画

2.1 基础动画

typescript
// ✅ 推荐:属性动画(硬件加速)
@Entry
@Component
struct AnimatedView {
    @State scale: number = 1.0
    @State opacity: number = 1.0
    @State rotation: number = 0

    build() {
        Column() {
            Text('Animated View')
                .animation({
                    duration: 500,
                    curve: Curve.EaseInOut,
                    fillMode: FillMode.Forwards  // 动画结束后保持状态
                })
                .scale({ x: this.scale, y: this.scale, z: this.scale })
                .opacity(this.opacity)
                .rotate({ x: 0, y: 0, z: 0, angle: this.rotation })
        }
    }

    onClick() {
        this.scale = 1.2
        this.opacity = 0.5
        this.rotation = 180
    }
}

2.2 插值器(Curve)

typescript
// 插值器类型
enum Curve {
    Linear,       // 匀速
    Ease,         // 缓入缓出(推荐)
    EaseIn,       // 慢入
    EaseOut,      // 慢出
    EaseInOut,    // 慢入慢出(最常用)
    Bounce        // 弹跳
}

// 使用插值器
Text('Animated View')
    .animation({
        duration: 500,
        curve: Curve.EaseInOut,  // 缓入缓出,更自然
        fillMode: FillMode.Forwards
    })

3. 动画性能优化

3.1 避免触发布局

typescript
// ❌ 错误:触发布局的动画属性
Text('Bad Animation')
    .animation({ duration: 200 })
    .width('50%')  // 触发布局 → 性能差
    .height(100)   // 触发布局 → 性能差
    .fontColor(Color.Red)  // 触发布局 → 性能差

// ✅ 正确:不触发布局的动画属性
Text('Good Animation')
    .animation({ duration: 200 })
    .scale(1.2)           // 不触发布局 ⭐
    .opacity(0.5)         // 不触发布局 ⭐
    .translate({ x: 50, y: 0 })  // 不触发布局 ⭐
    .rotate({ angle: 45 })  // 不触发布局 ⭐

3.2 动画性能检查清单

✅ 推荐:
├─ 使用 scale/opacity/translate/rotate(GPU 加速)
├─ 设置合理的 duration(200-500ms)
├─ 使用插值器让动画更自然
├─ 动画结束后清除动画(fillMode)
└─ 避免同时动画多个组件

❌ 避免:
├─ 动画 width/height/fontColor(触发布局)
├─ 动画时间过短(< 100ms)导致卡顿
├─ 动画时间过长(> 1000ms)导致不流畅
└─ 同时动画大量组件

4. 动画组合

4.1 顺序动画

typescript
@Entry
@Component
struct SequenceAnimation {
    @State step: number = 0

    build() {
        Column() {
            Text(`Step: ${this.step}`)
                .animation({
                    duration: 300,
                    curve: Curve.EaseInOut,
                    iterations: 1
                })
                .translate({ x: this.step * 100, y: 0 })
                .animation({
                    duration: 300,
                    curve: Curve.EaseInOut,
                    fillMode: FillMode.Forwards
                })
                .opacity(this.step >= 1 ? 0.5 : 1.0)
                .animation({
                    duration: 300,
                    curve: Curve.EaseInOut,
                    fillMode: FillMode.Forwards
                })
                .scale(this.step >= 2 ? 1.5 : 1.0)

            Button('Start Sequence')
                .onClick(() => this.startSequence())
        }
    }

    private async startSequence(): Promise<void> {
        this.step = 1
        await new Promise(r => setTimeout(r, 300))
        this.step = 2
        await new Promise(r => setTimeout(r, 300))
        this.step = 3
    }
}

4.2 并行动画

typescript
// 并行动画:同时触发
Text('Parallel Animation')
    .animation({ duration: 300, curve: Curve.EaseInOut })
    .scale(1.2)
    .opacity(0.5)
    .translate({ x: 50, y: 50 })
    .rotate({ angle: 45 })
// 四个属性动画同时触发(300ms 完成)

5. 面试高频考点

Q1: 动画性能优化的核心?

回答:只使用 scale/opacity/translate/rotate(GPU 加速),避免 width/height/fontColor(触发布局)。

Q2: 动画插值器的作用?

回答:控制动画速度曲线,让动画更自然。常用 EaseInOut,动画慢入慢出。


🐱 小猫提示:动画性能记住 "scale/opacity/translate/rotate GPU 加速、不用 width/height、插值器 EaseInOut、200-500ms"