- 图形学
- 移动开发
- 跨平台
- UI组件
【免费下载链接】react-native-skia
High-performance React Native Graphics using Skia
本文围绕 react-native-skia 的Path组件展开,讲解如何用 SVG 路径字符串或Skia.PathBuilder对象绘制路径,以及start/end路径裁剪、stroke描边转填充、fillType填充规则等核心属性。结合组件源码与类型定义,你可以掌握路径绘制的完整属性集,并理解每个属性在底层实现中对应的含义,从而在 React Native 应用中精确控制任意形状的描边与填充行为。
在 Skia 中,路径(Path)与 SVG Path 在语义上完全一致:由一系列带坐标的命令(M移动、L直线、C三次贝塞尔、Z闭合等)组成轮廓描述。react-native-skia 通过<Path>渲染组件把这两种表达方式统一接入 React 组件树。
Path 组件属性总览
Path组件的完整属性定义位于 Drawings.ts,PathProps在通用绘制节点属性DrawingNodeProps基础上扩展了以下核心字段:
| 属性 | 类型 | 说明 |
|---|---|---|
path | SkPath或string | 要绘制的路径。可以是使用 SVG Path 语法(line commands、curve commands 等)描述的字符串,也可以是用Skia.PathBuilder构建的路径对象 |
start | number | 裁剪路径的起点,取值范围[0, 1],默认0 |
end | number | 裁剪路径的终点,取值范围[0, 1],默认1 |
stroke | StrokeOptions | 将路径转换为「描边后的填充等价物」。当路径是 hairline(零宽度)时会失败。StrokeOptions描述转换后路径的外观,包含width、miter limit 与precision等属性 |
fillType | "winding"|"evenOdd"|"inverseWinding"|"inverseEvenOdd" | 决定「形状内部」的判定算法,默认winding |
组件实现非常薄,位于 Path.tsx:
export const Path = ({ start = 0, end = 1, ...props }: SkiaDefaultProps<PathProps, "start" | "end">) => { return <skPath start={start} end={end} {...props} />; };从源码结构看,start/end的默认值正是在组件层通过解构默认参数(start = 0, end = 1)确立的,其余属性(path、stroke、fillType以及继承自DrawingNodeProps的color、style、strokeWidth、strokeJoin、opacity等)全部透传给内部节点skPath,由渲染管线统一消费。这意味着Path与Circle、Rect等其他形状组件共享同一套颜色、透明度、裁剪等能力。
使用 SVG 路径字符串
最直接的方式是传入符合 SVG Path 语法的字符串。以下示例绘制了一个五角星:
import {Canvas, Path} from "@shopify/react-native-skia"; const SVGNotation = () => { return ( <Canvas style={{ flex: 1 }}> <Path path="M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z" color="lightblue" /> </Canvas> ); };字符串中M 128 0是移动起点,随后连续的L x y逐个添加直线段,末尾的Z闭合轮廓。该写法与 Web 端的 SVGd属性完全同构,方便把已有 SVG 资源直接迁移到 React Native 中。
使用 Path 对象(PathBuilder)
与字符串等价的另一种方式是使用Skia.PathBuilder以命令式 API 构建路径对象,再作为path属性传入。同一个五角星用 PathBuilder 的写法:
import {Canvas, Path, Skia} from "@shopify/react-native-skia"; const path = Skia.PathBuilder.Make() .moveTo(128, 0) .lineTo(168, 80) .lineTo(256, 93) .lineTo(192, 155) .lineTo(207, 244) .lineTo(128, 202) .lineTo(49, 244) .lineTo(64, 155) .lineTo(0, 93) .lineTo(88, 80) .lineTo(128, 0) .close() .build(); const PathDemo = () => { return ( <Canvas style={{ flex: 1 }}> <Path path={path} color="lightblue" /> </Canvas> ); };PathBuilder 采用链式调用,moveTo/lineTo/close与 SVG 命令一一对应,build()生成SkPath实例。相比字符串,PathBuilder 的优势在于:路径可以在运行时由数据动态计算(比如根据坐标数组生成折线),并且可以调用addArc、addOval、addRect等更丰富的几何方法——Path.ts 中的SkPath接口定义了这些链式几何方法,每个方法返回修改后的路径本身,便于继续链式追加。
使用 start / end 裁剪路径
start和end按路径总长度的比例[0, 1]截取路径的一段。以下示例只保留五角星轮廓中间的四分之一段,绘制为描边:
import {Canvas, Path} from "@shopify/react-native-skia"; const TrimDemo = () => { return ( <Canvas style={{ flex: 1 }}> <Path path="M 128 0 L 168 80 L 256 93 L 192 155 L 207 244 L 128 202 L 49 244 L 64 155 L 0 93 L 88 80 L 128 0 Z" color="lightblue" style="stroke" strokeJoin="round" strokeWidth={5} // 裁剪掉路径的前后各四分之一 start={0.25} end={0.75} /> </Canvas> ); };start/end与style="stroke"组合使用时尤其有用:让描边只沿路径的一部分显示,是实现「路径渐进描边」类动画的基础。配合 Animations Hooks 文档中介绍的动画 Hooks,可以把start/end绑定到动画值上,实现路径逐渐画出的效果。
stroke 属性:把描边转换为填充路径
stroke属性用于把「被描边的路径」转换为「描边结果等价的填充路径」,等价于 Skia 的SkPathEffect::Stroke/Path.stroke()。类型定义见 PathFactory.ts:
Stroke(path: SkPath, opts?: StrokeOpts): SkPath | null;注意该方法的返回值是SkPath | null——这与文档中的说明一致:当源路径是 hairline(退化零宽度)时转换会失败并返回null。
转换所用的参数类型StrokeOpts定义在 Path.ts:
/** * Options used for Path.stroke(). If an option is omitted, a sensible default will be used. */ export interface StrokeOpts { /** The width of the stroked lines. */ width?: number; miter_limit?: number; /** * if > 1, increase precision, else if (0 < resScale < 1) reduce precision to * favor speed and size */ precision?: number; join?: StrokeJoin; cap?: StrokeCap; }各字段含义:
width:描边线宽,决定转换后填充区域的宽度;miter_limit:miter(尖角)连接的最大延伸倍率,超过该值会改用 bevel 连接,避免尖角处产生过长的尖刺;precision:路径重建精度。大于1时提高精度;0 < precision < 1时降低精度以换取速度和更小的路径体积。注释明确说明省略选项时会使用合理默认值;join/cap:连接与端点样式,对应StrokeJoin、StrokeCap枚举(butt/round/square、miter/round/bevel等取值)。
stroke的典型用途是生成带圆角/圆头端点的粗线条形状,或把细路径「膨胀」成实心区域,后续可对其填充、做蒙版或参与PathOp(Path.ts 定义了Difference、Intersect、Union、XOR、ReverseDifference五种布尔运算)组合复杂形状。
fillType 填充规则
fillType决定「多边形内部」的判定算法,即路径自相交或包含子路径时哪些区域被视为可填充区域。可选值为winding(默认)、evenOdd、inverseWinding、inverseEvenOdd。底层对应 FillType 枚举:
export enum FillType { Winding, EvenOdd, InverseWinding, InverseEvenOdd, }两种核心规则:
- Winding(环绕规则,默认):以射线法统计路径各段围绕判定点的环绕次数,非零即为内部。方向相反的子路径(如外圈顺时针、内圈逆时针)会相互抵消,从而形成「挖空」;
- EvenOdd(奇偶规则):任意方向都计入,射线与路径边界的交点数为奇数即内部,更直观地生成镂空效果。
两种inverse变体把判定结果取反:原本透明的区域被填充,原本填充的区域透明。
下面示例绘制一个自相交的星形路径,用evenOdd规则填充,中心区域会呈现奇偶交替的镂空效果(与文档中winding默认填充的对比图见 evenodd-filltype.png):
import {Canvas, Skia, Fill, Path} from "@shopify/react-native-skia"; const star = () => { const R = 115.2; const C = 128.0; const builder = Skia.PathBuilder.Make(); builder.moveTo(C + R, C); for (let i = 1; i < 8; ++i) { const a = 2.6927937 * i; // 2π/5,五角星相邻顶点间的圆心角 builder.lineTo(C + R * Math.cos(a), C + R * Math.sin(a)); } return builder.build(); }; export const FillTypeDemo = () => { const path = star(); return ( <Canvas style={{ flex: 1 }}> <Fill color="white" /> <Path path={path} style="stroke" strokeWidth={4} color="#3EB489"/> <Path path={path} color="lightblue" fillType="evenOdd" /> </Canvas> ); };示例中星形由 8 个半径R = 115.2、中心C = 128的顶点连成,2.6927937即2π/5 ≈ 129.6°,使相邻顶点按五角星的步长绕行一圈形成自相交轮廓。叠加两个Path:一个style="stroke"勾勒轮廓,一个fillType="evenOdd"填充——可以清楚看到奇偶规则下中心与外围交替的填充区域。仓库的渲染测试目录中还有winding默认规则的对照图 default-filltype.png,可用于对比两种规则在同一图形上的差异。
扩展能力:Path Effects 与 Path 动画 Hooks
Path组件本身只负责几何定义与基本描边/填充,更高级的视觉效果由配套 API 提供:
- Path Effects:虚线、圆角折线、位移路径等效果,见 Path Effects 文档,可让同一路径以 dash、corner 等方式渲染;
- Path Hooks:将
start/end、路径插值等能力接入动画系统,配合 Animations Hooks 实现路径形变与渐进描边动画; - Path 迁移指南:旧版 API 到新 API 的对照见 Path Migration 文档。
另外,仓库的示例应用 Path.tsx 提供了 Path API 的交互式演示页面,可用于在真机/模拟器中快速验证各类路径行为。
小结
Path是 react-native-skia 中最灵活的形状组件:path属性同时接受 SVG 字符串与Skia.PathBuilder对象两种输入;start/end按比例裁剪路径区间(默认全路径,源码中默认值定义于 Path.tsx);stroke通过StrokeOpts(width、miter_limit、precision等,见 Path.ts)把描边转换为可填充路径,hairline 路径会转换失败;fillType在winding/evenOdd及其 inverse 变体之间切换内外判定规则。理解这组属性并对照源码中的类型定义,即可覆盖从静态图形到路径动画的绝大多数绘制需求。
- 图形学
- 移动开发
- 跨平台
- UI组件
【免费下载链接】react-native-skia
High-performance React Native Graphics using Skia
相关推荐
react-native-skia Path API 迁移指南:从可变 SkPath 到不可变 PathBuilder
react native skia Path API 迁移指南:从可变 SkPath 到不可变 PathBuilder 本文介绍 react native sk
图形学移动开发跨平台UI组件Enzyme ShallowWrapper.slice() 方法详解:按数组规则裁剪节点子集
Enzyme ShallowWrapper.slice 方法详解:按数组规则裁剪节点子集 导读 .slice 是 Enzyme 中用于在测试断言链上按数组规则截
测试前端react-native-art-svg路径编辑工具:使用Path组件创建自定义图形
react native art svg路径编辑工具:使用Path组件创建自定义图形 概述 在移动应用开发中,自定义图形绘制是提升用户界面视觉效果的重要手段。r
前端移动开发UI组件跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考