鴻蒙(HarmonyOS)提供了豐富的動畫能力,涵蓋屬性動畫、顯式動畫、轉場動畫、幀動畫等多種類型,適用于不同場景的交互需求。以下是鴻蒙中各類動畫的詳細解析及使用示例:
1. 屬性動畫(Property Animation)
作用:通過改變組件的屬性(如寬高、透明度、旋轉角度等)實現平滑過渡效果。
核心接口:animateTo
、animation
、keyframeAnimateTo
特點:系統自動插值計算中間幀,性能優化較好。
示例代碼:
// 使用 animateTo 實現縮放動畫
Button('點擊放大').onClick(() => {animateTo({ duration: 1000, curve: Curve.Ease }, () => {this.scaleValue = this.scaleValue === 1 ? 1.5 : 1;});}).scale({ x: this.scaleValue, y: this.scaleValue })
關鍵點:
animateTo
:顯式觸發動畫閉包內的屬性變化。animation
修飾符:自動響應狀態變化(無需閉包)。- 曲線類型:如
Curve.Ease
(緩入緩出)、Curve.Spring
(彈性效果)。
2. 顯式動畫(Explicit Animation)
作用:通過animateToImmediately
立即下發動畫指令,減少延遲。
適用場景:需要優先渲染部分動畫時(如高優先級交互反饋)。
示例代碼:
animateToImmediately({ duration: 500 }, () => {this.translateX = 100; // 立即執行位移動畫
});
3. 轉場動畫(Transition Animation)
作用:處理組件出現/消失時的過渡效果,如頁面跳轉、彈窗彈出。
類型:
- 基礎轉場:
TransitionEffect.opacity
(淡入淡出)、TransitionEffect.slide
(滑動)。 - 高級模板:導航轉場、模態轉場、共享元素轉場(一鏡到底)。
示例代碼:
// 共享元素轉場(一鏡到底)
Image($r('app.media.thumbnail')).sharedTransition('imageTransition', { duration: 1000 })// 頁面轉場
pageTransition() {PageTransitionEnter({ duration: 300 }).slide(SlideEffect.Right);PageTransitionExit({ duration: 300 }).opacity(0);
}
4. 幀動畫(Frame Animation)
作用:逐幀控制屬性變化,適合復雜自定義動畫。
核心接口:@ohos.animator
特點:靈活但性能開銷較大,需手動管理幀回調。
示例代碼:
const options = { duration: 2000, begin: 0, end: 100 };
const animator = this.getUIContext().createAnimator(options);
animator.onFrame = (value) => { this.progress = value; };
animator.play();
5. 粒子動畫(Particle Animation)
作用:通過大量粒子運動營造氛圍(如雪花、火焰)。
組件:Particle
配置參數:粒子大小、顏色、速度、生命周期等。
示例代碼:
Particle({particles: [{emitter: { particle: { type: ParticleType.POINT, radius: 5 } },color: { range: ['#FF0000', '#FFFF00'] }}]
}).width(200).height(200)
6. 路徑動畫(Motion Path)
作用:讓組件沿指定路徑運動。
接口:motionPath
路徑定義:支持 SVG 路徑字符串或關鍵點坐標。
示例代碼:
Image($r('app.media.rocket')).motionPath({ path: 'M 0 0 L 100 100', rotate: 'auto' })
7. 動畫性能優化
- 減少布局屬性動畫:優先使用
scale
/translate
替代width
/height
,避免觸發重新布局。 - 合并動畫閉包:多個屬性變化盡量合并到同一個
animateTo
中。 - 使用
renderGroup
:對復雜動效組件啟用緩存。 - 避免后臺動畫:應用切后臺時暫停動畫。
8. 常見問題
- 動畫不生效:檢查屬性是否支持動畫(如
zIndex
不可動畫)。 - 丟幀問題:簡化動畫復雜度,或使用
expectedFrameRateRange
限制幀率范圍。 - 手勢與動畫銜接:通過
responsiveSpringMotion
繼承手勢速度,實現自然過渡。
綜合示例
@Entry@Componentstruct ComplexAnimationDemo {@State rotate: number = 0;@State isVisible: boolean = false;build() {Column() {// 屬性動畫 + 轉場if (this.isVisible) {Text("Hello HarmonyOS").transition(TransitionEffect.rotate({ angle: 360 }).animation({ duration: 1000 }))}// 顯式動畫 + 路徑Button("觸發動畫").onClick(() => {this.isVisible = !this.isVisible;animateTo({ duration: 1500 }, () => {this.rotate = 180;});}).motionPath({ path: 'M 0 0 Q 50 100 100 0' })}}}
總結
鴻蒙的動畫體系覆蓋了從簡單屬性變化到復雜場景動效的全場景需求,開發者應根據交互目標選擇合適的動畫類型,并遵循性能優化原則。具體場景可參考官方文檔中的動畫實踐案例。