用途
Rive Generator 用于以编程方式生成 Rive 动画。当用户希望用代码创建 Rive 动画、提到“生成 .riv 文件”或“创建 Rive 动画”时,可触发该技能。它通过 TypeScript 构建 .riv 二进制文件,适合需要自动化或脚本化产出 Rive 资源的场景。
安装
先安装 npm 包:
npm install @stevysmith/rive-generator
主要能力
该技能围绕 RiveFile 类提供构建 .riv 文件的 API,主要方法包括:
- addArtboard(options):添加画板(画布)
- addNode(parent, options):添加变换组
- addShape(parent, options):添加形状容器
- addEllipse(shape, options):添加椭圆/圆
- addRectangle(shape, options):添加矩形
- addPointsPath(shape, options):添加自定义矢量路径
- addVertex(path, options):添加直线顶点
- addFill(shape, options):添加填充
- addStroke(shape, options):添加描边
- addSolidColor(paint, color):设置纯色
- addLinearGradient(paint, options):添加线性渐变
- addRadialGradient(paint, options):添加径向渐变
- addGradientStop(gradient, options):添加渐变色标
- addLinearAnimation(artboard, options):添加动画
- addKeyedObject(animation, targetId):将动画链接到对象
- addKeyedProperty(keyedObject, propertyKey):指定要动画的属性
- addKeyFrameDouble(keyedProperty, options):添加关键帧
- export():返回 .riv 二进制的 Uint8Array
颜色工具包括 hex 与 rgba,例如 hex('#ff0000')、rgba(255, 0, 0, 255)。PropertyKey 提供 x、y、scaleX、scaleY、rotation(弧度)等可动画属性。
使用方式
快速开始示例:
import { writeFileSync } from 'fs';
import { RiveFile, hex } from '@stevysmith/rive-generator';
const riv = new RiveFile();
// Create artboard
const artboard = riv.addArtboard({
name: 'My Animation',
width: 400,
height: 400,
});
// Add shape at center
const shape = riv.addShape(artboard, {
name: 'MyShape',
x: 200,
y: 200,
});
// Add path (ellipse or rectangle)
riv.addEllipse(shape, { width: 100, height: 100 });
// Add fill with color
const fill = riv.addFill(shape);
riv.addSolidColor(fill, hex('#3498db'));
// Export
writeFileSync('my-animation.riv', riv.export());
运行方式:
# With TypeScript (Node 22+)
node --experimental-strip-types generate.ts
# Or compile first
npx tsc generate.ts && node generate.js
动画示例:
import { RiveFile, hex, PropertyKey } from '@stevysmith/rive-generator';
import { writeFileSync } from 'fs';
const riv = new RiveFile();
const artboard = riv.addArtboard({ name: 'Pulse', width: 200, height: 200 });
const shape = riv.addShape(artboard, { name: 'Circle', x: 100, y: 100 });
riv.addEllipse(shape, { width: 50, height: 50 });
const fill = riv.addFill(shape);
riv.addSolidColor(fill, hex('#e74c3c'));
const anim = riv.addLinearAnimation(artboard, {
name: 'pulse',
fps: 60,
duration: 60,
loop: 'pingPong',
});
const keyed = riv.addKeyedObject(anim, shape);
const scaleX = riv.addKeyedProperty(keyed, PropertyKey.scaleX);
riv.addKeyFrameDouble(scaleX, { frame: 0, value: 1.0, interpolation: 'cubic' });
riv.addKeyFrameDouble(scaleX, { frame: 30, value: 1.2, interpolation: 'cubic' });
riv.addKeyFrameDouble(scaleX, { frame: 60, value: 1.0, interpolation: 'cubic' });
const scaleY = riv.addKeyedProperty(keyed, PropertyKey.scaleY);
riv.addKeyFrameDouble(scaleY, { frame: 0, value: 1.0, interpolation: 'cubic' });
riv.addKeyFrameDouble(scaleY, { frame: 30, value: 1.2, interpolation: 'cubic' });
riv.addKeyFrameDouble(scaleY, { frame: 60, value: 1.0, interpolation: 'cubic' });
writeFileSync('pulse.riv', riv.export());
适用场景
- 需要用代码批量或自动化生成 Rive 动画资源。
- 需要在构建流程中程序化产出 .riv 文件。
- 需要以脚本方式创建包含形状、填充、渐变与关键帧动画的 Rive 文件。
限制与约束
- 使用单一 Node 容器:所有形状必须是 Artboard 下同一个 Node 的子级。
- 渐变形状必须放在最后:带渐变的形状应在纯色形状之后添加。
- 不要使用 CubicVertex:仅使用 addVertex(),用大量直线顶点近似曲线。
- 不要使用 cornerRadius:使用普通矩形或 PointsPath 实现圆角。
- 首个形状位置存在 bug:需先添加一个极小的透明占位形状,例如:
const dummy = riv.addShape(container, { name: 'Dummy', x: 0, y: 0 });
riv.addRectangle(dummy, { width: 1, height: 1 });
const dummyFill = riv.addFill(dummy);
riv.addSolidColor(dummyFill, hex('#00000000'));
查看生成的 .riv 文件
- Rive Editor:导入以查看/编辑。
- rive.app/preview:快速在线预览。
- 在应用中使用 @rive-app/canvas 或 @rive-app/react-canvas。