加载资源
如果您想动态替换图像,请使用图像数据绑定。
某些 Rive 文件可能包含可以嵌入到实际文件二进制中的资源,例如字体、图像或音频文件。Rive 运行时可以在加载 Rive 文件时加载这些资源。虽然这使得 Rive 文件/运行时的使用变得简单,但有时可能需要在运行时加载这些资源甚至替换它们,而不是将它们嵌入到文件二进制中。
这种方法有几个好处:
- 保持
.riv文件小巧,避免大型资源的潜在膨胀 - 出于任何原因动态加载资源,例如:如果在移动设备上运行
.riv,加载较低分辨率的图像;而对于桌面设备,加载较高分辨率的图像 - 预加载资源以便在显示
.riv时立即可用 - 使用已与应用捆绑的资源,例如字体文件
- 在多个
.riv文件之间共享同一资源
加载资源的方法
目前有三种不同的方式为 Rive 文件加载资源。
在 Rive 编辑器中,从资源选项卡中选择所需的资源,并在检查器中选择所需的导出选项:
嵌入式资源
在 Rive 编辑器中,可以通过选择「嵌入式」导出类型将静态资源包含在 .riv 文件中。如本页开头所述,当 Rive 文件被加载时,运行时将隐式地尝试加载嵌入在 .riv 中的资源,您无需关心手动加载任何资源。
注意事项: 嵌入式资源可能会增加文件大小,特别是在使用 Rive Text 时的字体(文本概述)。
嵌入式是默认选项。
通过 Rive CDN 加载
在 Rive 编辑器中,您可以将导入的资源标记为「托管」导出类型,这意味着当您导出 .riv 文件时,资源不会嵌入到文件二进制中,而是托管在 Rive 的 CDN 上。这意味着在运行时加载文件时,运行时会看到资源被标记为"托管"并从 Rive CDN 加载资源,这样您无需自己加载任何内容,文件仍然可以保持小巧。
注意事项: 应用将向 Rive CDN 发起额外的调用以获取资源。
托管资源在 Voyager 和 Enterprise 计划中可用。了解更多关于我们的计划和定价。
图像 CDN
某些图像 CDN 允许即时进行图像转换,包括调整大小、裁剪和根据浏览器及设备能力自动格式转换。这些 CDN 可以托管您的 Rive 图像资源。请注意,对于这些 CDN,您可能需要指定接受的格式,例如作为 HTTP 头请求的一部分:
... headers: { Accept: 'image/png,image/webp,image/jpeg,*/*', } ...
请参见您的 CDN 提供商的文档了解更多信息。
⚠️ Rive 支持以下图像格式:jpeg、png 和 webp
引用资源
在 Rive 编辑器中,您可以将导入的资源标记为「引用」导出类型,这意味着当您导出 .riv 文件时,资源不会嵌入到文件二进制中,加载资源的责任将由您的应用在运行时处理。此选项使您能够在运行时开始加载 .riv 文件时通过处理程序 API 动态加载资源。如果您需要根据任何应用/游戏逻辑动态加载特定资源,并且特别希望保持文件大小较小,此选项是更可取的。
所有引用资源,包括 .riv,将在您导出动画时打包为 zip 文件。
注意事项: 您需要在加载 Rive 时提供资源处理程序 API,该 API 应自行完成加载资源的工作。请参见下面的处理资源。
处理资源
示例
新版运行时(推荐)
使用资源处理程序 API
要加载带外资源,在加载 Rive 文件时提供一个键值对象,将预期的资源映射到其来源。
键是从 Rive 编辑器导出的名称 + 唯一标识符组合。
const { riveFile, isLoading, error } = useRiveFile(
require('path/to/file.riv'),
{
referencedAssets: {
'Inter-594377': {
source: require('../../assets/fonts/Inter-594377.ttf'),
},
'referenced-image-2929282': {
source: { uri: 'https://picsum.photos/id/372/500/500' },
},
'referenced_audio-2929340': {
source: require('../../assets/audio/referenced_audio-2929340.wav'),
},
},
}
);
您可以选择性排除唯一标识符。例如,代替
Inter-594377,您可以使用Inter。但是,建议使用完整标识符以避免潜在的冲突。仅使用资源名称可以让您避免知道唯一标识符,并给您更多命名控制权。
使用 Suspense
您可以自己管理资源解码,并在多个 Rive 视图之间共享此资源。
目前我们仅支持图像,但其他资源类型的工作正在进行中。
function getImagePromise(url: string): Promise<RiveImage> {
return RiveImages.loadFromURLAsync(url);
}
<ErrorBoundary key={errorBoundaryKey} fallback={renderErrorFallback}>
<React.Suspense
fallback={
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" />
<Text style={styles.loadingText}>Loading image...</Text>
</View>
}
>
<RiveContent imageUrl={uri} />
</React.Suspense>
</ErrorBoundary>
function RiveContent({ imageUrl }: { imageUrl: string }) {
const imagePromise = React.useMemo(
() => getImagePromise(imageUrl),
[imageUrl]
);
const riveImage = React.use(imagePromise);
const { riveFile, isLoading, error } = useRiveFile(
require('../../assets/rive/out_of_band.riv'),
{
referencedAssets: {
'Inter-594377': {
source: require('../../assets/fonts/Inter-594377.ttf'),
},
'referenced-image-2929282': riveImage,
'referenced_audio-2929340': {
source: require('../../assets/audio/referenced_audio-2929340.wav'),
},
},
}
);
if (isLoading) {
return <ActivityIndicator />;
} else if (error != null) {
return (
<View style={styles.safeAreaViewContainer}>
<Text>Error loading Rive file: {error?.message}</Text>
</View>
);
}
return (
<RiveView
file={riveFile}
fit={Fit.Contain}
style={styles.rive}
stateMachineName="State Machine 1"
artboardName="Artboard"
/>
);
}
参见此示例了解更多信息。