在日常的鴻蒙應(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:motionPath 和 animateToImmediately。這兩個(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',這里巧妙地用start和end替代了起點(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)
}
}

在這段代碼中,我們創(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 })
}
}

這里,點(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)贊,加收藏哦~~~~