UNPKG

5.56 kBJavaScriptView Raw
1import { __read, __spreadArray } from "tslib";
2import { path2Absolute, path2Segments, path2Curve } from '@antv/util';
3import { Cubic as CubicUtil } from '@antv/g-math';
4import { clonePath, equalizeSegments, getDrawDirection, getRotatedCurve, reverseCurve } from '../../utils/path';
5import { Rectangle } from '../../shapes/Rectangle';
6export function parsePath(path, object) {
7 var absolutePath = path2Absolute(path);
8 var hasArc = hasArcOrBezier(absolutePath);
9 var clonedAbsolutePath = absolutePath.slice();
10
11 var _a = extractPolygons(clonedAbsolutePath),
12 polygons = _a.polygons,
13 polylines = _a.polylines; // convert to curves to do morphing & picking later
14 // @see http://thednp.github.io/kute.js/svgCubicMorph.html
15
16
17 var _b = __read(path2Curve(clonedAbsolutePath, true), 2),
18 curve = _b[0],
19 zCommandIndexes = _b[1];
20
21 var segments = path2Segments(clonedAbsolutePath);
22
23 var _c = calcLength(curve),
24 totalLength = _c.totalLength,
25 curveSegments = _c.curveSegments;
26
27 var rect = getPathBBox(curve);
28
29 if (object) {
30 object.parsedStyle.defX = rect.x;
31 object.parsedStyle.defY = rect.y;
32 }
33
34 return {
35 absolutePath: absolutePath,
36 hasArc: hasArc,
37 segments: segments,
38 polygons: polygons,
39 polylines: polylines,
40 curve: curve,
41 totalLength: totalLength,
42 curveSegments: curveSegments,
43 zCommandIndexes: zCommandIndexes,
44 rect: rect
45 };
46}
47
48function hasArcOrBezier(path) {
49 var hasArc = false;
50 var count = path.length;
51
52 for (var i = 0; i < count; i++) {
53 var params = path[i];
54 var cmd = params[0];
55
56 if (cmd === 'C' || cmd === 'A' || cmd === 'Q') {
57 hasArc = true;
58 break;
59 }
60 }
61
62 return hasArc;
63}
64
65function extractPolygons(pathArray) {
66 var polygons = [];
67 var polylines = [];
68 var points = []; // 防止第一个命令不是 'M'
69
70 for (var i = 0; i < pathArray.length; i++) {
71 var params = pathArray[i];
72 var cmd = params[0];
73
74 if (cmd === 'M') {
75 // 遇到 'M' 判定是否是新数组,新数组中没有点
76 if (points.length) {
77 // 如果存在点,则说明没有遇到 'Z',开始了一个新的多边形
78 polylines.push(points);
79 points = []; // 创建新的点
80 }
81
82 points.push([params[1], params[2]]);
83 } else if (cmd === 'Z') {
84 if (points.length) {
85 // 存在点
86 polygons.push(points);
87 points = []; // 开始新的点集合
88 } // 如果不存在点,同时 'Z',则说明是错误,不处理
89
90 } else {
91 points.push([params[1], params[2]]);
92 }
93 } // 说明 points 未放入 polygons 或者 polyline
94 // 仅当只有一个 M,没有 Z 时会发生这种情况
95
96
97 if (points.length > 0) {
98 polylines.push(points);
99 }
100
101 return {
102 polygons: polygons,
103 polylines: polylines
104 };
105}
106
107function calcLength(curve) {
108 var totalLength = 0;
109 var tempLength = 0; // 每段 curve 对应起止点的长度比例列表,形如: [[0, 0.25], [0.25, 0.6]. [0.6, 0.9], [0.9, 1]]
110
111 var curveSegments = [];
112 var segmentT;
113 var segmentL;
114 var segmentN;
115 var l;
116
117 if (!curve) {
118 return {
119 curveSegments: [],
120 totalLength: totalLength
121 };
122 }
123
124 curve.forEach(function (segment, i) {
125 segmentN = curve[i + 1];
126 l = segment.length;
127
128 if (segmentN) {
129 totalLength += CubicUtil.length(segment[l - 2], segment[l - 1], segmentN[1], segmentN[2], segmentN[3], segmentN[4], segmentN[5], segmentN[6]) || 0;
130 }
131 });
132
133 if (totalLength === 0) {
134 return {
135 curveSegments: [],
136 totalLength: totalLength
137 };
138 }
139
140 curve.forEach(function (segment, i) {
141 segmentN = curve[i + 1];
142 l = segment.length;
143
144 if (segmentN) {
145 segmentT = [];
146 segmentT[0] = tempLength / totalLength;
147 segmentL = CubicUtil.length(segment[l - 2], segment[l - 1], segmentN[1], segmentN[2], segmentN[3], segmentN[4], segmentN[5], segmentN[6]); // 当 path 不连续时,segmentL 可能为空,为空时需要作为 0 处理
148
149 tempLength += segmentL || 0;
150 segmentT[1] = tempLength / totalLength;
151 curveSegments.push(segmentT);
152 }
153 });
154 return {
155 curveSegments: curveSegments,
156 totalLength: totalLength
157 };
158}
159
160function getPathBBox(segments) {
161 var x = 0;
162 var y = 0;
163 var X = [];
164 var Y = [];
165 segments.forEach(function (segment) {
166 var _a = __read(segment.slice(-2), 2),
167 s1 = _a[0],
168 s2 = _a[1];
169
170 if (segment[0] === 'M') {
171 x = s1;
172 y = s2;
173 X.push(s1);
174 Y.push(s2);
175 } else if (segment[0] === 'C') {
176 // @ts-ignore
177 var dim = CubicUtil.box.apply(CubicUtil, __spreadArray([], __read([x, y].concat(segment.slice(1))), false));
178 X = X.concat(dim.x, dim.x + dim.width);
179 Y = Y.concat(dim.y, dim.y + dim.height);
180 x = s1;
181 y = s2;
182 }
183 });
184 var xTop = Math.min.apply(0, X);
185 var yTop = Math.min.apply(0, Y);
186 var xBot = Math.max.apply(0, X);
187 var yBot = Math.max.apply(0, Y);
188 var width = xBot - xTop;
189 var height = yBot - yTop;
190 return new Rectangle(xTop, yTop, width, height);
191}
192
193export function mergePaths(left, right, object) {
194 var curve1 = left.curve;
195 var curve2 = right.curve;
196 var curves = [curve1, curve2];
197
198 if (curve1.length !== curve2.length) {
199 curves = equalizeSegments(curve1, curve2);
200 }
201
202 var curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1]) ? reverseCurve(curves[0]) : clonePath(curves[0]);
203 return [curve0, getRotatedCurve(curves[1], curve0), function (pathArray) {
204 // need converting to path string?
205 return pathArray;
206 }];
207}
\No newline at end of file