HarmonyOS:動(dòng)畫(huà) motionPath 、 animateToImmediately API自學(xué)指南

在日常的鴻蒙應(yīng)用開(kāi)發(fā)工作中,我常常遇到需要為應(yīng)用添加靈動(dòng)、流暢動(dòng)畫(huà)效果的場(chǎng)景,從一個(gè)按鈕的簡(jiǎn)單位移,到復(fù)雜組件的漸變展示,動(dòng)畫(huà)已然成為提升用戶體驗(yàn)不可或缺的部分。然而,初涉鴻蒙開(kāi)發(fā)的動(dòng)畫(huà)領(lǐng)域時(shí),面對(duì)眾多的 API 和繁雜的參數(shù)設(shè)置,我深感迷茫與困惑。為了幫助像曾經(jīng)的我一樣在這方面苦苦摸索的開(kāi)發(fā)者,也為了自己能更好地梳理知識(shí)體系,便有了這篇技術(shù)博客。

今天,我想重點(diǎn)分享兩個(gè)在鴻蒙開(kāi)發(fā)中非常實(shí)用的動(dòng)畫(huà)相關(guān) API:motionPathanimateToImmediately。這兩個(gè) API 涵蓋了從基礎(chǔ)的位移動(dòng)畫(huà)路徑設(shè)定,到進(jìn)階的顯式動(dòng)畫(huà)立即下發(fā)功能,掌握它們,能讓你的應(yīng)用瞬間 “活” 起來(lái)。

一、motionPath API 詳解

從 API Version 7 開(kāi)始支持,它允許我們精細(xì)地控制組件的運(yùn)動(dòng)路徑,為用戶帶來(lái)別具一格的視覺(jué)體驗(yàn)。

1. 基本語(yǔ)法

motionPath(value: MotionPathOptions),這里的 value 是關(guān)鍵,它承載了所有關(guān)于運(yùn)動(dòng)路徑的設(shè)置信息。

2. 參數(shù)剖析

  • value:必填項(xiàng),類(lèi)型為 MotionPathOptions,它就像是一個(gè)裝滿動(dòng)畫(huà)路徑秘密的寶箱。
  • MotionPathOptions 自身又包含多個(gè)重要參數(shù):
  • path:字符串類(lèi)型,必填。這是定義組件運(yùn)動(dòng)軌跡的核心,使用 svg 路徑字符串來(lái)描繪。例如 'Mstart.x start.y L50 50 Lend.x end.y Z',這里巧妙地用 startend 替代了起點(diǎn)和終點(diǎn)坐標(biāo),讓路徑設(shè)定更靈活,參考繪制路徑文檔能解鎖更多玩法。當(dāng)設(shè)置為空字符串時(shí),相當(dāng)于關(guān)閉路徑動(dòng)畫(huà),組件就會(huì)乖乖待在原地啦。
  • from:數(shù)字類(lèi)型,非必填,默認(rèn)值是 0.0,取值范圍在 [0, 1]。它指定了運(yùn)動(dòng)路徑的起點(diǎn)位置比例,若輸入小于 0 或大于 1 的值,系統(tǒng)會(huì)智能地將其按默認(rèn)值 0 處理。
  • to:數(shù)字類(lèi)型,非必填,默認(rèn)值 1.0,取值范圍同樣是 [0, 1]。它代表運(yùn)動(dòng)路徑的終點(diǎn)位置比例,要注意設(shè)置時(shí)需滿足 to 值 >= 異常值處理后的 from 值,否則可能得不到預(yù)期效果。
  • rotatable:布爾類(lèi)型,非必填,默認(rèn)值為 false。當(dāng)設(shè)為 true 時(shí),組件會(huì)如同靈動(dòng)的舞者,跟隨路徑旋轉(zhuǎn),增添動(dòng)態(tài)美感。

3. 示例代碼解讀

以下是一個(gè)生動(dòng)的示例,展示如何讓按鈕組件沿著設(shè)定好的路徑歡快 “奔跑”:

// xxx.ets
@Entry
@Component
struct MotionPathExample {
  @State toggle: boolean = true

  build() {
    Column() {
      Button('click me').margin(50)
        // 執(zhí)行動(dòng)畫(huà):從起點(diǎn)移動(dòng)到(300,200),再到(300,500),再到終點(diǎn)
       .motionPath({ path: 'Mstart.x start.y L300 200 L300 500 Lend.x end.y', from: 0.0, to: 1.0, rotatable: true })
       .onClick(() => {
          animateTo({ duration: 4000, curve: Curve.Linear }, () => {
            this.toggle =!this.toggle // 通過(guò)this.toggle變化組件的位置
          })
        })
    }.width('100%').height('100%').alignItems(this.toggle? HorizontalAlign.Start : HorizontalAlign.Center)
  }
}
效果預(yù)覽

