UNPKG

12.4 kBJavaScriptView Raw
1import { __extends } from "tslib";
2import Path from '../graphic/Path.js';
3import PathProxy from '../core/PathProxy.js';
4import transformPath from './transformPath.js';
5import { extend } from '../core/util.js';
6var mathSqrt = Math.sqrt;
7var mathSin = Math.sin;
8var mathCos = Math.cos;
9var PI = Math.PI;
10function vMag(v) {
11 return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
12}
13;
14function vRatio(u, v) {
15 return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
16}
17;
18function vAngle(u, v) {
19 return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)
20 * Math.acos(vRatio(u, v));
21}
22;
23function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {
24 var psi = psiDeg * (PI / 180.0);
25 var xp = mathCos(psi) * (x1 - x2) / 2.0
26 + mathSin(psi) * (y1 - y2) / 2.0;
27 var yp = -1 * mathSin(psi) * (x1 - x2) / 2.0
28 + mathCos(psi) * (y1 - y2) / 2.0;
29 var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);
30 if (lambda > 1) {
31 rx *= mathSqrt(lambda);
32 ry *= mathSqrt(lambda);
33 }
34 var f = (fa === fs ? -1 : 1)
35 * mathSqrt((((rx * rx) * (ry * ry))
36 - ((rx * rx) * (yp * yp))
37 - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp)
38 + (ry * ry) * (xp * xp))) || 0;
39 var cxp = f * rx * yp / ry;
40 var cyp = f * -ry * xp / rx;
41 var cx = (x1 + x2) / 2.0
42 + mathCos(psi) * cxp
43 - mathSin(psi) * cyp;
44 var cy = (y1 + y2) / 2.0
45 + mathSin(psi) * cxp
46 + mathCos(psi) * cyp;
47 var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]);
48 var u = [(xp - cxp) / rx, (yp - cyp) / ry];
49 var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry];
50 var dTheta = vAngle(u, v);
51 if (vRatio(u, v) <= -1) {
52 dTheta = PI;
53 }
54 if (vRatio(u, v) >= 1) {
55 dTheta = 0;
56 }
57 if (dTheta < 0) {
58 var n = Math.round(dTheta / PI * 1e6) / 1e6;
59 dTheta = PI * 2 + (n % 2) * PI;
60 }
61 path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
62}
63var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
64var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
65function createPathProxyFromString(data) {
66 var path = new PathProxy();
67 if (!data) {
68 return path;
69 }
70 var cpx = 0;
71 var cpy = 0;
72 var subpathX = cpx;
73 var subpathY = cpy;
74 var prevCmd;
75 var CMD = PathProxy.CMD;
76 var cmdList = data.match(commandReg);
77 if (!cmdList) {
78 return path;
79 }
80 for (var l = 0; l < cmdList.length; l++) {
81 var cmdText = cmdList[l];
82 var cmdStr = cmdText.charAt(0);
83 var cmd = void 0;
84 var p = cmdText.match(numberReg) || [];
85 var pLen = p.length;
86 for (var i = 0; i < pLen; i++) {
87 p[i] = parseFloat(p[i]);
88 }
89 var off = 0;
90 while (off < pLen) {
91 var ctlPtx = void 0;
92 var ctlPty = void 0;
93 var rx = void 0;
94 var ry = void 0;
95 var psi = void 0;
96 var fa = void 0;
97 var fs = void 0;
98 var x1 = cpx;
99 var y1 = cpy;
100 var len = void 0;
101 var pathData = void 0;
102 switch (cmdStr) {
103 case 'l':
104 cpx += p[off++];
105 cpy += p[off++];
106 cmd = CMD.L;
107 path.addData(cmd, cpx, cpy);
108 break;
109 case 'L':
110 cpx = p[off++];
111 cpy = p[off++];
112 cmd = CMD.L;
113 path.addData(cmd, cpx, cpy);
114 break;
115 case 'm':
116 cpx += p[off++];
117 cpy += p[off++];
118 cmd = CMD.M;
119 path.addData(cmd, cpx, cpy);
120 subpathX = cpx;
121 subpathY = cpy;
122 cmdStr = 'l';
123 break;
124 case 'M':
125 cpx = p[off++];
126 cpy = p[off++];
127 cmd = CMD.M;
128 path.addData(cmd, cpx, cpy);
129 subpathX = cpx;
130 subpathY = cpy;
131 cmdStr = 'L';
132 break;
133 case 'h':
134 cpx += p[off++];
135 cmd = CMD.L;
136 path.addData(cmd, cpx, cpy);
137 break;
138 case 'H':
139 cpx = p[off++];
140 cmd = CMD.L;
141 path.addData(cmd, cpx, cpy);
142 break;
143 case 'v':
144 cpy += p[off++];
145 cmd = CMD.L;
146 path.addData(cmd, cpx, cpy);
147 break;
148 case 'V':
149 cpy = p[off++];
150 cmd = CMD.L;
151 path.addData(cmd, cpx, cpy);
152 break;
153 case 'C':
154 cmd = CMD.C;
155 path.addData(cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]);
156 cpx = p[off - 2];
157 cpy = p[off - 1];
158 break;
159 case 'c':
160 cmd = CMD.C;
161 path.addData(cmd, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy);
162 cpx += p[off - 2];
163 cpy += p[off - 1];
164 break;
165 case 'S':
166 ctlPtx = cpx;
167 ctlPty = cpy;
168 len = path.len();
169 pathData = path.data;
170 if (prevCmd === CMD.C) {
171 ctlPtx += cpx - pathData[len - 4];
172 ctlPty += cpy - pathData[len - 3];
173 }
174 cmd = CMD.C;
175 x1 = p[off++];
176 y1 = p[off++];
177 cpx = p[off++];
178 cpy = p[off++];
179 path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
180 break;
181 case 's':
182 ctlPtx = cpx;
183 ctlPty = cpy;
184 len = path.len();
185 pathData = path.data;
186 if (prevCmd === CMD.C) {
187 ctlPtx += cpx - pathData[len - 4];
188 ctlPty += cpy - pathData[len - 3];
189 }
190 cmd = CMD.C;
191 x1 = cpx + p[off++];
192 y1 = cpy + p[off++];
193 cpx += p[off++];
194 cpy += p[off++];
195 path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
196 break;
197 case 'Q':
198 x1 = p[off++];
199 y1 = p[off++];
200 cpx = p[off++];
201 cpy = p[off++];
202 cmd = CMD.Q;
203 path.addData(cmd, x1, y1, cpx, cpy);
204 break;
205 case 'q':
206 x1 = p[off++] + cpx;
207 y1 = p[off++] + cpy;
208 cpx += p[off++];
209 cpy += p[off++];
210 cmd = CMD.Q;
211 path.addData(cmd, x1, y1, cpx, cpy);
212 break;
213 case 'T':
214 ctlPtx = cpx;
215 ctlPty = cpy;
216 len = path.len();
217 pathData = path.data;
218 if (prevCmd === CMD.Q) {
219 ctlPtx += cpx - pathData[len - 4];
220 ctlPty += cpy - pathData[len - 3];
221 }
222 cpx = p[off++];
223 cpy = p[off++];
224 cmd = CMD.Q;
225 path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
226 break;
227 case 't':
228 ctlPtx = cpx;
229 ctlPty = cpy;
230 len = path.len();
231 pathData = path.data;
232 if (prevCmd === CMD.Q) {
233 ctlPtx += cpx - pathData[len - 4];
234 ctlPty += cpy - pathData[len - 3];
235 }
236 cpx += p[off++];
237 cpy += p[off++];
238 cmd = CMD.Q;
239 path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
240 break;
241 case 'A':
242 rx = p[off++];
243 ry = p[off++];
244 psi = p[off++];
245 fa = p[off++];
246 fs = p[off++];
247 x1 = cpx, y1 = cpy;
248 cpx = p[off++];
249 cpy = p[off++];
250 cmd = CMD.A;
251 processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
252 break;
253 case 'a':
254 rx = p[off++];
255 ry = p[off++];
256 psi = p[off++];
257 fa = p[off++];
258 fs = p[off++];
259 x1 = cpx, y1 = cpy;
260 cpx += p[off++];
261 cpy += p[off++];
262 cmd = CMD.A;
263 processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
264 break;
265 }
266 }
267 if (cmdStr === 'z' || cmdStr === 'Z') {
268 cmd = CMD.Z;
269 path.addData(cmd);
270 cpx = subpathX;
271 cpy = subpathY;
272 }
273 prevCmd = cmd;
274 }
275 path.toStatic();
276 return path;
277}
278var SVGPath = (function (_super) {
279 __extends(SVGPath, _super);
280 function SVGPath() {
281 return _super !== null && _super.apply(this, arguments) || this;
282 }
283 SVGPath.prototype.applyTransform = function (m) { };
284 return SVGPath;
285}(Path));
286function isPathProxy(path) {
287 return path.setData != null;
288}
289function createPathOptions(str, opts) {
290 var pathProxy = createPathProxyFromString(str);
291 var innerOpts = extend({}, opts);
292 innerOpts.buildPath = function (path) {
293 if (isPathProxy(path)) {
294 path.setData(pathProxy.data);
295 var ctx = path.getContext();
296 if (ctx) {
297 path.rebuildPath(ctx, 1);
298 }
299 }
300 else {
301 var ctx = path;
302 pathProxy.rebuildPath(ctx, 1);
303 }
304 };
305 innerOpts.applyTransform = function (m) {
306 transformPath(pathProxy, m);
307 this.dirtyShape();
308 };
309 return innerOpts;
310}
311export function createFromString(str, opts) {
312 return new SVGPath(createPathOptions(str, opts));
313}
314export function extendFromString(str, defaultOpts) {
315 var innerOpts = createPathOptions(str, defaultOpts);
316 var Sub = (function (_super) {
317 __extends(Sub, _super);
318 function Sub(opts) {
319 var _this = _super.call(this, opts) || this;
320 _this.applyTransform = innerOpts.applyTransform;
321 _this.buildPath = innerOpts.buildPath;
322 return _this;
323 }
324 return Sub;
325 }(SVGPath));
326 return Sub;
327}
328export function mergePath(pathEls, opts) {
329 var pathList = [];
330 var len = pathEls.length;
331 for (var i = 0; i < len; i++) {
332 var pathEl = pathEls[i];
333 pathList.push(pathEl.getUpdatedPathProxy(true));
334 }
335 var pathBundle = new Path(opts);
336 pathBundle.createPathProxy();
337 pathBundle.buildPath = function (path) {
338 if (isPathProxy(path)) {
339 path.appendPath(pathList);
340 var ctx = path.getContext();
341 if (ctx) {
342 path.rebuildPath(ctx, 1);
343 }
344 }
345 };
346 return pathBundle;
347}
348export function clonePath(sourcePath, opts) {
349 opts = opts || {};
350 var path = new Path();
351 if (sourcePath.shape) {
352 path.setShape(sourcePath.shape);
353 }
354 path.setStyle(sourcePath.style);
355 if (opts.bakeTransform) {
356 transformPath(path.path, sourcePath.getComputedTransform());
357 }
358 else {
359 if (opts.toLocal) {
360 path.setLocalTransform(sourcePath.getComputedTransform());
361 }
362 else {
363 path.copyTransform(sourcePath);
364 }
365 }
366 path.buildPath = sourcePath.buildPath;
367 path.applyTransform = path.applyTransform;
368 path.z = sourcePath.z;
369 path.z2 = sourcePath.z2;
370 path.zlevel = sourcePath.zlevel;
371 return path;
372}