@hxa-rn/art
v1.0.0
Published
React Native module that allows you to draw vector graphics
Readme
react-native-art
本项目基于 react-native-community/react-native-art 开发。交付库名与 GitCode 仓库名保持一致,均为 react-native-art。如果在使用过程中有任何问题,可以在 GitCode 提交 Issue,会及时跟进。
项目介绍
react-native-art 是 React Native 生态的矢量绘制库。本项目为其 HarmonyOS(RNOH / Fabric 架构)适配版本,npm 适配包名 @hxa-rn/art(1.0.0),业务导入名 @react-native-community/art,鸿蒙侧 ohpm 包名 @oh-rn/art,适配基线为上游 v1.2.0。
对外提供以下能力:
- 矢量画布:
Surface是唯一原生视图,承载整棵 ART 虚拟节点树。 - 分组与变换:
Group支持平移、缩放、旋转、透明度下传与矩形裁剪。 - 路径图元:
Shape支持Path/ 字符串路径、填充、描边、线帽、线连接、虚线、不透明度与阴影。 - 文本图元:
Text支持字体、对齐、填充、描边与多行文本绘制。 - 画刷与矩阵:
LinearGradient/RadialGradient/Pattern/Transform与上游公开 API 对齐。
本库按“虚拟节点树 + 单画布”模型适配:ARTSurfaceView 持有 ArkUI Canvas 与 CanvasRenderingContext2D,递归读取 Group / Shape / Text 的 descriptor props 后统一绘制。Group / Shape / Text 在鸿蒙侧不创建独立布局盒,仅作为 Fabric 虚拟节点参与绘制。
集成指南
以下步骤用于将本库接入已有的 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。
1. 安装适配包
在宿主应用根目录从 npmjs 安装精确版本:
npm install @hxa-rn/[email protected] --legacy-peer-deps --registry=https://registry.npmjs.org/包内包含 JS 产物、类型声明和与本分支源码同步构建的 harmony/art.har。鸿蒙模块名仍为 @oh-rn/art。
2. 配置 Metro 并导入
适配包的 package.json 已声明 harmony.alias: "@react-native-community/art"。宿主应用的 metro.config.js 需要合并 RNOH Metro 配置,才能使用该别名:
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');
module.exports = mergeConfig(
getDefaultConfig(__dirname),
createHarmonyMetroConfig({
reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
}),
);已有 Metro 配置时合并保留原有设置。业务代码继续使用原包名:
import {Surface, Group, Shape, Text, Path} from '@react-native-community/art';3. 注册鸿蒙原生模块
本库声明了 Autolinking 元数据:CMake 目标为 art,ohpm 包名为 @oh-rn/art,C++ / ETS Package 类名均为 ArtPackage。宿主已启用 RNOH Autolinking 时,按宿主的自动链接流程生成依赖和注册文件,再同步、构建;确认 CMake、C++ 和 ETS 三处都包含本库后,无需重复手动注册。
Autolinking 不可用时,按以下步骤手动接入。下列路径以 RN 应用根目录为起点,保留宿主已有的 RNOH 配置和其他 Package。
① 添加 HAR 依赖
如果宿主通过 npm 提供 RNOH HAR,在 harmony/oh-package.json5 合并以下覆盖项,使本库与宿主使用同一份 RNOH(本仓两个示例已配置):
"overrides": {
"@rnoh/react-native-openharmony": "file:../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har"
}在 harmony/entry/oh-package.json5 的 dependencies 中追加:
"@oh-rn/art": "file:../../node_modules/@hxa-rn/art/harmony/art.har"然后在 harmony/entry 目录执行 ohpm install,并在 DevEco Studio 中同步工程。
② 链接 C++ 库
在 harmony/entry/src/main/cpp/CMakeLists.txt 中加入子目录,并在已有 rnoh_app 目标创建之后链接:
# OH_MODULE_DIR 指向 harmony/entry/oh_modules。
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
add_subdirectory("${OH_MODULE_DIR}/@oh-rn/art/src/main/cpp" ./art)
# 放在已有 add_library(rnoh_app ...) 之后。
target_link_libraries(rnoh_app PUBLIC art)③ 注册 C++ Package
在 harmony/entry/src/main/cpp/PackageProvider.cpp 添加头文件,并在已有的 getPackages 返回集合中加入本库:
#include "ArtPackage.h"
// 加入已有 Package 集合,只注册一次:
std::make_shared<rnoh::ArtPackage>(ctx)例如使用本仓库宿主模板时,将该项加入 ManualLinkingPackage 初始化列表,保留原有合并逻辑。
④ 注册 ETS Package
在 harmony/entry/src/main/ets/RNPackagesFactory.ets 中增加默认导入,并向已有 createRNPackages 返回数组追加实例:
import ArtPackage from '@oh-rn/art';
// 加入 createRNPackages(ctx) 的返回数组,只注册一次:
new ArtPackage(ctx)注意这里是 HAR 的默认导出,不是 @oh-rn/art/ts 的具名导出。宿主 RNApp 的 rnInstanceConfig 必须使用该 createRNPackages,并启用 enableCAPIArchitecture: true。ArtPackage 提供 ARTSurfaceView 的组件构建器,Group / Shape / Text 由虚拟节点承载,无需逐个注册 ArkUI 可视组件。
完成后重新生成宿主 JS Bundle、构建并安装 HAP;仅刷新 JS 无法加载新加入的原生模块。本库绘制能力无需额外系统权限。
使用说明
基础绘制
import React from 'react';
import {Surface, Group, Shape, Text, Path} from '@react-native-community/art';
export default function ArtView() {
const rect = new Path()
.moveTo(0, 0)
.lineTo(90, 0)
.lineTo(90, 60)
.lineTo(0, 60)
.close();
return (
<Surface width={160} height={140}>
<Shape d={rect} x={10} y={20} fill="#3478F6" />
<Shape d={rect} x={30} y={40} stroke="#E0432B" strokeWidth={4} />
<Group x={20} y={20} opacity={0.6}>
<Text x={10} y={90} font={{fontSize: 20, fontFamily: 'sans-serif'}} fill="#111">
ART
</Text>
</Group>
</Surface>
);
}渐变与图案
import {LinearGradient, Shape, Path} from '@react-native-community/art';
const path = new Path().moveTo(20, 20).lineTo(120, 20).lineTo(80, 100).close();
const gradient = new LinearGradient({0: '#3478F6', 1: '#111111'}, 0, 0, 120, 100);
<Shape d={path} fill={gradient} />;Pattern 依赖鸿蒙适配层的 patternSrc 旁路传递图片 URI。黑盒或真机验证前,应确认当前 JS bundle 已包含图案资源。
接口文档
公开接口 = src/index.js 的 10 个根导出符号。
| 符号 | 类别 | 说明 |
|---|---|---|
| Surface | 组件 | 唯一原生视图,承载整棵矢量树;核心 props 为 width / height / style |
| Group | 虚拟节点 | 分组容器,支持变换、透明度下传与裁剪 |
| Shape | 虚拟节点 | 路径图元,支持 d、填充、描边、线帽、线连接、虚线、阴影 |
| Text | 虚拟节点 | 文本图元,支持字体、对齐、填充、描边和多行文本 |
| Path | 类 | 可序列化路径构造器,支持 moveTo / lineTo / curveTo / arc / close |
| ClippingRectangle | 虚拟节点 | 矩形裁剪节点,最终映射为 ARTGroup.clipping 契约 |
| LinearGradient | 类 | 线性渐变画刷 |
| RadialGradient | 类 | 径向渐变画刷 |
| Pattern | 类 | 图案画刷 |
| Transform | 类 | 矩阵变换工具,来自第三方 art 包转再导出 |
节点通用 props 包括:opacity / originX / originY / scaleX / scaleY / scale / x / y / visible / title / shadowOpacity / shadowColor / shadowRadius / shadowOffset。
可绘制 props 包括:fill / stroke / strokeCap / strokeDash / strokeJoin / strokeWidth。
快速验证(运行 Example)
前置条件
- Node.js >= 20(本库自身要求 >= 18,
example/package.json要求 >= 20)。 - 示例使用 React Native
0.72.5、React18.2.0、RNOH0.72.143。 - DevEco Studio 及可支持示例工程的 HarmonyOS SDK:当前
example/harmony/build-profile.json5的targetSdkVersion为6.1.1(24),compatibleSdkVersion为5.1.0(18)。 - 可连接的兼容设备,并在 DevEco Studio 中配置应用签名。
运行步骤
1. 克隆仓库
git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-art.git
cd react-native-art以下步骤使用 example 展示工程;example_auto 的依赖与构建输出独立,不要混用。Windows 建议使用较短目录,避免 RNOH 原生构建中间路径过长。
2. 从 npmjs 安装 Example 依赖
cd example
npm install --legacy-peer-deps --registry=https://registry.npmjs.org/example_auto 使用同样步骤。两个示例均精确依赖 @hxa-rn/[email protected];无需在仓根执行 npm pack。
确认 node_modules/@hxa-rn/art/harmony/art.har 存在。
3. 生成 JS Bundle
npm run dev确认产物为 example/harmony/entry/src/main/resources/rawfile/bundle.harmony.js。
4. 同步鸿蒙工程
用 DevEco Studio 打开 example/harmony,等待依赖同步完成。命令行方式在 example/harmony 执行 ohpm install --all。
示例已提交 HAR 依赖、CMake 链接、C++ 和 ETS Package 注册文件,无需重复手动注册。当前 example/harmony/hvigorfile.ts 中 autolinking: null,使用的是已提交的注册结果,不是每次构建重新生成。
5. 编译并运行 HAP
命令行构建在 example/harmony 执行:
hvigorw --mode module -p module=entry@default -p product=default -p buildMode=release assembleHap --no-daemonWindows 使用 DevEco 的 hvigorw.bat;hvigor 步骤使用 DevEco 自带 Node,npm 安装与 Bundle 步骤使用 Node >= 20。JAVA_HOME 指向 DevEco 的 jbr 并将其 bin 加入 PATH,DEVECO_SDK_HOME 指向 DevEco 的 sdk。
构建输出位于 harmony/entry/build/default/outputs/default/。需要装机时,在 DevEco Studio 中自行配置签名、选择设备并点击运行。JS 代码改动后重新执行 npm run dev 并重新构建安装,确保设备使用最新 Bundle。
常见问题
- 无法解析
@react-native-community/art:检查适配包是否安装,以及 Metro 是否合并createHarmonyMetroConfig;修改后重启打包进程。 - 找不到
art.har:检查是否已安装@hxa-rn/art,并核对node_modules/@hxa-rn/art/harmony/art.har路径。 ArtPackage或art链接失败:检查 ohpm 安装结果及 CMake、C++、ETS 注册是否齐全,避免手动注册和自动链接重复。- 画布空白或原生组件未注册:检查当前 HAP 是否包含新原生依赖,
createRNPackages是否传入RNApp,以及设备是否加载了最新 Bundle。 - Ninja 的
.rsp文件创建失败:先查看完整构建日志;若为 Windows 路径过长,缩短工程路径并清理对应构建缓存后重建。
维护者重建 HAR
在仓根执行 npm install --legacy-peer-deps 生成 JS 与内部 spec 类型产物,执行 npm run check:types 校验公开类型声明。原生源码变动后,使用上述 DevEco 工具环境执行:
cd harmony
ohpm install --all
hvigorw --mode module -p module=art@default -p product=default -p buildMode=release assembleHar --no-daemon将 harmony/art/build/default/outputs/default/art.har 复制为 harmony/art.har,再回仓根执行 npm pack。npm pack 本身不会编译 HAR。
约束与限制
| 项 | 说明 |
|---|---|
| 上游基线 | 上游 react-native-community/react-native-art 已归档,本适配以 v1.2.0 为基线 |
| RN / RNOH 版本 | 对应 React Native 0.72.5,RNOH @react-native-oh/react-native-harmony 0.72.143;JS peer 依赖要求 react-native >= 0.72 |
| 鸿蒙 SDK 版本 | 示例工程 targetSdkVersion 为 6.1.1(24),compatibleSdkVersion 为 5.1.0(18),runtimeOS 为 HarmonyOS |
| 本次发布验证范围 | JS Bundle、原生 HAR 与示例 HAP 编译;未做本版本真机验证 |
| 设备类型 | HAR 声明支持 default / tablet / 2in1 |
| 绘制模型 | Surface 为唯一原生视图,其他 ART 节点为虚拟节点;不要逐节点声明式渲染 |
| 层叠顺序 | 按声明顺序绘制,后绘制节点覆盖先绘制节点 |
| 单位口径 | API 入参按 vp 验收,底层 Canvas 使用 PX 上下文并显式乘 density |
| 文本度量 | 行距按 fontSize * 1.2 近似,Text.path 下发但不沿路径排字 |
| 空路径 | 无 d 的 Shape 会跳过绘制,避免整棵树崩溃 |
| 低透明度 | opacity < 0.01 的节点跳过绘制,与上游最小可绘不透明度一致 |
| 权限 | HAR module.json5 的 requestPermissions 为空;本库本体及其三方依赖不声明任何系统权限 |
开源 License
本项目基于 MIT License 开源,与上游 react-native-community/react-native-art 协议一致。
问题反馈渠道
使用过程中发现任何问题,欢迎在 GitCode 提交 Issue,也欢迎提交 PR 参与共建。
