ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-svg(CAPI) — 矢量图形组件
Defs 组件用于定义可复用的元素,如渐变、遮罩、裁剪路径等。定义在 Defs 中的元素不会直接显示,只有被其他元素引用时才会生效。将渐变、遮罩等定义放在 Defs 组件内,并设置唯一的 id 属性。然后在需要使用的地方通过 url(#id) 语法引用。这种方式可以实现资源的复用,减少代码重复。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
📌 开发环境声明:本文基于 React Native 0.72.90 版本进行开发适配

🚀 一、开篇引言
react-native-svg 是 React Native 生态中最流行的 SVG 图形渲染库,提供了 Svg、Path、Circle、Rect、Line、Polygon 等丰富的图形组件,支持渐变、遮罩、变换等高级特性。CAPI 版本是针对 HarmonyOS 平台优化的高性能实现,充分利用底层图形能力,为鸿蒙应用提供流畅的矢量图形渲染体验。本文将带你深入了解如何在 HarmonyOS 平台上集成和使用这个强大的矢量图形组件库。
1.1 你将学到什么?
- ✅ react-native-svg CAPI 版本的核心组件与概念
- ✅ HarmonyOS 平台的完整集成流程
- ✅ 基础图形绘制与路径操作
- ✅ 渐变、遮罩等高级特性
- ✅ 实际应用场景的最佳实践
1.2为什么选择 react-native-svg CAPI 版本?
| 特点 | 说明 |
|---|---|
| 高性能渲染 | 基于 CAPI 底层实现,渲染效率更高 |
| 丰富组件 | 支持 20+ SVG 组件 |
| 跨平台一致 | iOS、Android、HarmonyOS 表现一致 |
| 完整特性 | 支持渐变、遮罩、变换、动画等 |
| 社区活跃 | 被广泛使用,文档完善 |
📦 二、库概览
2.1 基本信息
| 项目 | 内容 |
|---|---|
| 库名称 | @react-native-ohos/react-native-svg |
| 版本信息 | 15.0.2 (0.72) / 15.12.1 (0.77) |
| 官方仓库 | https://github.com/software-mansion/react-native-svg |
| 鸿蒙仓库 | https://atomgit.com/openharmony-sig/rntpc_react-native-svg |
| 开源协议 | MIT |
2.2 版本兼容性
| 三方库版本 | 支持RN版本 | 说明 |
|---|---|---|
| 15.0.2 | 0.72 | 支持 Autolink |
| 15.12.1 | 0.77 | 支持 Autolink |
2.3 核心能力矩阵
| 能力项 | 描述 | HarmonyOS 支持 |
|---|---|---|
| Svg | SVG 容器组件 | ✅ 完全支持 |
| Path | 路径绘制 | ✅ 完全支持 |
| Circle | 圆形 | ✅ 完全支持 |
| Rect | 矩形 | ✅ 完全支持 |
| Ellipse | 椭圆 | ✅ 完全支持 |
| Line | 直线 | ✅ 完全支持 |
| Polygon | 多边形 | ✅ 完全支持 |
| Polyline | 多段线 | ✅ 完全支持 |
| G | 分组容器 | ✅ 完全支持 |
| Defs | 定义容器 | ✅ 完全支持 |
| Use | 元素复用 | ✅ 完全支持 |
| Image | 图像元素 | ✅ 完全支持 |
| Text | 文本元素 | ✅ 完全支持 |
| LinearGradient | 线性渐变 | ✅ 完全支持 |
| RadialGradient | 径向渐变 | ✅ 完全支持 |
| Mask | 遮罩 | ✅ 完全支持 |
| ClipPath | 裁剪路径 | ✅ 完全支持 |
2.4 技术架构图
📖 三、安装与配置
3.1 安装依赖
在项目根目录执行以下命令:
# 0.72 版本
npm install @react-native-ohos/react-native-svg@15.0.2-rc.1
# 0.77 版本
npm install @react-native-ohos/react-native-svg
3.2 验证安装
安装完成后,检查 package.json 文件中是否包含以下依赖:
{
"dependencies": {
"react-native-svg": "^15.0.0",
"@react-native-ohos/react-native-svg": "^15.0.2-rc.1"
}
}
3.3 基本导入
import Svg, { Circle, Rect, Path, Line, G, Defs, LinearGradient, Stop } from 'react-native-svg';
🔧 四、原生配置
4.2 配置 oh-package.json5
要看自己是什么版本,你的不一定是0.72.90
打开项目根目录的 harmony/oh-package.json5,添加 overrides 配置:
{
"overrides": {
"@rnoh/react-native-openharmony": "0.72.90"
}
}
4.3 配置 entry/oh-package.json5
打开 harmony/entry/oh-package.json5,添加依赖:
{
"dependencies": {
"@react-native-ohos/react-native-svg": "file:../../node_modules/@react-native-ohos/react-native-svg/harmony/svg.har"
}
}
4.4 配置 CMakeLists.txt
打开 harmony/entry/src/main/cpp/CMakeLists.txt,添加以下内容:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-svg/src/main/cpp" ./svg)
# RNOH_END: manual_package_linking_1
# ... 其他配置 ...
# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_svg)
# RNOH_END: manual_package_linking_2
4.5 配置 PackageProvider.cpp
打开 harmony/entry/src/main/cpp/PackageProvider.cpp,添加 SVGPackage:
#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "SVGPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<RNOHGeneratedPackage>(ctx),
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<SVGPackage>(ctx),
};
}
4.6 配置 RNPackagesFactory.ts
打开 harmony/entry/src/main/ets/RNPackagesFactory.ts,添加 SvgPackage:
+ import { SvgPackage } from '@react-native-ohos/react-native-svg/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SamplePackage(ctx),
+ new SvgPackage(ctx),
];
}
4.7 同步依赖
在 DevEco Studio 中点击右上角的 sync 按钮,或在终端执行:
cd harmony/entry
ohpm install
4.8 字体配置(可选)
如果使用 Text 组件的 fontFamily 属性指定字体,需要额外配置字体文件:
步骤一: 复制字体文件到 entry/src/main/resources/rawfile/assets/fonts 目录
步骤二: 在 entry/src/main/ets/pages/Index.ets 中注册字体:
const fonts: Record<string, Resource> = {
"Noto Sans Pau Cin Hau": $rawfile("assets/fonts/Noto Sans Pau Cin Hau.ttf"),
"HarmonyOS_Sans_Condensed_Regular_Italic": $rawfile("assets/fonts/HarmonyOS_Sans_Condensed_Regular_Italic.ttf")
}
@Entry
@Component
struct Index {
build() {
Column() {
RNApp({
rnInstanceConfig: {
fontResourceByFontFamily: fonts
},
})
}
}
}
📖 五、API 详解
5.1 Svg 容器组件
Svg 是所有 SVG 图形的根容器组件,相当于 HTML 中的 <svg> 元素。它定义了图形的画布大小和坐标系统,所有其他图形组件都必须作为 Svg 的子元素使用。
核心概念:
Svg 组件通过 width 和 height 属性定义画布的物理尺寸,这两个属性是必须设置的。你可以使用数字(表示像素值)或字符串(如 “100%”、“50vw” 等)。在实际开发中,建议使用数字类型,因为字符串类型的百分比在某些场景下可能存在兼容性问题。
viewBox 属性是一个强大的特性,它允许你定义 SVG 的内部坐标系统。viewBox 的格式为 “min-x min-y width height”,例如 viewBox=“0 0 100 100” 表示坐标系统从 (0,0) 开始,宽高各 100 单位。当 viewBox 与实际的 width/height 比例不一致时,可以通过 preserveAspectRatio 属性控制缩放和对齐方式。
使用场景:
Svg 容器常用于创建固定尺寸的图标、响应式的图表容器,以及需要精确控制图形尺寸的场景。在开发复杂图形时,建议先规划好 Svg 的尺寸和内部坐标系统,这样可以避免后续调整带来的连锁问题。
import Svg, { Circle, Rect } from 'react-native-svg';
const SvgExample = () => {
return (
<View style={styles.container}>
<Svg width={200} height={200} viewBox="0 0 100 100">
<Circle cx={50} cy={50} r={40} fill="#FF6B6B" />
</Svg>
<Svg width="100%" height={100} style={{ marginTop: 20 }}>
<Rect x={0} y={0} width="100%" height={100} fill="#4ECDC4" />
</Svg>
</View>
);
};
注意事项:
- width 和 height 必须设置,否则图形不会显示
- 当使用百分比宽度时,确保父容器有明确的宽度
- viewBox 可以实现图形的缩放而不失真,适合响应式场景
- 在 HarmonyOS 上,建议优先使用数字类型的尺寸值
5.2 Path 路径组件
Path 是 SVG 中最强大、最灵活的绘图组件,它通过一系列命令来定义任意形状。几乎任何复杂的图形都可以用 Path 来绘制,包括曲线、弧线、不规则多边形等。
路径命令详解:
Path 的 d 属性接收一个命令字符串,每个命令由一个字母和后面的数值参数组成。命令字母大写表示绝对坐标,小写表示相对坐标。
移动命令 M/m:将画笔移动到指定位置,不绘制线条。例如 M10 10 表示移动到坐标 (10, 10)。每个路径通常以 M 命令开始,指定起始点。
直线命令 L/l:从当前位置画直线到指定位置。例如 M10 10 L90 90 表示从 (10,10) 画线到 (90,90)。H 和 V 是 L 的简化形式,分别用于绘制水平和垂直线。
曲线命令 C/c、S/s、Q/q:用于绘制贝塞尔曲线。C 命令绘制三次贝塞尔曲线,需要两个控制点和一个终点,格式为 C x1 y1, x2 y2, x y。Q 命令绘制二次贝塞尔曲线,只需要一个控制点。S 命令是 C 的简化形式,它会自动计算第一个控制点。
弧线命令 A/a:绘制椭圆弧,是最复杂的命令。格式为 A rx ry x-axis-rotation large-arc-flag sweep-flag x y,其中 rx 和 ry 是椭圆的两个半径,x-axis-rotation 是旋转角度,两个 flag 控制弧线的方向和大小。
闭合命令 Z/z:将路径闭合,从当前位置画直线回到路径起点。通常用于绘制封闭图形如三角形、多边形等。
实际应用示例:
import Svg, { Path, G } from 'react-native-svg';
const PathExample = () => {
return (
<Svg width={300} height={200}>
<G>
<Path
d="M50 150 L100 50 L150 150 Z"
fill="#FF6B6B"
stroke="#333"
strokeWidth={2}
/>
<Path
d="M200 50 C200 50, 250 50, 250 100 C250 150, 200 150, 200 100"
fill="none"
stroke="#4ECDC4"
strokeWidth={3}
/>
<Path
d="M280 100 A30 30 0 1 1 280 99"
fill="none"
stroke="#45B7D1"
strokeWidth={2}
/>
</G>
</Svg>
);
};
开发技巧:
- 复杂路径建议使用设计工具(如 Figma、Illustrator)导出,然后复制 d 属性值
- 使用 G 组件对多个 Path 进行分组,便于统一设置样式
- fill=“none” 可以绘制纯线条图形,如折线图、签名板等
- stroke 属性设置线条颜色,strokeWidth 设置线条粗细
5.3 Circle 圆形组件
Circle 用于绘制圆形,是最基础的几何图形组件。通过圆心坐标和半径三个属性即可定义一个圆。
属性说明:
cx 和 cy 定义圆心的坐标位置,默认值为 0。r 定义圆的半径,必须为正数。这三个属性都可以使用数字或字符串类型,但在 HarmonyOS 上建议使用数字类型以获得最佳兼容性。
样式控制:
fill 属性控制圆的填充颜色,可以使用十六进制颜色码(如 “#FF6B6B”)、颜色名称(如 “red”)或 rgba 格式(如 “rgba(255,0,0,0.5)”)。stroke 属性设置描边颜色,strokeWidth 设置描边宽度。通过组合这些属性,可以创建实心圆、空心圆、带边框的圆等多种效果。
典型应用:
import Svg, { Circle, Defs, RadialGradient, Stop } from 'react-native-svg';
const CircleExample = () => {
return (
<Svg width={200} height={200}>
<Defs>
<RadialGradient id="sunGradient" cx="50%" cy="50%" r="50%">
<Stop offset="0%" stopColor="#FFD700" />
<Stop offset="100%" stopColor="#FF6B00" />
</RadialGradient>
</Defs>
<Circle cx={100} cy={100} r={80} fill="url(#sunGradient)" />
<Circle cx={60} cy={70} r={8} fill="#fff" opacity={0.8} />
<Circle cx={140} cy={70} r={8} fill="#fff" opacity={0.8} />
<Circle
cx={100}
cy={100}
r={80}
fill="none"
stroke="#333"
strokeWidth={2}
strokeDasharray="5,5"
/>
</Svg>
);
};
应用场景:
圆形组件广泛应用于图标设计(如状态指示器、头像边框)、数据可视化(如饼图、气泡图)、装饰元素(如按钮背景、装饰圆点)等场景。结合渐变效果,可以创建更加丰富的视觉效果。
5.4 Rect 矩形组件
Rect 用于绘制矩形,是最常用的基础图形之一。除了基本的宽高属性外,还支持圆角设置,可以绘制从正方形到圆角矩形的各种形状。
核心属性:
x 和 y 定义矩形左上角的位置坐标,默认值为 0。width 和 height 定义矩形的宽度和高度,是必须设置的属性。rx 和 ry 分别定义 x 轴和 y 轴方向的圆角半径,当只设置 rx 时,ry 会自动取相同值。
圆角矩形:
通过设置 rx 属性可以创建圆角矩形。当 rx 值等于 width/2 和 height/2 中的较小值时,矩形会变成胶囊形状(两端半圆)。这个特性常用于创建按钮背景、标签等 UI 元素。
import Svg, { Rect, Defs, LinearGradient, Stop } from 'react-native-svg';
const RectExample = () => {
return (
<Svg width={300} height={200}>
<Defs>
<LinearGradient id="btnGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<Stop offset="0%" stopColor="#667eea" />
<Stop offset="100%" stopColor="#764ba2" />
</LinearGradient>
</Defs>
<Rect x={20} y={20} width={80} height={80} fill="#FF6B6B" />
<Rect x={120} y={20} width={80} height={80} rx={10} fill="#4ECDC4" />
<Rect x={220} y={20} width={60} height={80} rx={30} fill="#45B7D1" />
<Rect
x={20}
y={130}
width={260}
height={50}
rx={25}
fill="url(#btnGradient)"
/>
</Svg>
);
};
实际应用:
矩形组件在 UI 开发中应用广泛,包括按钮背景、卡片容器、进度条背景、分割线、占位符等。结合渐变和阴影效果,可以创建现代化的 UI 元素。
5.5 Ellipse 椭圆组件
Ellipse 用于绘制椭圆,与 Circle 类似但可以分别设置 x 轴和 y 轴的半径,从而创建出椭圆形的图形。
属性详解:
cx 和 cy 定义椭圆中心的坐标位置。rx 定义椭圆在 x 轴方向的半径,ry 定义椭圆在 y 轴方向的半径。当 rx 等于 ry 时,椭圆就变成了圆形。
应用场景:
椭圆常用于创建椭圆形的装饰元素、图标背景、头像边框等。在数据可视化中,椭圆也用于表示具有两个维度数据的散点图。
import Svg, { Ellipse, Defs, LinearGradient, Stop } from 'react-native-svg';
const EllipseExample = () => {
return (
<Svg width={300} height={150}>
<Defs>
<LinearGradient id="ellipseGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<Stop offset="0%" stopColor="#a8edea" />
<Stop offset="100%" stopColor="#fed6e3" />
</LinearGradient>
</Defs>
<Ellipse cx={80} cy={75} rx={60} ry={40} fill="#FF6B6B" />
<Ellipse cx={220} cy={75} rx={70} ry={50} fill="url(#ellipseGrad)" />
</Svg>
);
};
5.6 Line 直线组件
Line 用于绘制直线,通过定义起点和终点坐标来创建线段。虽然 Path 也可以画线,但 Line 组件更加直观和简洁。
属性说明:
x1 和 y1 定义直线的起点坐标,x2 和 y2 定义直线的终点坐标。Line 组件默认没有填充色,必须设置 stroke 属性才能看到线条。
线条样式:
除了基本的 stroke 和 strokeWidth 属性外,还可以使用 strokeLinecap 设置线条端点样式(butt、round、square),使用 strokeDasharray 创建虚线效果。
import Svg, { Line, G } from 'react-native-svg';
const LineExample = () => {
return (
<Svg width={300} height={200}>
<G>
<Line
x1={20}
y1={20}
x2={280}
y2={20}
stroke="#333"
strokeWidth={2}
/>
<Line
x1={20}
y1={60}
x2={280}
y2={60}
stroke="#FF6B6B"
strokeWidth={3}
strokeLinecap="round"
/>
<Line
x1={20}
y1={100}
x2={280}
y2={100}
stroke="#4ECDC4"
strokeWidth={2}
strokeDasharray="10,5"
/>
<Line
x1={20}
y1={140}
x2={280}
y2={180}
stroke="#45B7D1"
strokeWidth={4}
strokeLinecap="round"
/>
</G>
</Svg>
);
};
应用场景:
直线组件常用于绘制分割线、坐标轴、连接线、进度指示器等。在图表开发中,Line 是绘制网格线和坐标轴的基础组件。
5.7 Polygon 多边形组件
Polygon 用于绘制封闭的多边形,通过指定一系列顶点坐标自动闭合形成多边形。与 Path 相比,Polygon 更加简洁,适合绘制规则或不规则的多边形。
属性详解:
points 属性定义多边形的顶点坐标序列,格式为 “x1,y1 x2,y2 x3,y3 …”,坐标之间用空格分隔,x 和 y 之间用逗号分隔。Polygon 会自动将最后一个顶点与第一个顶点连接,形成封闭图形。
常见多边形:
三角形需要 3 个顶点,四边形需要 4 个顶点,五边形需要 5 个顶点,以此类推。通过调整顶点位置,可以创建各种形状的多边形,包括星形、箭头等复杂图形。
import Svg, { Polygon, G } from 'react-native-svg';
const PolygonExample = () => {
return (
<Svg width={300} height={200}>
<G>
<Polygon
points="50,150 100,50 150,150"
fill="#FF6B6B"
stroke="#333"
strokeWidth={2}
/>
<Polygon
points="200,30 230,90 280,90 245,130 260,190 200,150 140,190 155,130 120,90 170,90"
fill="#F7DC6F"
stroke="#333"
strokeWidth={1}
/>
<Polygon
points="250,50 280,70 280,110 250,130 220,110 220,70"
fill="#BB8FCE"
/>
</G>
</Svg>
);
};
应用场景:
多边形组件适用于创建图标(如箭头、星标)、装饰元素、不规则形状的按钮等。在地图应用中,Polygon 也用于绘制区域边界。
5.8 Polyline 多段线组件
Polyline 用于绘制连续的多段线,与 Polygon 类似但不会自动闭合。它是一系列连接的直线段,适合绘制折线图、路径轨迹等。
属性说明:
points 属性定义各段线的端点坐标序列,格式与 Polygon 相同。Polyline 不会自动闭合,如果需要闭合可以使用 Polygon 或者在 points 中手动添加起点坐标。
import Svg, { Polyline, G } from 'react-native-svg';
const PolylineExample = () => {
return (
<Svg width={300} height={200}>
<G>
<Polyline
points="20,180 60,120 100,150 140,80 180,100 220,40 260,60"
fill="none"
stroke="#FF6B6B"
strokeWidth={2}
/>
<Polyline
points="20,100 60,100 100,60 140,60 180,20"
fill="none"
stroke="#4ECDC4"
strokeWidth={3}
strokeLinecap="round"
strokeLinejoin="round"
/>
</G>
</Svg>
);
};
应用场景:
Polyline 最常见的应用是折线图,用于展示数据趋势。此外也用于绘制签名轨迹、路线规划、手绘效果等场景。
5.9 渐变效果
react-native-svg 支持线性渐变(LinearGradient)和径向渐变(RadialGradient),可以为图形添加丰富的色彩过渡效果。
LinearGradient 线性渐变:
线性渐变沿着直线方向进行颜色过渡。x1、y1 定义渐变的起点坐标,x2、y2 定义终点坐标。坐标可以使用百分比(如 “50%”)或小数(如 0.5)。渐变方向由起点到终点决定,例如从左到右(x1=“0%” x2=“100%”)、从上到下(y1=“0%” y2=“100%”)、对角线方向等。
RadialGradient 径向渐变:
径向渐变从中心点向外辐射进行颜色过渡。cx、cy 定义渐变中心点坐标,r 定义渐变半径。fx、fy 定义渐变焦点,可以创建偏心的渐变效果。
Stop 渐变节点:
Stop 组件定义渐变中的颜色节点。offset 属性定义节点位置(0% 到 100%),stopColor 定义该位置的颜色。通过设置多个 Stop 节点,可以创建多色渐变效果。
import Svg, { Rect, Circle, Defs, LinearGradient, RadialGradient, Stop } from 'react-native-svg';
const GradientExample = () => {
return (
<Svg width={300} height={300}>
<Defs>
<LinearGradient id="horizontalGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<Stop offset="0%" stopColor="#667eea" />
<Stop offset="50%" stopColor="#764ba2" />
<Stop offset="100%" stopColor="#f093fb" />
</LinearGradient>
<LinearGradient id="diagonalGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<Stop offset="0%" stopColor="#a8edea" />
<Stop offset="100%" stopColor="#fed6e3" />
</LinearGradient>
<RadialGradient id="radialGrad" cx="50%" cy="50%" r="50%">
<Stop offset="0%" stopColor="#fff" />
<Stop offset="50%" stopColor="#FFD700" />
<Stop offset="100%" stopColor="#FF6B00" />
</RadialGradient>
</Defs>
<Rect x={20} y={20} width={120} height={80} rx={10} fill="url(#horizontalGrad)" />
<Rect x={160} y={20} width={120} height={80} rx={10} fill="url(#diagonalGrad)" />
<Circle cx={100} cy={200} r={60} fill="url(#radialGrad)" />
<Circle cx={220} cy={200} r={60} fill="url(#horizontalGrad)" />
</Svg>
);
};
使用技巧:
- 渐变必须定义在 Defs 组件内,并通过 id 属性标识
- 使用渐变时,通过 fill=“url(#id)” 或 stroke=“url(#id)” 引用
- 多个图形可以共享同一个渐变定义
- 渐变坐标是相对于引用它的图形的本地坐标系
5.10 G 分组组件
G 组件用于将多个图形元素分组,类似于 HTML 中的 <div> 容器。分组后的元素可以统一设置样式、变换等属性,便于管理和复用。
核心功能:
G 组件本身不绘制任何图形,它只是一个逻辑容器。在 G 上设置的 fill、stroke、opacity、transform 等属性会应用到所有子元素,除非子元素自己覆盖了这些属性。
变换操作:
G 组件支持 transform 属性,可以对整组元素进行平移(translate)、旋转(rotate)、缩放(scale)、倾斜(skew)等变换操作。这在创建复杂图形时非常有用。
import Svg, { G, Circle, Rect } from 'react-native-svg';
const GroupExample = () => {
return (
<Svg width={300} height={200}>
<G transform="translate(50, 50)">
<Rect x={0} y={0} width={80} height={80} fill="#E8E8E8" />
<Circle cx={25} cy={40} r={15} fill="#FF6B6B" />
<Circle cx={55} cy={40} r={15} fill="#4ECDC4" />
</G>
<G transform="translate(170, 50)" opacity={0.7}>
<Rect x={0} y={0} width={80} height={80} rx={10} fill="#45B7D1" />
<Circle cx={40} cy={30} r={10} fill="#fff" />
<Circle cx={25} cy={55} r={8} fill="#fff" />
<Circle cx={55} cy={55} r={8} fill="#fff" />
</G>
</Svg>
);
};
应用场景:
G 组件常用于创建可复用的图形组件、图标库、复杂图形的组织管理等。通过分组,可以将相关的图形元素组织在一起,便于整体操作和维护。
5.11 Defs 定义组件
Defs 组件用于定义可复用的元素,如渐变、遮罩、裁剪路径等。定义在 Defs 中的元素不会直接显示,只有被其他元素引用时才会生效。
使用方式:
将渐变、遮罩等定义放在 Defs 组件内,并设置唯一的 id 属性。然后在需要使用的地方通过 url(#id) 语法引用。这种方式可以实现资源的复用,减少代码重复。
import Svg, { Defs, Rect, LinearGradient, Stop, ClipPath, Circle } from 'react-native-svg';
const DefsExample = () => {
return (
<Svg width={300} height={200}>
<Defs>
<LinearGradient id="cardGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<Stop offset="0%" stopColor="#667eea" />
<Stop offset="100%" stopColor="#764ba2" />
</LinearGradient>
<ClipPath id="circleClip">
<Circle cx={100} cy={100} r={80} />
</ClipPath>
</Defs>
<Rect x={20} y={20} width={120} height={80} rx={10} fill="url(#cardGradient)" />
<Rect
x={180}
y={20}
width={100}
height={100}
fill="url(#cardGradient)"
clipPath="url(#circleClip)"
/>
</Svg>
);
};
5.12 公共属性与样式
所有 SVG 图形组件都支持一组公共属性,用于控制填充、描边、透明度等样式效果。
填充属性:
fill 属性设置图形的填充颜色,可以是颜色值或渐变引用。fillOpacity 单独控制填充的透明度(0-1)。fillRule 属性定义填充规则,用于复杂路径的填充判断(evenodd 或 nonzero)。
描边属性:
stroke 设置描边颜色,strokeWidth 设置描边宽度。strokeOpacity 控制描边透明度。strokeLinecap 设置线条端点样式(butt、round、square)。strokeLinejoin 设置线条连接处样式(miter、round、bevel)。strokeDasharray 创建虚线效果,格式为 “线段长度,间隔长度”。
透明度与变换:
opacity 属性设置整体透明度(0-1),会影响填充和描边。transform 属性支持 translate、rotate、scale、skew 等变换操作,可以对图形进行几何变换。
import Svg, { Circle, Rect, G } from 'react-native-svg';
const StyleExample = () => {
return (
<Svg width={300} height={200}>
<Circle
cx={60}
cy={100}
r={40}
fill="#FF6B6B"
fillOpacity={0.5}
stroke="#333"
strokeWidth={3}
/>
<Rect
x={120}
y={60}
width={80}
height={80}
fill="none"
stroke="#4ECDC4"
strokeWidth={4}
strokeDasharray="10,5"
strokeLinecap="round"
/>
<G transform="translate(230, 100) rotate(45)">
<Rect
x={-30}
y={-30}
width={60}
height={60}
fill="#45B7D1"
opacity={0.7}
/>
</G>
</Svg>
);
};
掌握这些公共属性,可以灵活地控制图形的外观,创建丰富多彩的视觉效果。在实际开发中,建议将这些样式封装成可复用的配置对象,便于统一管理和主题切换。
💻 六、完整代码示例

一个可直接运行的 SVG 图形展示应用:
import React from 'react';
import { View, Text, StyleSheet, SafeAreaView, ScrollView } from 'react-native';
import Svg, {
Circle,
Rect,
Path,
Line,
Polygon,
Ellipse,
G,
Defs,
LinearGradient,
Stop
} from 'react-native-svg';
const SvgDemo = () => {
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.content}>
<Text style={styles.title}>SVG 图形示例</Text>
<View style={styles.section}>
<Text style={styles.sectionTitle}>圆形 Circle</Text>
<Svg width={100} height={100}>
<Circle
cx={50}
cy={50}
r={40}
fill="#FF6B6B"
stroke="#333"
strokeWidth={2}
/>
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>矩形 Rect</Text>
<Svg width={100} height={100}>
<Rect x={10} y={10} width={80} height={80} rx={10} fill="#4ECDC4" />
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>椭圆 Ellipse</Text>
<Svg width={100} height={100}>
<Ellipse cx={50} cy={50} rx={45} ry={30} fill="#45B7D1" />
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>路径 Path - 三角形</Text>
<Svg width={100} height={100}>
<Path
d="M50 10 L90 90 L10 90 Z"
fill="#F7DC6F"
stroke="#333"
strokeWidth={2}
/>
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>多边形 Polygon - 六边形</Text>
<Svg width={100} height={100}>
<Polygon
points="50,10 90,30 90,70 50,90 10,70 10,30"
fill="#BB8FCE"
/>
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>直线 Line</Text>
<Svg width={100} height={100}>
<Line
x1="10"
y1="10"
x2="90"
y2="90"
stroke="#E74C3C"
strokeWidth={3}
/>
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>渐变 Gradient</Text>
<Svg width={150} height={100}>
<Defs>
<LinearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">
<Stop offset="0%" stopColor="#FF6B6B" />
<Stop offset="50%" stopColor="#4ECDC4" />
<Stop offset="100%" stopColor="#45B7D1" />
</LinearGradient>
</Defs>
<Rect x={10} y={10} width={130} height={80} rx={10} fill="url(#grad)" />
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>组合图形 G</Text>
<Svg width={150} height={100}>
<G transform="translate(10, 10)">
<Rect width={130} height={80} rx={10} fill="#E8E8E8" />
<Circle cx={40} cy={40} r={25} fill="#FF6B6B" />
<Circle cx={90} cy={40} r={25} fill="#4ECDC4" />
</G>
</Svg>
</View>
<View style={styles.section}>
<Text style={styles.sectionTitle}>笑脸</Text>
<Svg width={120} height={120}>
<Circle
cx={60}
cy={60}
r={55}
fill="#F7DC6F"
stroke="#333"
strokeWidth={2}
/>
<Circle cx={40} cy={45} r={8} fill="#333" />
<Circle cx={80} cy={45} r={8} fill="#333" />
<Path
d="M30 75 Q60 100 90 75"
fill="none"
stroke="#333"
strokeWidth={3}
strokeLinecap="round"
/>
</Svg>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5'
},
content: {
padding: 16
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
textAlign: 'center',
marginBottom: 20
},
section: {
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
alignItems: 'center'
},
sectionTitle: {
fontSize: 16,
fontWeight: '600',
color: '#333',
marginBottom: 12
}
});
export default SvgDemo;
📋 七、属性参考
Svg 属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| width | number| string | 是 | 组件宽度 |
| height | number| string | 是 | 组件高度 |
| viewBox | string | 否 | 视区定义 |
| preserveAspectRatio | string | 否 | 宽高比保持方式 |
| color | string | 否 | 默认颜色 |
| style | object | 否 | 样式 |
Path 属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| d | string | 是 | 路径命令字符串 |
| fill | string | 否 | 填充颜色 |
| stroke | string | 否 | 描边颜色 |
Circle 属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cx | number| string | 否 | 圆心 x 坐标 |
| cy | number| string | 否 | 圆心 y 坐标 |
| r | number| string | 是 | 半径 |
Rect 属性
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x | number| string | 否 | 左上角 x 坐标 |
| y | number| string | 否 | 左上角 y 坐标 |
| width | number| string | 是 | 宽度 |
| height | number| string | 是 | 高度 |
| rx | number| string | 否 | x 轴圆角半径 |
| ry | number| string | 否 | y 轴圆角半径 |
⚠️ 八、常见问题
Q1: SVG 不显示?
A: 确保 Svg 组件设置了正确的 width 和 height:
<Svg width={100} height={100}>
<Circle cx={50} cy={50} r={40} fill="blue" />
</Svg>
Q2: 渐变不生效?
A: 确保渐变定义在 Defs 中,且 id 正确引用:
<Defs>
<LinearGradient id="myGrad" x1="0" y1="0" x2="1" y2="0">
<Stop offset="0" stopColor="red" />
<Stop offset="1" stopColor="blue" />
</LinearGradient>
</Defs>
<Rect fill="url(#myGrad)" />
Q3: 如何绘制复杂图形?
A: 使用 Path 组件的 d 属性定义路径:
<Path d="M10 10 C20 20, 40 20, 50 10" fill="none" stroke="black" />
Q4: 如何实现动画效果?
A: 结合 react-native-reanimated 或 Animated API:
import Animated from 'react-native-reanimated';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
📝 九、总结
react-native-svg CAPI 版本为 HarmonyOS 平台提供了高性能的 SVG 渲染能力,支持丰富的图形组件和高级特性。通过本篇文章,你已经掌握了:
- SVG 基础组件的使用方法
- 渐变、遮罩等高级特性
- 实际应用场景的最佳实践
更多推荐


所有评论(0)