在這段代碼中,我們創(chuàng)建了一個(gè)按鈕,點(diǎn)擊它后,按鈕會(huì)沿著 'Mstart.x start.y L300 200 L300 500 Lend.x end.y' 的路徑移動(dòng),從起點(diǎn)(默認(rèn) 0.0 比例處)穩(wěn)步邁向終點(diǎn)(默認(rèn) 1.0 比例處),并且在移動(dòng)過(guò)程中歡快旋轉(zhuǎn)(因?yàn)?rotatable 設(shè)為 true),同時(shí)借助 animateTo 控制動(dòng)畫(huà)時(shí)長(zhǎng)為 4000 毫秒,曲線為線性,讓整個(gè)動(dòng)畫(huà)流暢自然。

另外,從 API version 11 開(kāi)始,該接口支持在元服務(wù)中使用,這無(wú)疑為元服務(wù)開(kāi)發(fā)中的動(dòng)畫(huà)需求打開(kāi)了新大門(mén),讓元服務(wù)界面也能擁有炫酷動(dòng)感。

二、animateToImmediately API 深度探索

從 API Version 12 開(kāi)始閃亮登場(chǎng),它為我們提供了顯式動(dòng)畫(huà)立即下發(fā)的超能力。

1. 語(yǔ)法結(jié)構(gòu)

animateToImmediately(value: AnimateParam, event: () => void): void,簡(jiǎn)潔的外表下蘊(yùn)含強(qiáng)大功能。

2. 參數(shù)洞察

  • value:必填,類(lèi)型 AnimateParam,負(fù)責(zé)調(diào)配動(dòng)畫(huà)效果的各種參數(shù),如延遲時(shí)間、持續(xù)時(shí)長(zhǎng)等,是動(dòng)畫(huà)節(jié)奏的指揮官。
  • event:必填,是一個(gè)返回值為空的函數(shù)類(lèi)型,也就是閉包函數(shù)。在這個(gè)閉包函數(shù)里,組件狀態(tài)的任何改變都會(huì)被系統(tǒng)敏銳捕捉,并自動(dòng)插入過(guò)渡動(dòng)畫(huà),讓變化絲滑順暢。

3. 示例實(shí)戰(zhàn)

看看下面這段代碼如何巧用該 API 實(shí)現(xiàn)復(fù)雜的動(dòng)畫(huà)序列:

// xxx.ets
@Entry
@Component
struct AnimateToImmediatelyExample {
  @State widthSize: number = 250
  @State heightSize: number = 100
  @State opacitySize: number = 0
  private flag: boolean = true

  build() {
    Column() {
      Column()
     .width(this.widthSize)
     .height(this.heightSize)
     .backgroundColor(Color.Orange)
     .opacity(this.opacitySize)
      Button('change size')
       .margin(30)
       .onClick(() => {
          if (this.flag) {
            animateToImmediately({
              delay: 0,
              duration: 1000
            }, () => {
              this.opacitySize = 1
            })
            animateTo({
              delay: 1000,
              duration: 1000
            }, () => {
              this.widthSize = 150
              this.heightSize = 60
            })
          } else {
            animateToImmediately({
              delay: 0,
              duration: 1000
            }, () => {
              this.widthSize = 250
              this.heightSize = 100
            })
            animateTo({
              delay: 1000,
              duration: 1000
            }, () => {
              this.opacitySize = 0
            })
          }
          this.flag =!this.flag
        })
    }.width('100%').margin({ top: 5 })
  }
}
效果預(yù)覽

這里,點(diǎn)擊按鈕后,根據(jù) flag 的狀態(tài),首先利用 animateToImmediately 立即觸發(fā)透明度變化動(dòng)畫(huà),讓組件瞬間顯現(xiàn)(設(shè)置延遲為 0,持續(xù) 1000 毫秒使透明度變?yōu)?1),隨后通過(guò) animateTo 按順序調(diào)整組件的寬度和高度,實(shí)現(xiàn)一套連貫又富有層次感的動(dòng)畫(huà)組合。而且,從 API version 12 起,它也在元服務(wù)中有了用武之地,配合元服務(wù)的系統(tǒng)能力 SystemCapability.ArkUI.ArkUI.Full,為元服務(wù)的交互添彩。

最后如果這篇文章對(duì)你有幫助,希望您能關(guān)注,點(diǎn)贊,加收藏哦~~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容