# 幀動(dòng)畫(huà)
幀動(dòng)畫(huà)是一種內(nèi)置的動(dòng)畫(huà)實(shí)現(xiàn),提供給開(kāi)發(fā)者類似于css動(dòng)畫(huà)的能力,去控制一個(gè)元素下所有組件的數(shù)據(jù)。
我們提供了一種資源來(lái)定義幀動(dòng)畫(huà),之后可以用對(duì)應(yīng)的加載器加載,在組件中使用。
# 幀動(dòng)畫(huà)資源
首先我們要準(zhǔn)備一個(gè)幀動(dòng)畫(huà)資源,它是被存儲(chǔ)為json格式,大致如下:
{
"keyframe": {
"parent": {
"0": {
"rotation": [0, 0, 0],
},
"100": {
"rotation": [0, 6.28, 0]
}
},
"child": {
"0": {
"position.y": -0.5,
"material.u_baseColorFactor": [0.48, 0.78, 0.64, 1]
},
"100": {
"position.y": 1.5,
"material.u_baseColorFactor": [0.176, 0.368, 0.937, 1]
}
}
},
"animation": {
"parent": {
"keyframe": "parent",
"duration": 8,
"ease": "linear",
"loop": -1
},
"child": {
"keyframe": "child",
"duration": 4,
"ease": "ease-in-out",
"direction": "both",
"loop": -1
}
}
}
可以看到其中有兩個(gè)部分:keyframe和animation。
keyframe中定義了幀動(dòng)畫(huà)具體的行為,本質(zhì)上類似于css3中的keyframes,其中進(jìn)度的范圍是0~100,每個(gè)進(jìn)度下是動(dòng)畫(huà)具體影響的鍵和值。其中鍵的規(guī)則是[組件].[屬性].[屬性2].[屬性...],比如transform.postion.x,就是對(duì)應(yīng)于使用了這個(gè)幀動(dòng)畫(huà)的元素下的transform組件的position屬性的x屬性變化。
當(dāng)然我們不難看到,如果僅僅是按照這樣的規(guī)則,一來(lái)是開(kāi)發(fā)者必須要實(shí)現(xiàn)對(duì)應(yīng)組件下每個(gè)屬性的訪問(wèn)器,其次是對(duì)于一些常見(jiàn)的屬性寫(xiě)起來(lái)會(huì)繁瑣,再者對(duì)于材質(zhì)動(dòng)畫(huà)會(huì)無(wú)從下手。為了解決這個(gè)問(wèn)題,我做了一些實(shí)現(xiàn)上的優(yōu)化:
- 如果整個(gè)屬性路徑最終是
[組件].[屬性]的形式,則不需要寫(xiě)訪問(wèn)器,會(huì)自動(dòng)設(shè)置。 position、rotation、scale會(huì)被自動(dòng)代理到transform組件下。material是一種特殊的定義,會(huì)被自動(dòng)代理到mesh組件的材質(zhì)的uniform下。
要注意,屬性的值僅僅支持
number、number-array和color類型的數(shù)據(jù)。 有了keyframe,再者就是animation了。animation中定義了真的暴露給animator的片段,其中第一級(jí)的每個(gè)鍵都是片段的名字,它對(duì)應(yīng)的值就是其作為動(dòng)畫(huà)播放時(shí)的一些參數(shù)。keyframe定義這個(gè)片段對(duì)應(yīng)于上面定義的哪個(gè)keyframe,duration是以秒為單位的時(shí)長(zhǎng),loop是默認(rèn)循環(huán)次數(shù)(-1為永遠(yuǎn)循環(huán)),delay是播放延遲,direction是播放方向,默認(rèn)forwards,可選backwards和both(在循環(huán)時(shí)交替前向反向),ease則是時(shí)間函數(shù),決定動(dòng)畫(huà)的插值曲線。
支持的時(shí)間函數(shù)可見(jiàn)API文檔:noneParamsEaseFuncs和useParamsEaseFuncs。
# 使用
有了資源我們便可以加載使用它,和其他資源一樣,keyframe資源遵循標(biāo)準(zhǔn)加載流程:
<xr-asset-load type="keyframe" asset-id="anim" src="/assets/keyframes/test.json" />
然后便可以引用使用:
<xr-node anim-keyframe="anim" anim-autoplay="clip:parent">
<xr-node position="0 -0.5 3" anim-keyframe="anim" anim-autoplay="clip:child">
</xr-node>
</xr-node>
注意這里使用了anim-keyframe字段來(lái)指定animator組件要默認(rèn)使用哪個(gè)keyframe動(dòng)畫(huà)。