欢迎加入开源鸿蒙跨平台社区: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 技术架构图

平台层

核心功能

高级特性

组件层

Svg

Path

Circle

Rect

Ellipse

Line

Polygon

LinearGradient

RadialGradient

Mask

ClipPath

Defs

fill/stroke

transform

opacity

iOS

Android

HarmonyOS CAPI


📖 三、安装与配置

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 基础组件的使用方法
  • 渐变、遮罩等高级特性
  • 实际应用场景的最佳实践
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