DEV Community

魔眼天王
魔眼天王

Posted on

Comprehensive Guide to Animation Development in HarmonyOS ArkTS

I. Animation System Classification

1. Property Animation

​Core Mechanism: Achieves transitional effects by modifying animatable component properties (position/size/opacity)
​Key APIs: animation() decorator, animateTo() method
​Typical Implementation:

// Button scaling animation
Button("Click")
  .scale({ x: this.scaleVal, y: this.scaleVal })
  .animation({ curve: Curve.EaseInOut })
  .onClick(() => {
    animateTo({ duration: 300 }, () => {
      this.scaleVal = this.scaleVal === 1.2 ? 1 : 1.2
    })
  })
Enter fullscreen mode Exit fullscreen mode

2. Transition Animation

​Application Level: Transition effects during component/page visibility changes
​Implementation: Configured via transition property
​Recommended Types: Slide/Fade/Scale animations

3. Component Animation

​Subtypes:

  • Loading Animation: LoadingProgress component

  • Layout Animation: LayoutAnimation container

  • Spring Animation: Spring-curve based effects

4. Frame Animation

​Implementation Principle: Frame-by-frame property control via @ohos.animator
​Use Cases: Complex path animations/game effects

II. Implementation Scenarios

Scenario 1: Interactive Feedback Enhancement

​Implementation:

// Hover feedback animation
Column() {
  @State isHovered = false
  Box()
    .width(100)
    .height(100)
    .onHover((state) => isHovered = state)
    .animateTo(
      { duration: 200, curve: Curve.Spring },
      () => { this.isHovered ? this.scale = 1.1 : this.scale = 1 }
    )
}
Enter fullscreen mode Exit fullscreen mode

​Advantage: Enhances user operation confirmation

Scenario 2: Page Navigation Transition

​Implementation:

// Page transition animation
router.pushUrl({
  url: "pages/detail",
  transition: {
    type: "slide",
    duration: 400,
    direction: "left"
  }
})
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Data Loading Feedback

​Implementation:

// Loading spinner
LoadingProgress()
  .type(LoadingType.Spin)
  .color("#4A90E2")
  .size(50)
Enter fullscreen mode Exit fullscreen mode

Scenario 4: List Item Dynamics

​Implementation:

List() {
  ForEach(listData, (item) => {
    ListItem()
      .animateTo(
        { duration: 200, curve: Curve.EaseOut },
        () => { this.listData.indexOf(item) === 0 }
      )
  })
}
Enter fullscreen mode Exit fullscreen mode

Scenario 5: Complex Path Animation

​Implementation:

// Bezier curve animation
animateTo({
  duration: 1000,
  curve: Curve.Bezier(0.25, 0.1, 0.25, 1)
}, () => {
  this.ballPos = { x: 300, y: 500 }
})
Enter fullscreen mode Exit fullscreen mode

Scenario 6: Particle Effects

​Implementation:

// Snowfall effect
ParticleSystem {
  emitter: PointEmitter {
    position: { x: 0, y: -100 }
    speed: 0.2
    lifespan: 3000
  }
  texture: $r("app.media.snowflake")
}
Enter fullscreen mode Exit fullscreen mode

III. Comparative Analysis

Animation Type Advantages Limitations Best Use Cases
Property Animation Simple development, good performance optimization Limited complex path support Basic UI animations
Transition Animation System-level smooth transitions Fixed animation types Page transitions
Component Animation High reusability Relies on presets List/form interactions
Frame Animation Fully customizable High memory consumption Game/special effects

IV. Performance Optimization

  1. ​Hierarchy Control: ≤3 nested animation layers

  2. ​Hardware Acceleration: animation({ timing: "hardware" })

  3. ​Object Reuse: Pre-instantiate animation components

  4. ​Frame Rate Monitoring: PerformanceMonitor component

  5. ​Resource Compression: Textures ≤1024x1024px

V. Case Study: Parallax Cart Animation

@Entry
@Component
struct CartAnimation {
  @State ballPos = { x: 0, y: 0 }

  build() {
    Column() {
      Button("Add to Cart")
        .onClick(() => this.startAnimation())

      Image($r("app.media.cart"))
        .position(this.ballPos)
    }
  }

  startAnimation() {
    animateTo(
      { duration: 800, curve: Curve.Spring },
      () => this.ballPos = { x: 150, y: 300 },
      () => animateTo(
        { duration: 500, curve: Curve.EaseOut },
        () => this.ballPos = { x: 0, y: 0 }
      )
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

VI. Best Practices

  1. ​Motion Consistency: Maintain 60FPS through hardware acceleration

  2. ​Easing Curves: Use system-defined curves for natural motion

  3. ​State Management: Synchronize animations with component state

  4. ​Memory Management: Dispose unused animations promptly

  5. ​Accessibility: Ensure animations respect reduced motion preferences

Top comments (0)