跳到主要内容

加载资源

如果你想动态替换图像,请使用图像数据绑定

某些 Rive 文件可能包含可以嵌入到实际文件二进制中的资源,例如字体、图像或音频文件。Rive 运行时可以在加载 Rive 文件时加载这些资源。虽然这样可以轻松使用 Rive 文件/运行时,但有时有机会在运行时加载这些资源甚至替换它们,而不是将它们嵌入文件二进制中。

这种方式有几个好处:

  • 保持 .riv 文件小巧,避免较大资源的潜在臃肿
  • 根据任何原因动态加载资源,例如在移动设备上运行 .riv 时加载较小分辨率的图像,而在桌面设备上加载较大分辨率的图像
  • 预加载资源以便在显示 .riv 时立即可用
  • 使用已打包在应用中的资源,如字体文件
  • 在多个 .riv 之间共享同一资源

加载资源的方法

目前有三种不同的方式来加载 Rive 文件的资源。

在 Rive 编辑器中,从资源选项卡中选择所需的资源,并在检查器中选择所需的导出选项:

Image

嵌入式资源

在 Rive 编辑器中,通过选择「嵌入式」导出类型,可以将静态资源包含在 .riv 文件中。如本页开头所述,当 Rive 文件加载时,运行时会隐式尝试同时加载嵌入在 .riv 中的资源,你无需关心手动加载任何资源。

注意事项: 嵌入式资源可能会增大文件体积,尤其是在使用 Rive 文本(文本概述)时的字体方面。

嵌入是默认选项。

通过 Rive CDN 加载

在 Rive 编辑器中,你可以将导入的资源标记为「托管」导出类型,这意味着当你导出 .riv 文件时,资源不会嵌入到文件二进制中,而是托管在 Rive 的 CDN 上。这意味着在运行时加载文件时,运行时会看到资源被标记为「Hosted」并从 Rive CDN 加载资源,因此你无需自己加载任何内容,同时文件仍然保持小巧。

注意事项: 应用将额外调用 Rive CDN 来检索你的资源。

托管资源在 Voyager 和 Enterprise 计划中可用。了解更多关于我们的计划和定价

图片 CDN

某些图片 CDN 允许实时图像转换,包括调整大小、裁剪和基于浏览器和设备能力的自动格式转换。这些 CDN 可以托管你的 Rive 图像资源。请注意,对于这些 CDN,你可能需要指定接受的格式,例如作为 HTTP 头部请求的一部分:

... headers: { Accept: 'image/png,image/webp,image/jpeg,*/*', } ...

请参阅你的 CDN 提供商的文档以获取更多信息。

⚠️ Rive 支持以下图像格式:jpegpngwebp

引用资源

在 Rive 编辑器中,你可以将导入的资源标记为「引用」导出类型,这意味着当你导出 .riv 文件时,资源不会嵌入到文件二进制中,加载资源的责任将由你的应用在运行时处理。此选项允许你在运行时开始加载 .riv 文件时通过处理程序 API 动态加载资源。如果你需要根据任何应用/游戏逻辑动态加载特定资源,并且特别希望保持文件大小小巧,则此选项更合适。

所有引用的资源,包括 .riv,将在你导出动画时打包为 zip 文件。

注意事项: 你需要在加载 Rive 时提供资源处理程序 API,负责自行加载资源。请参见下方的处理资源部分。

处理资源

示例

使用资源处理程序 API

在实例化新的 Rive 实例时,向参数列表中添加 assetLoader 回调属性。此回调将在运行时从 .riv 文件检测到的每个资源加载时被调用,并负责处理运行时资源的加载或传递责任给运行时以其他方式加载。

你可能需要处理资源加载的一个场景是,如果文件中的资源标记为引用,并且你需要提供实际资源来渲染图形,因为 Rive 未将其嵌入 .riv 中,因此无法加载。

