基于ArkTS的應(yīng)用入場動畫
前言
相信讀者對應(yīng)用入場動畫并不陌生。當(dāng)用戶打開某個應(yīng)用時,應(yīng)用得到響應(yīng),與此同時其在屏幕中所渲染的第一個畫面通常是它的入場動畫。當(dāng)然,應(yīng)用響應(yīng)后所拋出的不一定是動畫,它也可以是一個靜態(tài)的頁面,不過不論是動畫還是靜態(tài)頁面,它們所起到的功能是相同的——在后臺完成應(yīng)用中的重要模塊的初始化,貼出開發(fā)團隊的slogen,亦或展示一些甲方的產(chǎn)品推廣廣告。
本期筆者將以一個輕量Demo的開發(fā)流程為例,與筆者共同探索如何利于ArkTS生產(chǎn)應(yīng)用的入場動畫。
正文
創(chuàng)建工程
打開DevEco Studio(開發(fā)工具的版本必須支持API9),創(chuàng)建一個新的project,相關(guān)勾選如下:
添加新頁面
成功創(chuàng)建工程后,在工程文件目錄中打開目錄:Demo/entry/src/main/ets/pages, 接著右擊page,選擇New>TypeScript ArkTS File, 創(chuàng)建一個新的ArkTS文件,并將其命名為Second
接著,在工程文件目錄中打開目錄:Demo/entry/src/resources/base/profile/main_pages,添加Second頁面的路徑信息。注意,字符串'pages/Index’后面的逗號不能漏寫。
編寫新頁面的UI
在編輯器中打開新創(chuàng)建的Second.ets,添加如下代碼:
@Entry
@Component
struct Index {
@State message: string = '主頁面'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(40)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
.backgroundColor('#F1F1F1')
}
}
事實上,這段代碼來自于Index.ets, 我們只不過是將Index.ets的代碼拷貝至Second.ets中后,修改了變量message的初值,并更換了頁面的背景色。由于Second.ets所管理的頁面在此次的開發(fā)案例中不是主角,所以我們簡單設(shè)計一下它的UI就足夠了。
Second.ets的最終預(yù)覽效果如下:
編寫入場頁面的UI
加入圖片資源
Before coding,我們需要添加一份圖片資源到工程的指定目錄內(nèi)。
在工程文件目錄中打開目錄:Demo/entry/src/main/resources/rawfile, 添加一張任意的圖片(可以在IDE中將待添加的圖片資源直接粘貼至rawfile目錄下,也可以在文件資源管理器中通過文件路徑打開rawfile目錄并添加圖片資源),將其命名為logo1。當(dāng)然,圖片的格式?jīng)]有要求,只要在之后的步驟中能被正確引用即可。
添加組件
在編輯器中打開Index.ets(此頁面將作為入場頁面), 刪除Column組件內(nèi)關(guān)于Text組件的代碼塊,增添一個新的Image件和一個新的Text組件,并填充它們的UI屬性,相關(guān)代碼如下。其中,新增的Image組件所引用的圖片資源是上一個步驟中所添加的logo1.jpg。
@Entry
@Component
struct First {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
//刪除頁面初始化時默認帶有的Text組件, 增加一個新的image件和一個新的Text組件
Image($rawfile('logo1.jpg'))
.height(120)
.width(120)
Text('Brunhild')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({
top:7
})
}
.width('100%')
}
.height('100%')
}
}
預(yù)覽器效果如下:
至此,我們已完成對Index.ets的頁面UI繪制。接下來,我們需要為這兩個新添的組件設(shè)置與屬性動畫有關(guān)的屬性。屬性動畫(animation)是ArkUI提供的最基礎(chǔ)和常用的動畫功能之一,它的功能邏輯是,當(dāng)組件的布局屬性(譬如位置,大小,背景顏色)發(fā)生變化時,組件會按照已設(shè)置好的動畫參數(shù),從原有的布局狀態(tài)過渡到變化后的布局狀態(tài),而這個過渡的擬連續(xù)過程便是用戶所見到的動畫。在這個基礎(chǔ)上,我們可以制作一個簡單的應(yīng)用入場動畫效果。
添加關(guān)鍵屬性
所涉及的兩個重要屬性分別是translate屬性和animation屬性。
事實上,系統(tǒng)為每個被渲染的組件都設(shè)置屬于它的相對坐標系。這個坐標系是一個平面直角坐標系,并且,相對于屏幕,X坐標軸正方向水平向右,Y坐標軸正方向豎直向下。當(dāng)一個組件的translate屬性被設(shè)置時,它的實際位置會跟著translate屬性而偏移。比如,一個原本位于屏幕中央的組件,更改其translate屬性為{x:100,y:0}后,其位置會相對屏幕中央往右平移100px。
animation屬性的可供設(shè)置的參數(shù)如下所示,每個參數(shù)都會在不同維度影響動畫的最終效果。
/**
* Animation duration, in ms.
* @since 7
*/
/**
* Animation duration, in ms.
* @form
* @since 9
*/
duration?: number;
/**
* Animation playback speed. A larger value indicates faster animation playback, and a smaller value indicates slower
* animation playback. The value 0 means that there is no animation.
* @since 7
*/
tempo?: number;
/**
* Animation curve.
* @type { string | Curve}
* @since 7
*/
/**
* Animation curve.
* @type { string | Curve | ICurve}
* @form
* @since 9
*/
curve?: Curve | string | ICurve;
/**
* Animation playback mode. By default, the animation is played from the beginning after the playback is complete.
* @since 7
*/
delay?: number;
/**
* Animation playback mode. By default, the animation is played from the beginning after the playback is complete.
* @since 7
*/
iterations?: number;
/**
* Animation playback mode. By default, the animation is played from the beginning after the playback is complete.
* @since 7
*/
/**
* Animation playback mode. By default, the animation is played from the beginning after the playback is complete.
* @form
* @since 9
*/
playMode?: PlayMode;
/**
* Callback invoked when the animation playback is complete.
* @since 7
*/
/**
* Callback invoked when the animation playback is complete.
* @form
* @since 9
*/
onFinish?: () => void;
接下來,我們?yōu)榻M件添加關(guān)鍵屬性。
首先,定義變量 translateY_Logo,同時設(shè)置Image組件的translate屬性和animation屬性。
@Entry
@Component
struct First {
......
@State translateY_Logo:number = -200 //定義一個用@state修飾的number型變量translateY_Logo
build() {
Row() {
Column() {
//刪除頁面初始化時默認帶有的Text組件, 增加一個新的image件和一個新的Text組件
Image($rawfile('logo1.jpg'))
.height(120)
.width(120)
//添加關(guān)鍵屬性
.translate({
y:this.translateY_Logo
})
.animation({
//播放時長(ms)
duration:2000,
//播放速度
tempo:1,
//播放曲線,所選擇的是‘快出慢入’
curve:Curve.FastOutSlowIn,
//延遲(ms)
delay:500,
//循環(huán)次數(shù)(-1為無限循環(huán))
iterations:1,
//播放模式
playMode:PlayMode.Normal
})
......
}
.width('100%')
}
.height('100%')
}
}
接著,定義變量 translateY_Title,同時設(shè)置Text組件的translate屬性和animation屬性。
@Entry
@Component
struct First {
......
@State translateY_Title:number = 200 //定義一個用@state修飾的number型變量translateY_Title
build() {
Row() {
Column() {
//刪除頁面初始化時默認帶有的Text組件, 增加一個新的image件和一個新的Text組件
......
Text('Brunhild')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({
top:7
})
//添加關(guān)鍵屬性
.translate({
y:this.translateY_Title
})
.animation({
delay:500,
duration:2000,
curve:Curve.FastOutSlowIn,
tempo:1,
})
}
.width('100%')
}
.height('100%')
}
}
頁面起始狀態(tài)的效果如下,可以看到,設(shè)置translate屬性后,Image組件往Y軸負方向偏移,Text組件則往Y軸正方向偏移。
最后,我們?yōu)門ext組件添加onAppear回調(diào)。onAppear可以被理解為一個事件監(jiān)聽器,當(dāng)一個綁定了onAppear的組件裝載于顯示器時,onAppear回調(diào)將被觸發(fā),執(zhí)行onAppear()中所傳入的操作語句。換句話說,Text組件在添加onAppear屬性后,當(dāng)此Text組件出現(xiàn)時(筆者也不清楚這個出現(xiàn)是如何定義的),onAppear立即觸發(fā),執(zhí)行已寫入的函數(shù)參數(shù)(即λ表達式中的內(nèi)容)。
在如下代碼中,筆者為Text組件增加了onAppear回調(diào),導(dǎo)入了router模塊,并寫入了相關(guān)操作語句:首先,改變Image組件和Text組件的translate屬性,激活屬性動畫;之后,設(shè)置定時器(每4秒執(zhí)行一次),使得系統(tǒng)在屬性動畫結(jié)束后執(zhí)行頁面跳轉(zhuǎn)(跳轉(zhuǎn)至Second頁面);最后,銷毀先前設(shè)置的定時器。
import router from '@ohos.router'; //導(dǎo)入router模塊
@Entry
@Component
struct First {
......
@State translateY_Title:number = 200 //定義一個用@state修飾的number型變量translateY_Title
build() {
Row() {
Column() {
//刪除頁面初始化時默認帶有的Text組件, 增加一個新的image件和一個新的Text組件
......
Text('Brunhild')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({
top:7
})
//添加關(guān)鍵屬性
.translate({
y:this.translateY_Title
})
.animation({
delay:500,
duration:2000,
curve:Curve.FastOutSlowIn,
tempo:1,
})
//增加onAppear回調(diào)
.onAppear(()=>{
//改變屬性參數(shù)
this.translateY_Logo = 0
this.translateY_Title = 0
//設(shè)置定時器
let id = setInterval(()=>{
//打印日志
console.info('router to Second')
//頁面跳轉(zhuǎn)
router.pushUrl({
url:'pages/Second'
})
//定時器執(zhí)行之后立即銷毀
clearInterval(id)
},4000,[])
})
}
.width('100%')
}
.height('100%')
}
}
至此,一個關(guān)于入場動畫的Demo便完成了。
預(yù)覽效果如下:
結(jié)語
ArkTS的動畫開發(fā)無疑是非常有趣的,如果讀者想開發(fā)更加復(fù)雜的動畫效果,不妨參考ArkTS的官方API文檔,學(xué)習(xí)和玩轉(zhuǎn)更多新奇的用法。
文章相關(guān)附件可以點擊下面的原文鏈接前往下載:
https://ost.51cto.com/resource/3050