数据绑定
数据绑定允许你将代码与 Rive 编辑器中绑定的元素连接起来。通过使用 View Model,你可以在编辑器中定义可绑定属性,然后在运行时通过 React Hook 读取和写入这些属性的值。
View Model
使用 useViewModel Hook 获取 View Model 的引用。你需要传入从 useRive 获取的 rive 对象。
import { useRive, useViewModel } from '@rive-app/react-webgl2';
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
// ... 其他选项
});
// 方式 1:获取画板的默认 ViewModel
const defaultViewModel = useViewModel(rive);
// 方式 2:显式获取默认 ViewModel
const defaultViewModelExplicit = useViewModel(rive, { useDefault: true });
// 方式 3:按名称获取 ViewModel
const namedViewModel = useViewModel(rive, { name: 'MyViewModelName' });
View Model 实例
使用 useViewModelInstance Hook 从 useViewModel Hook 返回的 View Model 创建 View Model 实例。
import { useRive, useViewModel, useViewModelInstance } from '@rive-app/react-webgl2';
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
artboard: 'MyArtboard',
stateMachine: 'MyStateMachine',
// ... 其他选项
});
const viewModel = useViewModel(rive, { name: 'MyViewModelName' });
// 或:const viewModel = useViewModel(rive); // 默认 VM
// 获取默认实例,不绑定
const defaultUnbound = useViewModelInstance(viewModel, { useDefault: true });
// 获取命名实例,不绑定
const namedUnbound = useViewModelInstance(viewModel, { name: 'MyInstanceName' });
// 创建新的空白实例,不绑定
const newUnbound = useViewModelInstance(viewModel, { useNew: true });
你也可以通过向 useViewModelInstance Hook 传入 rive 对象,将 View Model 实例直接绑定到 Rive 实例。
import { useRive, useViewModel, useViewModelInstance } from '@rive-app/react-webgl2';
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
artboard: 'MyArtboard',
stateMachine: 'MyStateMachine',
autoBind: false, // 禁用自动绑定,以便稍后手动绑定
// ... 其他选项
});
const viewModel = useViewModel(rive, { name: 'MyViewModelName' });
// 获取默认实例(隐式)并绑定
const defaultBound = useViewModelInstance(viewModel, { rive });
// 获取命名实例并绑定
const namedBound = useViewModelInstance(viewModel, { name: 'MyInstanceName', rive });
// 创建新的空白实例并绑定
const newBound = useViewModelInstance(viewModel, { useNew: true, rive });
如果你在 useRive 中设置了 autoBind: true,一旦 Rive 加载完成,你可以直接通过 rive.viewModelInstance 访问自动绑定的默认实例,无需使用 useViewModel 或 useViewModelInstance。
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
artboard: 'MyArtboard',
stateMachine: 'MyStateMachine',
autoBind: true,
});
// 加载完成后,实例即可用:
const boundInstance = rive?.viewModelInstance;
绑定
对于 React,无需额外步骤即可将 View Model 实例绑定到 Rive 组件。向 useViewModelInstance 传入 rive 对象会自动处理绑定——该 Hook 会设置实例并调度一次 bind()。
先设置所有实例,再调用一次 bind()。 设置实例的开销很小;bind() 的开销要大得多,每次按实例调用都会重复支付该 开销。批量处理在初始化时最为重要,尤其是在有许多绑定或深层嵌套画板的图形上。
View Model Hook 已为你处理了这一点:在同一渲染提交中解析的 Hook 共享一次合并的 bind()。当手动绑定时——例如在 onRiveReady 中——使用 setViewModelInstance() / setGlobalViewModelInstance() 逐个设置实例,然后用一次 bind() 统一应用。
首帧前绑定(Binding before the first frame)
View Model Hook 在 Rive 加载后运行,这意味着即使设置了 autoplay: false,第一帧也会在它们绑定之前已经推进和渲染。如果想在首次渲染前设置数据,请在 useRive 的 onRiveReady 回调中进行数据绑定设置。它在文件加载后、状态机推进之前同步接收 Rive 实例,因此你可以设置实例和属性值,让第一帧就使用这些值进行渲染。
import { useRive, ViewModel, ViewModelInstance } from '@rive-app/react-webgl2';
const { RiveComponent } = useRive({
src: 'your_file.riv',
stateMachines: 'MyStateMachine',
autoplay: true,
autoBind: false, // 自行在首帧前设置实例
onRiveReady: (rive) => {
const mainVM = rive.viewModelByName('MyViewModel') as ViewModel;
const instance = mainVM.defaultInstance() as ViewModelInstance;
instance.string('username').value = 'Rive';
rive.setViewModelInstance(instance);
rive.bind(); // 应用已设置的实例
},
});
对于任何预渲染数据绑定工作,请使用 onRiveReady 而非 onLoad。你可以从 Rive 实例访问的所有内容——包括全局视图模型——都可以在其中准备。
自动绑定
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
artboard: 'MyArtboard',
stateMachine: 'MyStateMachine',
autoBind: true, // 启用自动绑定
// ... 其他选项
});
// 加载完成后,主视图模型实例可用:
const boundInstance = rive?.viewModelInstance;
全局视图模型(Global View Models)
在编辑器中标记为全局的视图模型在整个文件中共享,而不是由单个画板拥有。文件为每个全局视图模型持有一个按名称寻址的槽位,因此每个画板和状态机都读取同一个实例——适用于主题、会话或设置等应用级状态。
使用 useGlobalViewModelInstance Hook 来解析实例并将其注册到全局名称下。它接收视图模型(来自 useViewModel)、全局槽位名称以及与 useViewModelInstance 相同类型的选择器参数:
import {
useRive,
useViewModel,
useGlobalViewModelInstance,
useViewModelInstanceColor,
} from '@rive-app/react-webgl2';
const { rive, RiveComponent } = useRive({
src: 'your_file.riv',
stateMachines: 'State Machine 1',
autoBind: false,
});
const themeViewModel = useViewModel(rive, { name: 'Theme' });
// 解析默认实例并将其注册为 "Theme" 全局
const themeInstance = useGlobalViewModelInstance(themeViewModel, 'Theme', { rive });
// 属性 Hook 的用法与主实例完全相同
const { value: bgColor, setValue: setBgColor } = useViewModelInstanceColor(
'backgroundColor',
themeInstance
);
第三个参数选择要解析的实例:
{ rive }— 视图模型的默认实例(隐式默认){ instanceName: 'Dark', rive }— 具有该名称的实例{ useNew: true, rive }— 新的空白实例{ instance: myInstance, rive }— 你自己创建的实例
传入 rive 会将实例注册为全局并调度绑定。省略它则只解析实例而不绑定。
你只需要为想要读取或写入属性的全局视图模型使用 Hook。绑定会用文件中该视图模型的默认实例填充你未设置的每个槽位——包括主视图模型实例。
要通过代码列出文件的全局视图模型或读取当前占用某个槽位的实例,直接通过 rive 实例操作:
const names = rive?.globalViewModelNames(); // 例如 ["Theme", "Session"]
const themeInstance = rive?.globalViewModelInstance('Theme'); // ViewModelInstance | null
globalViewModelInstance() 不会创建实例——在 Hook 设置、在 onRiveReady 中设置或通过 autoBind: true 创建之前,它返回 null。