你可能希望让运行时处理资源加载的一个场景是,如果文件中的资源标记为托管,并希望将加载责任传递给运行时(运行时将调用 Rive CDN 来加载)。

assetLoader: (asset: rc.FileAsset, bytes: Uint8Array) => boolean;

你提供的回调将传递 assetbytes

  • asset — 来自 WASM 的 FileAsset 对象引用。你可以从此对象获取多个属性,例如名称、资源类型等。你还会用此对象为你想要动态加载的资源设置新的 Rive 特定资源(例如图像的 RenderImage、字体的 Font 或音频的 Audio)。
  • bytes — 资源的字节数组(如果可用,比如它是嵌入式资源)。

重要提示: 注意返回值是一个 boolean,如果你打算自行处理加载资源,需要返回 true;如果你不希望自行处理该给定资源的加载,并尝试让运行时加载该资源,则返回 false

在解码资源时,确保在不再需要时调用 unref,以避免内存泄漏。这允许引擎在该资源不再被任何动画使用时清理它。

示例用法

import {
Rive,
Fit,
Alignment,
Layout,
decodeFont,
ImageAsset, // 可选包含用于类型检查
FontAsset, // 可选包含用于类型检查
FileAsset, // 可选包含用于类型检查
} from "@rive-app/canvas";

// 通过使用 decodeFont API 加载随机资源,
// 并将其提供给 assetLoader 中提供的 asset 的 setFont API
const randomFontAsset = (asset) => {
const urls = [
"https://cdn.rive.app/runtime/flutter/IndieFlower-Regular.ttf",
"https://cdn.rive.app/runtime/flutter/comic-neue.ttf",
"https://cdn.rive.app/runtime/flutter/inter.ttf",
"https://cdn.rive.app/runtime/flutter/inter-tight.ttf",
"https://cdn.rive.app/runtime/flutter/josefin-sans.ttf",
"https://cdn.rive.app/runtime/flutter/send-flowers.ttf",
];
let randomIndex = Math.floor(Math.random() * urls.length);
fetch(urls[randomIndex]).then(
async (res) => {
// decodeFont 创建一个 Rive 特定的 Font 对象,该对象用于 assetLoader
// 中的 asset 的 `setFont()`
const font = await decodeFont(new Uint8Array(await res.arrayBuffer()));
asset.setFont(font);

// 确保在不再需要时对字体调用 unref。这允许引擎在
// 不再被任何动画使用时清理它。
font.unref();
}
);
};


const riveInstance = new Rive({
src: "acqua_text.riv",
stateMachines: "State Machine 1", // 要播放的状态机名称
canvas: document.getElementById("rive-canvas"),
layout: new Layout({
fit: Fit.Cover,
alignment: Alignment.Center,
}),
autoplay: true,
// 回调处理程序,指示如何处理正在加载的 Rive 文件中找到的资源
assetLoader: (asset, bytes) => {
console.log("Asset properties to query", {
name: asset.name,
fileExtension: asset.fileExtension,
cdnUuid: asset.cdnUuid,
isFont: asset.isFont,
isImage: asset.isImage,
isAudio: asset.isAudio,
bytes,
});

// 如果资源具有 `cdnUuid`,返回 false 让运行时处理从 CDN 加载
// 或者如果找到了资源的字节(即它是嵌入的),返回 false,因为此处不需要工作
if (asset.cdnUuid.length > 0 || bytes.length > 0) {
return false;
}

// 这里,我们在 Rive 文件加载时加载一个随机字体的字体资源
// 并返回 true,因为此回调处理程序负责加载资源,而非运行时
if (asset.isFont) {
randomFontAsset(asset);
return true;
}
},
onLoad: () => {
// 使用设备像素比防止 canvas 模糊
riveInstance.resizeDrawingSurfaceToCanvas();
}
});

额外资源

视频教程:https://www.youtube.com/watch?v=BrWBmZwouQQ