1 | # util
|
2 |
|
3 | > AntV 底层依赖的工具库,不建议在自己业务中使用。
|
4 |
|
5 | [](https://github.com/antvis/util/actions)
|
6 | [](https://www.npmjs.com/package/@antv/util)
|
7 | [](https://www.npmjs.com/package/@antv/util)
|
8 | [](https://www.npmjs.com/package/@antv/util)
|
9 |
|
10 | ## Usage
|
11 |
|
12 | ```ts
|
13 | import { gradient } from '@antv/util';
|
14 | ```
|
15 |
|
16 | ## 原则
|
17 |
|
18 | - util 只有一个 npm 包,按照目录来组织不同类型的方法,避免 monorepo 互相依赖
|
19 | - 内容和 AntV 强相关,避免做和 lodash 等相同的工具库
|
20 | - 不使用的方法,及时删除,并保持新增方法可以按需引入
|
21 | - 旧版本的不维护,如果 AntV 技术栈的旧版本需要迭代,请升级到 v3
|
22 |
|
23 | ## API
|
24 |
|
25 | 提供以下 Path 工具方法,包含转换、几何计算等。
|
26 |
|
27 | ### path2String
|
28 |
|
29 | 将 PathArray 转换成字符串形式,不会对原始定义中的命令进行修改:
|
30 |
|
31 | ```js
|
32 | const str: PathArray = [
|
33 | ['M', 10, 10],
|
34 | ['L', 100, 100],
|
35 | ['l', 10, 10],
|
36 | ['h', 20],
|
37 | ['v', 20],
|
38 | ];
|
39 | expect(path2String(str)).toEqual('M10 10L100 100l10 10h20v20');
|
40 | ```
|
41 |
|
42 | ### path2Array
|
43 |
|
44 | 将 PathArray 转换成数组,不会对原始定义中的命令进行修改:
|
45 |
|
46 | ```js
|
47 | const str = 'M10 10L100 100l10 10h20v20';
|
48 | expect(path2Array(str)).toEqual([
|
49 | ['M', 10, 10],
|
50 | ['L', 100, 100],
|
51 | ['l', 10, 10],
|
52 | ['h', 20],
|
53 | ['v', 20],
|
54 | ]);
|
55 | ```
|
56 |
|
57 | ### path2Absolute
|
58 |
|
59 | 将定义中的相对命令转换成绝对命令,例如:
|
60 |
|
61 | - l -> L
|
62 | - h -> H
|
63 | - v -> V
|
64 |
|
65 | 完整方法签名如下:
|
66 |
|
67 | ```js
|
68 | path2Absolute(pathInput: string | PathArray): AbsoluteArray;
|
69 | ```
|
70 |
|
71 | ```js
|
72 | const str: PathArray = [
|
73 | ['M', 10, 10],
|
74 | ['L', 100, 100],
|
75 | ['l', 10, 10],
|
76 | ['h', 20],
|
77 | ['v', 20],
|
78 | ];
|
79 | const arr = path2Absolute(str);
|
80 | expect(arr).toEqual([
|
81 | ['M', 10, 10],
|
82 | ['L', 100, 100],
|
83 | ['L', 110, 110],
|
84 | ['H', 130],
|
85 | ['V', 130],
|
86 | ]);
|
87 | ```
|
88 |
|
89 | ### path2Curve
|
90 |
|
91 | 将部分命令转曲,例如 L / A 转成 C 命令,借助 cubic bezier 易于分割的特性用于实现形变动画。
|
92 | 该方法内部会调用 [path2Absolute](#path2Absolute),因此最终返回的 PathArray 中仅包含 M 和 C 命令。
|
93 |
|
94 | 完整方法签名如下:
|
95 |
|
96 | ```js
|
97 | path2Curve(pathInput: string | PathArray): CurveArray;
|
98 | ```
|
99 |
|
100 | ```js
|
101 | expect(
|
102 | path2Curve([
|
103 | ['M', 0, 0],
|
104 | ['L', 100, 100],
|
105 | ]),
|
106 | ).toEqual([
|
107 | ['M', 0, 0],
|
108 | ['C', 44.194173824159215, 44.194173824159215, 68.75, 68.75, 100, 100],
|
109 | ]);
|
110 | ```
|
111 |
|
112 | ### clonePath
|
113 |
|
114 | 复制路径:
|
115 |
|
116 | ```js
|
117 | const cloned = clonePath(pathInput);
|
118 | ```
|
119 |
|
120 | ### reverseCurve
|
121 |
|
122 | ```js
|
123 | const pathArray: CurveArray = [
|
124 | ['M', 170, 90],
|
125 | ['C', 150, 90, 155, 10, 130, 10],
|
126 | ['C', 105, 10, 110, 90, 90, 90],
|
127 | ['C', 70, 90, 75, 10, 50, 10],
|
128 | ['C', 25, 10, 30, 90, 10, 90],
|
129 | ];
|
130 |
|
131 | const reversed = reverseCurve(pathArray);
|
132 | ```
|
133 |
|
134 | ### getPathBBox
|
135 |
|
136 | 获取几何定义下的包围盒,形如:
|
137 |
|
138 | ```js
|
139 | export interface PathBBox {
|
140 | width: number;
|
141 | height: number;
|
142 | x: number;
|
143 | y: number;
|
144 | x2: number;
|
145 | y2: number;
|
146 | cx: number;
|
147 | cy: number;
|
148 | cz: number;
|
149 | }
|
150 | ```
|
151 |
|
152 | ```js
|
153 | const bbox = getPathBBox([['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['Z']]);
|
154 |
|
155 | expect(bbox).toEqual({ cx: 50, cy: 50, cz: 150, height: 100, width: 100, x: 0, x2: 100, y: 0, y2: 100 });
|
156 | ```
|
157 |
|
158 | ### getTotalLength
|
159 |
|
160 | 获取路径总长度。
|
161 |
|
162 | ```js
|
163 | const length = getTotalLength([['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['Z']]);
|
164 |
|
165 | expect(length).toEqual(400);
|
166 | ```
|
167 |
|
168 | ### getPointAtLength
|
169 |
|
170 | 获取路径上从起点出发,到指定距离的点。
|
171 |
|
172 | ```js
|
173 | const point = getPointAtLength([['M', 0, 0], ['L', 100, 0], ['L', 100, 100], ['L', 0, 100], ['Z']], 0);
|
174 | expect(point).toEqual({ x: 0, y: 0 });
|
175 | ```
|
176 |
|
177 | ### getPathArea
|
178 |
|
179 | 计算路径包围的面积。内部实现中首先通过 [path2Curve](#path2Curve) 转曲,再计算 cubic curve 面积,[详见](https://stackoverflow.com/a/15845996)。
|
180 |
|
181 | 方法签名如下:
|
182 |
|
183 | ```js
|
184 | function getPathArea(path: PathArray): number;
|
185 | ```
|
186 |
|
187 | ### isPointInStroke
|
188 |
|
189 | 判断一个点是否在路径上,仅通过几何定义计算,不考虑其他样式属性例如线宽、lineJoin、miter 等。
|
190 |
|
191 | 方法签名如下:
|
192 |
|
193 | ```js
|
194 | isPointInStroke(pathInput: string | PathArray, point: Point): boolean;
|
195 | ```
|
196 |
|
197 | ```js
|
198 | const result = isPointInStroke(segments, { x: 10, y: 10 });
|
199 | ```
|
200 |
|
201 | ### distanceSquareRoot
|
202 |
|
203 | 计算两点之间的距离。
|
204 |
|
205 | 方法签名如下:
|
206 |
|
207 | ```js
|
208 | distanceSquareRoot(a: [number, number], b: [number, number]): number;
|
209 | ```
|
210 |
|
211 | ### equalizeSegments
|
212 |
|
213 | 将两条路径处理成段数相同,用于形变动画前的分割操作。
|
214 |
|
215 | ```js
|
216 | const [formattedPath1, formattedPath2] = equalizeSegments(path1, path2);
|
217 | ```
|
218 |
|
219 | ### isPointInPolygon
|
220 |
|
221 | 判断一个点是否在多边形内。多边形形如:
|
222 |
|
223 | ```js
|
224 | const polygon = [
|
225 | [0, 0],
|
226 | [0, 100],
|
227 | [30, 100],
|
228 | [30, 0],
|
229 | ];
|
230 |
|
231 | // [0, 0] 在多边形的边上
|
232 | isPointInPolygon(polygon, 0, 0); // true
|
233 | ```
|
234 |
|
235 | ### isPolygonsIntersect
|
236 |
|
237 | 判断两个多边形是否相交:
|
238 |
|
239 | ```js
|
240 | isPolygonsIntersect(polygon1, polygon2);
|
241 | ```
|
242 |
|
243 | ## Benchmarks
|
244 |
|
245 | Build first.
|
246 |
|
247 | ```bash
|
248 | yarn run benchmarks
|
249 | ```
|
250 |
|
251 | We can get the following output in the console, it can be seen that the same method from 5.0 is ~3 times faster than 4.0.
|
252 |
|
253 | ```js
|
254 | // logs
|
255 | // Path2String#4.0 x 14,795 ops/sec ±3.35% (79 runs sampled)
|
256 | // Path2String#5.0 x 51,710 ops/sec ±2.05% (85 runs sampled)
|
257 | // Fastest is Path2String#5.0
|
258 |
|
259 | // Path2Absolute#4.0 x 14,524 ops/sec ±2.55% (80 runs sampled)
|
260 | // Path2Absolute#5.0 x 35,120 ops/sec ±3.10% (81 runs sampled)
|
261 | // Fastest is Path2Absolute#5.0
|
262 | ```
|
263 |
|
264 | ## License
|
265 |
|
266 | MIT@[AntV](https://github.com/antvis).
|