前兩天分別討論了要怎麼自己實現 render loop,以及要怎麼操作 State Machine, Rive Text, Rive Event,只要掌握了這兩個概念,就可以成功使用 Low-level API 了。
但除此之外,Low-level API 其中一個賣點就是更精細的操縱渲染,到底什麼叫做更精細的操控?可以用它做到什麼?就是我們今天想分享的部分。以下是一些簡單的 cookbook。
要先提到的是說,因為每一個 .riv 檔都執行一次 update & render,所以不要傻傻的一行一行手寫,記得做成陣列然後用 forEach 去跑。
既然做成陣列了,那乾脆把所有 .riv 檔相關的資料抽象出一個設定檔,我們的設定檔大概長這樣。
const files = [
{
name: 'Rive1',
path: '/path1.riv',
artboardName: 'artboardName1',
stateMachineName: 'stateMachineName1',
isShow: () => true
zIndex: 10,
isReportingEvent: () => false
},
// ...Rive2, Rive3, Rive4
]
簡單來說就是用一些 key 去控制渲染流程,例如因為 canvas 是一層一層畫上去的,所以用 zIndex 搭配 sort,可以做出 CSS z-index 的效果。或是用 isShow 判斷要不要渲染,或是在發送 event 的時候先判斷一下 isReportingEvent,達到在某些時候攔截 event 的效果。
不過這很考驗工程師的抽象化能力就是了,一不小心很容易失控,自己要稍微斟酌一下。
因為 init 階段也是我們手寫的,其中有 fetch 這一段,因此有需要的話,可以事先 fetch 好需要的 .riv 檔,不需要等用到時再載入,達到 preload 的效果。也可以離開時想辦法 cache 起來,不用回來時再載入一遍。
const bytes = await (await fetch(new Request('file/path/filename.riv'))).arrayBuffer()
甚至操作的好的話,整段 init 都可以提前做好,加快載入速度,讓使用者一進去就直接開始 render loop。或是操作 render loop 的遞迴條件,達到 pause 或 freeze 的效果,讓使用者可以暫停,或頻繁切換多個 Rive 動畫時更加流暢。
不過老實說,講到這邊已經是扯得非常遠了,除了實作難度不低以外,其實投資報酬率沒有想像中高,畢竟你最佳化半天,可能設計師多載入一張圖片就抵掉你放出的所有性能,所以稍微知道一下就好,謹慎使用,不用太強求。
礙於篇幅的關係,我們只有稍微提一些簡單的 cookbook,畢竟 render loop 是自己手刻的,所以通常可以操作的更精細,可以做到更多實務上奇怪的需求,就等大家自己去發掘了。