昨天介紹了 number、boolean、trigger,今天繼續替玩家卡片加上姓名、主題色、等級與頭像,也補上其他還沒完整介紹的型別。
以下沿用 High-level API 與已手動綁定的 vmi。範例中的欄位,需要先在 Editor 建立並接好 Binding。
玩家姓名適合使用 string,透過 .value 讀寫即可:
const playerName = vmi.string("playerName");
if (!playerName) throw new Error("請確認 playerName 欄位");
playerName.value = "小明";
console.log(playerName.value);
比較需要跟設計師確認的是文字長度。預覽時放兩個字很漂亮,實際玩家名稱卻可能有十幾個字……。換行、截斷或縮小字體的呈現方式,要一起確認。
如果資料只能從固定選項中挑選,例如玩家等級 Bronze、Silver、Gold,就可以使用 enum:
const rank = vmi.enum("rank");
if (!rank) throw new Error("請確認 rank 欄位");
rank.value = "Gold";
console.log(rank.value);
這些選項必須先在 Editor 定義,前端傳入對應的名稱。雖然這裡同樣使用字串,enum 有事先約定的選項範圍,適合表示狀態、模式或樣式。Enum 說明
卡片底色或文字顏色,可以綁定到 color 欄位:
const themeColor = vmi.color("themeColor");
if (!themeColor) throw new Error("請確認 themeColor 欄位");
themeColor.rgb(255, 120, 0);
需要透明度時,也有對應的設定方法:
// 以下是不同的設定方式,依需求擇一使用
themeColor.rgba(255, 120, 0, 128); // alpha 使用 0–255
themeColor.opacity(0.5); // 透明度使用 0–1
themeColor.value = 0xFFFF7800; // 數值格式為 0xAARRGGBB
這裡容易混淆的是數值範圍與排列順序。串接前先約定顏色格式,拿到設計稿色碼時,才知道該怎麼轉換。Color API
頭像使用 image。它接收的是 Rive 解碼後的圖片物件,因此需要先下載圖片,再呼叫 decodeImage():
import { decodeImage } from "@rive-app/webgl2";
以下函式放在能存取 vmi 的範圍內:
async function updateAvatar(url) {
const avatar = vmi.image("avatar");
if (!avatar) throw new Error("請確認 avatar 欄位");
const response = await fetch(url);
if (!response.ok) {
throw new Error(`圖片載入失敗:${response.status}`);
}
const bytes = new Uint8Array(await response.arrayBuffer());
const image = await decodeImage(bytes);
if (!image) throw new Error("圖片解碼失敗");
try {
avatar.value = image;
} finally {
// 設定後,釋放這次持有的圖片參考
image.unref();
}
}
// 圖片放在專案的 public/avatar.png
updateAvatar("/avatar.png").catch(console.error);
這段範例設定完就釋放本地持有的參考;如果要保留圖片供後續重用,需要另外安排釋放時機。清除頭像則可以設定 avatar.value = null。Image API
實務上,頭像比例、裁切方式與載入失敗時的預設圖,也應該一起約定。這樣圖片來源換了,才不會每次都需要重新調整版面。
除了前兩天介紹的型別,還有以下幾種用途:
| 型別 | High-level 取得方式 | 使用情境 |
|---|---|---|
| font | vmi.font("nameFont") |
替文字樣式更換字體 |
| artboard | vmi.artboard("badge") |
動態替換徽章等 Component |
| view model | vmi.viewModel("stats") |
整理巢狀資料,Day 05 已介紹 |
| list | vmi.list("players") |
顯示數量會變動的玩家卡片或排行榜 |
這些都是 View Model 可以使用的屬性型別。完整型別說明
font 的流程與 image 類似:下載字體檔、用 decodeFont() 解碼,再指定給欄位的 .value。Font API
artboard 則需要先在 Editor 準備可替換的 Component。程式端可從已載入的 RiveFile 呼叫 getBindableArtboard(name),再把取得的物件指定給欄位。Artboard API
list 裡面放的是 View Model Instances。假設 Editor 已建立 players 清單,並將 PlayerCard 配置成清單項目,可以這樣新增一位玩家:
const players = vmi.list("players");
const playerVM = r.viewModelByName("PlayerCard");
if (!players || !playerVM) {
throw new Error("請確認 players 與 PlayerCard");
}
const player = playerVM.defaultInstance();
const name = player?.string("playerName");
if (!player || !name) {
throw new Error("請確認玩家的初始資料與姓名欄位");
}
name.value = "小明";
players.addInstance(player);
List 也提供 removeInstance()、removeInstanceAt()、swap() 與 length,用來管理項目及順序。畫面上的重複項目與排版,仍需要在 Editor 設定好。List 串接方式、Editor 設定
到這裡,就能看出 Data Binding 可承接的資料範圍:從單一文字、顏色,到圖片、Component 與整份清單。對團隊來說,除了約定 key,還要一起確認內容長度、資源規格與資料結構,才能把更多時間留給功能製作,減少交付後的來回調整。