跳到內容

載入資源

Cavalry Web Player 和 API 目前處於 beta 階段,可能會有所變更。

類型API 方法
圖像replaceImageAsset()
字型replaceFontAsset()
CSVreplaceCSVAsset()
ExcelreplaceExcelAsset()
SVGreplaceSVGAsset()
Google SheetsreplaceGoogleSheet()

首先透過匯入 CavalryWasm.js JavaScript 模組來實例化模組。

const CavalryModule = await import("./wasm-lib/CavalryWasm.js");const Module = await CavalryModule.default( // `locateFile` is required for the module to load the wasm files { locateFile: (path) => `./wasm-lib/${path}` });

在將檔案路徑傳遞給各種方法時,播放器會在虛擬檔案系統中尋找這些檔案。

使用 FS.writeFile 將資源寫入虛擬檔案系統。

Module.FS.writeFile("my-image.png", Uint8Array)

使用 fetch 從 URL 請求資源。然後可以透過 Response.bytes 讀取資料,不過瀏覽器支援有限。為獲得更好的瀏覽器支援,請使用 Response.arrayBuffer 並將其轉換為 Uint8Array

const filename = "my-image.png"const response = await fetch(`/url/to/${filename}`)// 瀏覽器支援有限// const asset = await response.bytes()const asset = await response.arrayBuffer()Module.FS.writeFile(filename, new Uint8Array(asset))

資源可以在執行時替換。assetId(例如 asset#2)與 Cavalry 場景檔案中的資源 ID 相符。

// 替換圖像資源const filename = "new-image.png"const response = await fetch(filename);const imageData = await response.arrayBuffer();Module.FS.writeFile(filename, new Uint8Array(imageData));player.replaceImageAsset(filename, "asset#2");player.render(surface);
// 替換 CSV 資源const filename = "data.csv"const response = await fetch(filename);const csvData = await response.arrayBuffer();Module.FS.writeFile(filename, new Uint8Array(csvData));player.replaceCSVAsset(filename, "asset#3");player.render(surface);

字型需要先載入,播放器才能識別它們。

// 在使用 `MakeWithPath` 載入場景之前Module.loadFont(filename, assetId);

如果需要,可以替換字型資源。這不會卸載現有字型,也不會更改正在使用該字型的任何文字形狀的字型。

player.replaceFontAsset(filename, assetId);

Google Sheets 會自動載入。使用 replaceGoogleSheet 在執行時替換 Google Sheet 資源。

將 Google Sheet 的共用權限設為「任何知道連結的人」,以避免錯誤。

const sheetId = "UNIQUE_ID_OF_GOOGLE_SHEET"const url = `https://docs.google.com/spreadsheets/d/${sheetId}`player.replaceGoogleSheet(url, assetId);

當透過 MakeWithPath 載入場景時,其資源將位於 Module.pendingAssets 陣列中。

可以透過走訪該陣列來載入資源。

const player = Module.Cavalry.MakeWithPath("scene.cv");const assets = Module.pendingAssetsfor (const { type, filename, assetId } of assets) { // 假設資源與場景中的資源檔案名稱相同 const response = await fetch(`/url/to/${filename}`); const data = await response.arrayBuffer(); Module.FS.writeFile(filename, new Uint8Array(data)); switch (type) { case "image": player.replaceImageAsset(filename, assetId); break; case "font": // 字型需要載入 module.loadFont(filename, assetId); // 如果需要,替換字型資源 player.replaceFontAsset(filename, assetId); break; case "csv": player.replaceCSVAsset(filename, assetId); break; case "svg": player.replaceSVGAsset(filename, assetId); break; case "excel": player.replaceExcelAsset(filename, assetId); break; default: console.warn( `Unexpected asset type "${type}" for ${filename} (${assetId})` ); return; }}const canvas = document.getElementById("canvas")const { width, height } = player.getSceneResolution()const surface = module.makeWebGLSurfaceFromElement(canvas, width, height)player.render(surface);

當透過 MakeWithPath 載入場景時,每個資源都會觸發 cavalryAutoLoadAsset 事件。

監聽此事件可作為 Module.pendingAssets 的替代方案。

確保回呼函式可以存取 Moduleplayersurface

window.addEventListener("cavalryAutoLoadAsset", async (event) => { const { assetId, filename, type } = event.detail const response = await fetch(`/url/to/${filename}`); const data = await response.arrayBuffer(); Module.FS.writeFile(filename, new Uint8Array(data)); switch (type) { case "image": player.replaceImageAsset(filename, assetId); break; case "font": // 字型需要載入 Module.loadFont(filename, assetId); // 如果需要,替換字型資源 player.replaceFontAsset(filename, assetId); break; case "csv": player.replaceCSVAsset(filename, assetId); break; case "svg": player.replaceSVGAsset(filename, assetId); break; case "excel": player.replaceExcelAsset(filename, assetId); break; default: console.warn(`Unexpected asset type "${type}" for ${assetId} (${filename})`); return; } player.render(surface);})