跳转到内容

加载资源

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);})