# ohos_rive **Repository Path**: zhang-xixi-1/ohos_rive ## Basic Information - **Project Name**: ohos_rive - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 29 - **Created**: 2025-10-29 - **Last Updated**: 2025-12-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OHOS Rive Project 本项目包含两个部分: 1. **后端编译包** - 用于编译 Rive 引擎的原生库 2. **前端集成** - HarmonyOS ArkTS 应用的 Rive 集成指南 ## 第一部分: 后端编译指南 ### 下载代码 #### 内部开发(使用dev分支) ```bash git clone --recursive -b dev git@gitee.com:yp9522/ohos_rive.git ``` #### 客户联调(使用master分支) ```bash git clone --recursive -b master git@gitee.com:yp9522/ohos_rive.git ``` > 说明:dev分支包含最新开发代码,用于内部团队开发和测试;master分支包含稳定版本,用于客户联调和正式使用。 ### 编译前准备 #### 1. 配置 OHOS_NDK 环境变量 - 确保已安装 OpenHarmony SDK - 找到 SDK 中的 native 目录,通常路径类似于 `D:\OpenHarmonySDK\api_version\native` - 配置环境变量: 1. 在「系统变量」中点击「新建」 2. 变量名输入 `OHOS_NDK` 3. 变量值输入 OpenHarmony SDK 中 native 目录的完整路径 4. 点击「确定」保存设置 - 验证环境变量: 1. 打开新的命令提示符窗口 2. 输入 `echo %OHOS_NDK%` 验证环境变量是否正确设置 > 注意:如果您的 OpenHarmony SDK 安装在非默认路径,请确保使用正确的路径。 完成以上步骤后,您就可以开始编译 OHOS Rive 项目了。 #### 2. 安装 MSYS2 并配置环境 - 下载并安装 MSYS2(推荐安装到默认路径 `C:\msys64`) - 下载地址:https://www.msys2.org/ - 安装完成后,运行 MSYS2 UCRT64 终端 - 在 MSYS2 终端中执行以下命令安装所需工具: ```bash pacman -S mingw-w64-x86_64-ninja mingw-w64-x86_64-premake mingw-w64-x86_64-python-ply make --noconfirm ``` - 配置环境变量: 1. 找到系统变量中的 `Path` 变量并点击「编辑」 2. 添加以下两个路径(假设 MSYS2 安装在默认路径): - `C:\msys64\mingw64\bin` - `C:\msys64\usr\bin` 3. 点击「确定」保存设置 - 验证环境变量: 1. 打开新的命令提示符窗口 2. 输入 `premake5 --version` 和 `make --version` 验证工具是否可用 ## 第二部分: 前端 HarmonyOS Rive 动画库 ### 简介 本项目是Rive动画引擎的HarmonyOS移植版本,提供了在鸿蒙应用中使用Rive矢量动画的能力。通过该库,开发者可以轻松地在HarmonyOS应用中集成和控制高质量的交互式矢量动画,与Android和iOS版本保持一致的功能和体验。 ### 什么是Rive? Rive是一个现代化的矢量动画工具和运行时引擎,允许设计师和开发者创建和交付交互式矢量动画。相比传统的动画方案,Rive动画具有以下特点: - 文件体积小(通常比GIF和Lottie小很多) - 运行时渲染,保持高清晰度 - 支持复杂的交互式动画 - 支持运行时状态控制和参数调整 - 支持多种平台(Web, iOS, Android, 现在包括HarmonyOS) ### 安装集成 #### 前提条件 - DevEco Studio 5.1.1 Release 或更高版本 - HarmonyOS SDK API 12或更高版本 #### 集成方法 1. 将库模块`library`添加到你的项目中作为依赖 在项目的`build-profile.json5`文件中添加: ```json "dependencies": { "library": { "bundleName": "com.example.library", "version": "1.0.0" } } ``` 2. 在入口能力的`onCreate`中调用初始化函数 ```typescript // EntryAbility.ets import { initializeRive } from 'library'; onCreate() { // 初始化Rive try { initializeRive(); } catch (error) { console.error("Failed to initialize Rive library:", error); } } ``` ### 基本用法 #### 在页面中使用Rive动画 ```typescript import { RiveAnimationView } from 'library'; @Entry @Component struct AnimationPage { build() { Column() { // 简单展示一个Rive动画 RiveAnimationView({ riveResource: '@rawfile/example_animation.riv', // 位于rawfile目录下的Rive文件 riveFit: 'cover', // 适配方式 riveAutoPlay: false // 自动播放,默认true }) .width('100%') .height('30%') } } } ``` ### 高级用法 #### Artboard切换 ```typescript RiveAnimationView({ riveResource: '@rawfile/multi_artboard.riv', riveArtboard: 'Circle', // 指定要显示的Artboard }) ``` #### 动画事件控制 ```typescript @State riveView: RiveAnimationView | null = null; RiveAnimationView({ riveResource: '@rawfile/button.riv', riveAutoPlay: false, onReady: (view) => { this.riveView = view; } }) // 控制动画的播放、暂停和重置 this.riveView?.play() // 播放动画 this.riveView?.pause() // 暂停动画 this.riveView?.reset() // 重置动画 ``` #### 加载网络资源 ##### 方案1:直接使用URL ```typescript RiveAnimationView({ riveUrl: 'https://cdn.rive.app/animations/vehicles.riv', }) .width('100%') .height('100%') ``` ##### 方案2:使用HTTP请求加载 ```typescript // 在module.json5中添加网络权限 "requestPermissions": [{ "name": "ohos.permission.INTERNET", }], // 页面代码 private riveUrl = "https://cdn.rive.app/animations/juice_v7.riv" @State riveView: RiveAnimationView | null = null; RiveAnimationView({ onReady: (view) => { this.riveView = view } }) .width('100%') .height('100%') const httpRequest = http.createHttp(); httpRequest.request(this.riveUrl, { method: http.RequestMethod.GET, connectTimeout: 30000, readTimeout: 30000 }).then((response) => { if (response.responseCode === 200) { const arrayBuffer = response.result as ArrayBuffer; this.riveView?.setRiveBytes(arrayBuffer) } else { console.error(`HttpPage: Network request failed: ${response.responseCode}`); } }).catch((error: Error) => { console.error(`HttpPage: Network request error: ${error}`); }).finally(() => { httpRequest.destroy(); }); ``` ### 目录结构 ``` ohos_rive/ ├── entry/ # 入口模块 │ ├── src/main/ # 主要源代码 │ │ ├── ets/ # ArkTS代码 │ │ │ ├── common/ # 公共组件 │ │ │ ├── entryability/ # 入口能力 │ │ │ └── pages/ # 样例页面 │ │ └── resources/ # 资源文件 │ │ └── rawfile/ # Rive动画文件(.riv) ├── library/ # Rive库模块 │ ├── src/main/ │ │ ├── ets/ # ArkTS文件 │ │ ├── cpp/ # C++原生代码 │ │ └── resources/ # 库资源文件 └── README.md # 项目说明 ``` ### API接口说明 #### RiveAnimationView `RiveAnimationView`是鸿蒙版Rive的主要组件,用于在页面中展示和控制Rive动画。 ##### 属性 | 属性名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `riveResource` | string | 否 | 本地Rive资源路径(与`riveUrl`二选一) | | `riveUrl` | string | 否 | Rive资源的URL(与`riveResource`二选一) | | `riveLoop` | number | 否 | 动画播放模式 | | `rendererType` | RendererType | 否 | 渲染器类型 | | `riveArtboard` | string | 否 | 指定Artboard名称,默认使用第一个 | | `riveStateMachine` | string | 否 | 指定状态机名称 | | `riveAnimation` | string | 否 | 指定动画名称 | | `riveFit` | string | 否 | 适配方式,可选值: 'contain', 'cover', 'fill', 'fitWidth', 'fitHeight', 'none', 'scaleDown' | | `alignmentIndex` | number | 否 | 对齐方式 | | `riveAutoPlay` | boolean | 否 | 是否自动播放动画,默认为true | | `onReady` | (view: RiveAnimationView) => void | 否 | 动画准备就绪后的回调 | ##### 方法 | 方法 | 说明 | | --- | --- | | `play(animationName?: string, loop?: Loop, direction?: Direction, isStateMachine?: boolean, settleInitialState?: boolean)` | 播放动画,可选指定动画名称。返回 void。 | | `pause()` | 暂停动画。返回 void。 | | `stop()` | 停止动画。返回 void。 | | `reset()` | 重置动画到初始状态。返回 void。 | | `isPlaying()` | 检查动画是否正在播放。返回 boolean。 | | `setRiveFile(file: File, artboardName?: string, animationName?: string, stateMachineName?: string, autoplay?: boolean, autoBind?: boolean, fit?: Fit, alignment?: Alignment, loop?: Loop)` | 设置Rive文件对象。返回 void。 | | `setRiveBytes(bytes: ArrayBuffer, artboardName?: string, animationName?: string, stateMachineName?: string, autoplay?: boolean, autoBind?: boolean, fit?: Fit, alignment?: Alignment, loop?: Loop)` | 从字节数组加载Rive动画。返回 void。 | | `setNumberState(stateMachineName: string, inputName: string, value: number)` | 设置数字状态。返回 void。 | | `pauseAnimation(animationName: string, isStateMachine?: boolean)` | 暂停指定名称的动画。返回 void。 | | `stopAnimation(animationName: string, isStateMachine?: boolean)` | 停止指定名称的动画。返回 void。 | | `setBooleanState(stateMachineName: string, inputName: string, value: boolean)` | 设置布尔状态。返回 void。 | | `setBooleanStateAtPath(inputName: string, value: boolean, path: string)` | 在路径上设置布尔状态。返回 void。 | | `setTextRunValue(textRunName: string, textValue: string, path?: string)` | 设置文本运行值。返回 void。 | | `setVolume(value: number)` | 设置音量。返回 void。 | | `setRiveResource(resId: number\string, artboardName?: string, animationName?: string, stateMachineName?: string, autoplay?: boolean, autoBind?: boolean, fit?: Fit, alignment?: Alignment, loop?: Loop)` | 设置Rive资源。返回 void。 | | `setArtboardName(name: string\null)` | 设置当前画板名称。返回 void。 | | `setAutoplay(value: boolean)` | 设置自动播放状态。返回 void。 | | `getFit()` | 获取Fit。返回 Fit。 | | `setFit(value: Fit)` | 设置Fit。返回 void。 | | `setAlignment(value: Alignment)` | 设置Alignment。返回 void。 | | `getLayoutScaleFactor()` | 获取布局缩放因子。返回 number\null。 | | `setLayoutScaleFactor(value: number\null)` | 设置布局缩放因子。返回 void。 | | `registerListener(listener: RiveFileControllerListener)` | 注册监听器。返回 void。 | | `unregisterListener(listener: RiveFileControllerListener)` | 取消注册监听器。返回 void。 | | `addEventListener(listener: RiveEventListener)` | 添加事件监听器。返回 void。 | | `removeEventListener(listener: RiveEventListener)` | 移除事件监听器。返回 void。 | | `getRenderer()` | 获取渲染器对象。返回 Renderer\null。 | | `getArtboard()` | 获取当前活动的画板对象。返回 Artboard\null。 | | `Alignment.fromIndex(index: number)` | 根据输入得到Alignment枚举值。返回 Alignment。 | | `Fit.fromString(fitString: string)` | 根据输入得到Fit枚举值。返回 Fit。 | | `RiveManager.getInstance()` | 获取RiveManager实例。返回 RiveManager。 | | `RiveManager.init(context: Context, defaultRenderer?: RendererType)` | 初始化RiveManager。返回 void。 | | `RiveManager.setFallbackFont(context: Context, byteArray?: Uint8Array, opts?: FontOpts)` | 为Rive runtime设置备用字体。返回 boolean。 | | `RiveRenderImage.fromEncoded(encodedBytes: Uint8Array, rendererType?: RendererType, premultiplied?: boolean)` | 通过解码encodedBytes创建RiveRenderImage。返回 RiveRenderImage。 | | `RiveRenderImage.fromARGBInts(pixels: Uint32Array, width: number, height: number, rendererType?: RendererType, premultiplied?: boolean)` | 通过ARGB创建RiveRenderImage。返回 RiveRenderImage。 | | `RiveRenderImage.fromRGBABytes(pixelBytes: Uint8Array, width: number, height: number, rendererType?: RendererType, premultiplied?: boolean)` | 通过RGBA创建RiveRenderImage。返回 RiveRenderImage。 | | `artboardByName(name: string)` | 在File中获取名为name的画板。返回 Artboard。 | | `animationIndex(index: number)` | 在Artboard中根据index获取动画。返回 LinearAnimationInstance。 | | `restoreControllerState(state: ControllerState)` | 恢复控制器状态。返回 void。 | | `saveControllerState()` | 保存控制器状态。返回 ControllerState\null。 | | `release()` | 减少引用计数。返回 number。 | | `RiveFont.make(bytes: Uint8Array, rendererType?: RendererType)` | 创建RiveFont。返回 RiveFont。 | #### initializeRive Rive库的初始化函数,应在应用启动时调用一次。 ```typescript import { initializeRive } from 'library'; // 在应用启动时初始化 initializeRive(); ``` ### 注意事项 1. 确保将Rive动画文件(.riv)放在项目的`resources/rawfile`目录下 2. 大型动画文件可能会影响性能,建议优化动画大小 3. 动画状态机名称和参数名称必须与Rive文件中定义的完全一致(区分大小写) 4. 初始化Rive库只需在应用启动时执行一次 ## 关于混淆 - 代码混淆,请查看[代码混淆简介](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/arkts-utils/source-obfuscation.md) - 如果希望rive库在代码混淆过程中不会被混淆,需要在混淆规则配置文件obfuscation-rules.txt中添加相应的排除规则: ``` -keep ./oh_modules/@ohos/rive ``` ## 开源协议 本项目基于 [Apache License 2.0](https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/blob/master/ohos_rive/LICENSE) ,请自由地享受和参与开源。 ## 贡献代码 使用过程中发现任何问题都可以提 [Issue](https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/issues) 给组件,当然,也非常欢迎发 [PR](https://gitcode.com/openharmony-tpc/openharmony_tpc_samples/pulls)共建。