1 | import Group from '../graphic/Group.js';
|
2 | import ZRImage from '../graphic/Image.js';
|
3 | import Circle from '../graphic/shape/Circle.js';
|
4 | import Rect from '../graphic/shape/Rect.js';
|
5 | import Ellipse from '../graphic/shape/Ellipse.js';
|
6 | import Line from '../graphic/shape/Line.js';
|
7 | import Polygon from '../graphic/shape/Polygon.js';
|
8 | import Polyline from '../graphic/shape/Polyline.js';
|
9 | import * as matrix from '../core/matrix.js';
|
10 | import { createFromString } from './path.js';
|
11 | import { defaults, trim, each, map, keys, hasOwn } from '../core/util.js';
|
12 | import LinearGradient from '../graphic/LinearGradient.js';
|
13 | import RadialGradient from '../graphic/RadialGradient.js';
|
14 | import TSpan from '../graphic/TSpan.js';
|
15 | import { parseXML } from './parseXML.js';
|
16 | ;
|
17 | var nodeParsers;
|
18 | var INHERITABLE_STYLE_ATTRIBUTES_MAP = {
|
19 | 'fill': 'fill',
|
20 | 'stroke': 'stroke',
|
21 | 'stroke-width': 'lineWidth',
|
22 | 'opacity': 'opacity',
|
23 | 'fill-opacity': 'fillOpacity',
|
24 | 'stroke-opacity': 'strokeOpacity',
|
25 | 'stroke-dasharray': 'lineDash',
|
26 | 'stroke-dashoffset': 'lineDashOffset',
|
27 | 'stroke-linecap': 'lineCap',
|
28 | 'stroke-linejoin': 'lineJoin',
|
29 | 'stroke-miterlimit': 'miterLimit',
|
30 | 'font-family': 'fontFamily',
|
31 | 'font-size': 'fontSize',
|
32 | 'font-style': 'fontStyle',
|
33 | 'font-weight': 'fontWeight',
|
34 | 'text-anchor': 'textAlign',
|
35 | 'visibility': 'visibility',
|
36 | 'display': 'display'
|
37 | };
|
38 | var INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS = keys(INHERITABLE_STYLE_ATTRIBUTES_MAP);
|
39 | var SELF_STYLE_ATTRIBUTES_MAP = {
|
40 | 'alignment-baseline': 'textBaseline',
|
41 | 'stop-color': 'stopColor'
|
42 | };
|
43 | var SELF_STYLE_ATTRIBUTES_MAP_KEYS = keys(SELF_STYLE_ATTRIBUTES_MAP);
|
44 | var SVGParser = (function () {
|
45 | function SVGParser() {
|
46 | this._defs = {};
|
47 | this._root = null;
|
48 | }
|
49 | SVGParser.prototype.parse = function (xml, opt) {
|
50 | opt = opt || {};
|
51 | var svg = parseXML(xml);
|
52 | if (process.env.NODE_ENV !== 'production') {
|
53 | if (!svg) {
|
54 | throw new Error('Illegal svg');
|
55 | }
|
56 | }
|
57 | this._defsUsePending = [];
|
58 | var root = new Group();
|
59 | this._root = root;
|
60 | var named = [];
|
61 | var viewBox = svg.getAttribute('viewBox') || '';
|
62 | var width = parseFloat((svg.getAttribute('width') || opt.width));
|
63 | var height = parseFloat((svg.getAttribute('height') || opt.height));
|
64 | isNaN(width) && (width = null);
|
65 | isNaN(height) && (height = null);
|
66 | parseAttributes(svg, root, null, true, false);
|
67 | var child = svg.firstChild;
|
68 | while (child) {
|
69 | this._parseNode(child, root, named, null, false, false);
|
70 | child = child.nextSibling;
|
71 | }
|
72 | applyDefs(this._defs, this._defsUsePending);
|
73 | this._defsUsePending = [];
|
74 | var viewBoxRect;
|
75 | var viewBoxTransform;
|
76 | if (viewBox) {
|
77 | var viewBoxArr = splitNumberSequence(viewBox);
|
78 | if (viewBoxArr.length >= 4) {
|
79 | viewBoxRect = {
|
80 | x: parseFloat((viewBoxArr[0] || 0)),
|
81 | y: parseFloat((viewBoxArr[1] || 0)),
|
82 | width: parseFloat(viewBoxArr[2]),
|
83 | height: parseFloat(viewBoxArr[3])
|
84 | };
|
85 | }
|
86 | }
|
87 | if (viewBoxRect && width != null && height != null) {
|
88 | viewBoxTransform = makeViewBoxTransform(viewBoxRect, { x: 0, y: 0, width: width, height: height });
|
89 | if (!opt.ignoreViewBox) {
|
90 | var elRoot = root;
|
91 | root = new Group();
|
92 | root.add(elRoot);
|
93 | elRoot.scaleX = elRoot.scaleY = viewBoxTransform.scale;
|
94 | elRoot.x = viewBoxTransform.x;
|
95 | elRoot.y = viewBoxTransform.y;
|
96 | }
|
97 | }
|
98 | if (!opt.ignoreRootClip && width != null && height != null) {
|
99 | root.setClipPath(new Rect({
|
100 | shape: { x: 0, y: 0, width: width, height: height }
|
101 | }));
|
102 | }
|
103 | return {
|
104 | root: root,
|
105 | width: width,
|
106 | height: height,
|
107 | viewBoxRect: viewBoxRect,
|
108 | viewBoxTransform: viewBoxTransform,
|
109 | named: named
|
110 | };
|
111 | };
|
112 | SVGParser.prototype._parseNode = function (xmlNode, parentGroup, named, namedFrom, isInDefs, isInText) {
|
113 | var nodeName = xmlNode.nodeName.toLowerCase();
|
114 | var el;
|
115 | var namedFromForSub = namedFrom;
|
116 | if (nodeName === 'defs') {
|
117 | isInDefs = true;
|
118 | }
|
119 | if (nodeName === 'text') {
|
120 | isInText = true;
|
121 | }
|
122 | if (nodeName === 'defs' || nodeName === 'switch') {
|
123 | el = parentGroup;
|
124 | }
|
125 | else {
|
126 | if (!isInDefs) {
|
127 | var parser_1 = nodeParsers[nodeName];
|
128 | if (parser_1 && hasOwn(nodeParsers, nodeName)) {
|
129 | el = parser_1.call(this, xmlNode, parentGroup);
|
130 | var nameAttr = xmlNode.getAttribute('name');
|
131 | if (nameAttr) {
|
132 | var newNamed = {
|
133 | name: nameAttr,
|
134 | namedFrom: null,
|
135 | svgNodeTagLower: nodeName,
|
136 | el: el
|
137 | };
|
138 | named.push(newNamed);
|
139 | if (nodeName === 'g') {
|
140 | namedFromForSub = newNamed;
|
141 | }
|
142 | }
|
143 | else if (namedFrom) {
|
144 | named.push({
|
145 | name: namedFrom.name,
|
146 | namedFrom: namedFrom,
|
147 | svgNodeTagLower: nodeName,
|
148 | el: el
|
149 | });
|
150 | }
|
151 | parentGroup.add(el);
|
152 | }
|
153 | }
|
154 | var parser = paintServerParsers[nodeName];
|
155 | if (parser && hasOwn(paintServerParsers, nodeName)) {
|
156 | var def = parser.call(this, xmlNode);
|
157 | var id = xmlNode.getAttribute('id');
|
158 | if (id) {
|
159 | this._defs[id] = def;
|
160 | }
|
161 | }
|
162 | }
|
163 | if (el && el.isGroup) {
|
164 | var child = xmlNode.firstChild;
|
165 | while (child) {
|
166 | if (child.nodeType === 1) {
|
167 | this._parseNode(child, el, named, namedFromForSub, isInDefs, isInText);
|
168 | }
|
169 | else if (child.nodeType === 3 && isInText) {
|
170 | this._parseText(child, el);
|
171 | }
|
172 | child = child.nextSibling;
|
173 | }
|
174 | }
|
175 | };
|
176 | SVGParser.prototype._parseText = function (xmlNode, parentGroup) {
|
177 | var text = new TSpan({
|
178 | style: {
|
179 | text: xmlNode.textContent
|
180 | },
|
181 | silent: true,
|
182 | x: this._textX || 0,
|
183 | y: this._textY || 0
|
184 | });
|
185 | inheritStyle(parentGroup, text);
|
186 | parseAttributes(xmlNode, text, this._defsUsePending, false, false);
|
187 | applyTextAlignment(text, parentGroup);
|
188 | var textStyle = text.style;
|
189 | var fontSize = textStyle.fontSize;
|
190 | if (fontSize && fontSize < 9) {
|
191 | textStyle.fontSize = 9;
|
192 | text.scaleX *= fontSize / 9;
|
193 | text.scaleY *= fontSize / 9;
|
194 | }
|
195 | var font = (textStyle.fontSize || textStyle.fontFamily) && [
|
196 | textStyle.fontStyle,
|
197 | textStyle.fontWeight,
|
198 | (textStyle.fontSize || 12) + 'px',
|
199 | textStyle.fontFamily || 'sans-serif'
|
200 | ].join(' ');
|
201 | textStyle.font = font;
|
202 | var rect = text.getBoundingRect();
|
203 | this._textX += rect.width;
|
204 | parentGroup.add(text);
|
205 | return text;
|
206 | };
|
207 | SVGParser.internalField = (function () {
|
208 | nodeParsers = {
|
209 | 'g': function (xmlNode, parentGroup) {
|
210 | var g = new Group();
|
211 | inheritStyle(parentGroup, g);
|
212 | parseAttributes(xmlNode, g, this._defsUsePending, false, false);
|
213 | return g;
|
214 | },
|
215 | 'rect': function (xmlNode, parentGroup) {
|
216 | var rect = new Rect();
|
217 | inheritStyle(parentGroup, rect);
|
218 | parseAttributes(xmlNode, rect, this._defsUsePending, false, false);
|
219 | rect.setShape({
|
220 | x: parseFloat(xmlNode.getAttribute('x') || '0'),
|
221 | y: parseFloat(xmlNode.getAttribute('y') || '0'),
|
222 | width: parseFloat(xmlNode.getAttribute('width') || '0'),
|
223 | height: parseFloat(xmlNode.getAttribute('height') || '0')
|
224 | });
|
225 | rect.silent = true;
|
226 | return rect;
|
227 | },
|
228 | 'circle': function (xmlNode, parentGroup) {
|
229 | var circle = new Circle();
|
230 | inheritStyle(parentGroup, circle);
|
231 | parseAttributes(xmlNode, circle, this._defsUsePending, false, false);
|
232 | circle.setShape({
|
233 | cx: parseFloat(xmlNode.getAttribute('cx') || '0'),
|
234 | cy: parseFloat(xmlNode.getAttribute('cy') || '0'),
|
235 | r: parseFloat(xmlNode.getAttribute('r') || '0')
|
236 | });
|
237 | circle.silent = true;
|
238 | return circle;
|
239 | },
|
240 | 'line': function (xmlNode, parentGroup) {
|
241 | var line = new Line();
|
242 | inheritStyle(parentGroup, line);
|
243 | parseAttributes(xmlNode, line, this._defsUsePending, false, false);
|
244 | line.setShape({
|
245 | x1: parseFloat(xmlNode.getAttribute('x1') || '0'),
|
246 | y1: parseFloat(xmlNode.getAttribute('y1') || '0'),
|
247 | x2: parseFloat(xmlNode.getAttribute('x2') || '0'),
|
248 | y2: parseFloat(xmlNode.getAttribute('y2') || '0')
|
249 | });
|
250 | line.silent = true;
|
251 | return line;
|
252 | },
|
253 | 'ellipse': function (xmlNode, parentGroup) {
|
254 | var ellipse = new Ellipse();
|
255 | inheritStyle(parentGroup, ellipse);
|
256 | parseAttributes(xmlNode, ellipse, this._defsUsePending, false, false);
|
257 | ellipse.setShape({
|
258 | cx: parseFloat(xmlNode.getAttribute('cx') || '0'),
|
259 | cy: parseFloat(xmlNode.getAttribute('cy') || '0'),
|
260 | rx: parseFloat(xmlNode.getAttribute('rx') || '0'),
|
261 | ry: parseFloat(xmlNode.getAttribute('ry') || '0')
|
262 | });
|
263 | ellipse.silent = true;
|
264 | return ellipse;
|
265 | },
|
266 | 'polygon': function (xmlNode, parentGroup) {
|
267 | var pointsStr = xmlNode.getAttribute('points');
|
268 | var pointsArr;
|
269 | if (pointsStr) {
|
270 | pointsArr = parsePoints(pointsStr);
|
271 | }
|
272 | var polygon = new Polygon({
|
273 | shape: {
|
274 | points: pointsArr || []
|
275 | },
|
276 | silent: true
|
277 | });
|
278 | inheritStyle(parentGroup, polygon);
|
279 | parseAttributes(xmlNode, polygon, this._defsUsePending, false, false);
|
280 | return polygon;
|
281 | },
|
282 | 'polyline': function (xmlNode, parentGroup) {
|
283 | var pointsStr = xmlNode.getAttribute('points');
|
284 | var pointsArr;
|
285 | if (pointsStr) {
|
286 | pointsArr = parsePoints(pointsStr);
|
287 | }
|
288 | var polyline = new Polyline({
|
289 | shape: {
|
290 | points: pointsArr || []
|
291 | },
|
292 | silent: true
|
293 | });
|
294 | inheritStyle(parentGroup, polyline);
|
295 | parseAttributes(xmlNode, polyline, this._defsUsePending, false, false);
|
296 | return polyline;
|
297 | },
|
298 | 'image': function (xmlNode, parentGroup) {
|
299 | var img = new ZRImage();
|
300 | inheritStyle(parentGroup, img);
|
301 | parseAttributes(xmlNode, img, this._defsUsePending, false, false);
|
302 | img.setStyle({
|
303 | image: xmlNode.getAttribute('xlink:href') || xmlNode.getAttribute('href'),
|
304 | x: +xmlNode.getAttribute('x'),
|
305 | y: +xmlNode.getAttribute('y'),
|
306 | width: +xmlNode.getAttribute('width'),
|
307 | height: +xmlNode.getAttribute('height')
|
308 | });
|
309 | img.silent = true;
|
310 | return img;
|
311 | },
|
312 | 'text': function (xmlNode, parentGroup) {
|
313 | var x = xmlNode.getAttribute('x') || '0';
|
314 | var y = xmlNode.getAttribute('y') || '0';
|
315 | var dx = xmlNode.getAttribute('dx') || '0';
|
316 | var dy = xmlNode.getAttribute('dy') || '0';
|
317 | this._textX = parseFloat(x) + parseFloat(dx);
|
318 | this._textY = parseFloat(y) + parseFloat(dy);
|
319 | var g = new Group();
|
320 | inheritStyle(parentGroup, g);
|
321 | parseAttributes(xmlNode, g, this._defsUsePending, false, true);
|
322 | return g;
|
323 | },
|
324 | 'tspan': function (xmlNode, parentGroup) {
|
325 | var x = xmlNode.getAttribute('x');
|
326 | var y = xmlNode.getAttribute('y');
|
327 | if (x != null) {
|
328 | this._textX = parseFloat(x);
|
329 | }
|
330 | if (y != null) {
|
331 | this._textY = parseFloat(y);
|
332 | }
|
333 | var dx = xmlNode.getAttribute('dx') || '0';
|
334 | var dy = xmlNode.getAttribute('dy') || '0';
|
335 | var g = new Group();
|
336 | inheritStyle(parentGroup, g);
|
337 | parseAttributes(xmlNode, g, this._defsUsePending, false, true);
|
338 | this._textX += parseFloat(dx);
|
339 | this._textY += parseFloat(dy);
|
340 | return g;
|
341 | },
|
342 | 'path': function (xmlNode, parentGroup) {
|
343 | var d = xmlNode.getAttribute('d') || '';
|
344 | var path = createFromString(d);
|
345 | inheritStyle(parentGroup, path);
|
346 | parseAttributes(xmlNode, path, this._defsUsePending, false, false);
|
347 | path.silent = true;
|
348 | return path;
|
349 | }
|
350 | };
|
351 | })();
|
352 | return SVGParser;
|
353 | }());
|
354 | var paintServerParsers = {
|
355 | 'lineargradient': function (xmlNode) {
|
356 | var x1 = parseInt(xmlNode.getAttribute('x1') || '0', 10);
|
357 | var y1 = parseInt(xmlNode.getAttribute('y1') || '0', 10);
|
358 | var x2 = parseInt(xmlNode.getAttribute('x2') || '10', 10);
|
359 | var y2 = parseInt(xmlNode.getAttribute('y2') || '0', 10);
|
360 | var gradient = new LinearGradient(x1, y1, x2, y2);
|
361 | parsePaintServerUnit(xmlNode, gradient);
|
362 | parseGradientColorStops(xmlNode, gradient);
|
363 | return gradient;
|
364 | },
|
365 | 'radialgradient': function (xmlNode) {
|
366 | var cx = parseInt(xmlNode.getAttribute('cx') || '0', 10);
|
367 | var cy = parseInt(xmlNode.getAttribute('cy') || '0', 10);
|
368 | var r = parseInt(xmlNode.getAttribute('r') || '0', 10);
|
369 | var gradient = new RadialGradient(cx, cy, r);
|
370 | parsePaintServerUnit(xmlNode, gradient);
|
371 | parseGradientColorStops(xmlNode, gradient);
|
372 | return gradient;
|
373 | }
|
374 | };
|
375 | function parsePaintServerUnit(xmlNode, gradient) {
|
376 | var gradientUnits = xmlNode.getAttribute('gradientUnits');
|
377 | if (gradientUnits === 'userSpaceOnUse') {
|
378 | gradient.global = true;
|
379 | }
|
380 | }
|
381 | function parseGradientColorStops(xmlNode, gradient) {
|
382 | var stop = xmlNode.firstChild;
|
383 | while (stop) {
|
384 | if (stop.nodeType === 1
|
385 | && stop.nodeName.toLocaleLowerCase() === 'stop') {
|
386 | var offsetStr = stop.getAttribute('offset');
|
387 | var offset = void 0;
|
388 | if (offsetStr && offsetStr.indexOf('%') > 0) {
|
389 | offset = parseInt(offsetStr, 10) / 100;
|
390 | }
|
391 | else if (offsetStr) {
|
392 | offset = parseFloat(offsetStr);
|
393 | }
|
394 | else {
|
395 | offset = 0;
|
396 | }
|
397 | var styleVals = {};
|
398 | parseInlineStyle(stop, styleVals, styleVals);
|
399 | var stopColor = styleVals.stopColor
|
400 | || stop.getAttribute('stop-color')
|
401 | || '#000000';
|
402 | gradient.colorStops.push({
|
403 | offset: offset,
|
404 | color: stopColor
|
405 | });
|
406 | }
|
407 | stop = stop.nextSibling;
|
408 | }
|
409 | }
|
410 | function inheritStyle(parent, child) {
|
411 | if (parent && parent.__inheritedStyle) {
|
412 | if (!child.__inheritedStyle) {
|
413 | child.__inheritedStyle = {};
|
414 | }
|
415 | defaults(child.__inheritedStyle, parent.__inheritedStyle);
|
416 | }
|
417 | }
|
418 | function parsePoints(pointsString) {
|
419 | var list = splitNumberSequence(pointsString);
|
420 | var points = [];
|
421 | for (var i = 0; i < list.length; i += 2) {
|
422 | var x = parseFloat(list[i]);
|
423 | var y = parseFloat(list[i + 1]);
|
424 | points.push([x, y]);
|
425 | }
|
426 | return points;
|
427 | }
|
428 | function parseAttributes(xmlNode, el, defsUsePending, onlyInlineStyle, isTextGroup) {
|
429 | var disp = el;
|
430 | var inheritedStyle = disp.__inheritedStyle = disp.__inheritedStyle || {};
|
431 | var selfStyle = {};
|
432 | if (xmlNode.nodeType === 1) {
|
433 | parseTransformAttribute(xmlNode, el);
|
434 | parseInlineStyle(xmlNode, inheritedStyle, selfStyle);
|
435 | if (!onlyInlineStyle) {
|
436 | parseAttributeStyle(xmlNode, inheritedStyle, selfStyle);
|
437 | }
|
438 | }
|
439 | disp.style = disp.style || {};
|
440 | if (inheritedStyle.fill != null) {
|
441 | disp.style.fill = getFillStrokeStyle(disp, 'fill', inheritedStyle.fill, defsUsePending);
|
442 | }
|
443 | if (inheritedStyle.stroke != null) {
|
444 | disp.style.stroke = getFillStrokeStyle(disp, 'stroke', inheritedStyle.stroke, defsUsePending);
|
445 | }
|
446 | each([
|
447 | 'lineWidth', 'opacity', 'fillOpacity', 'strokeOpacity', 'miterLimit', 'fontSize'
|
448 | ], function (propName) {
|
449 | if (inheritedStyle[propName] != null) {
|
450 | disp.style[propName] = parseFloat(inheritedStyle[propName]);
|
451 | }
|
452 | });
|
453 | each([
|
454 | 'lineDashOffset', 'lineCap', 'lineJoin', 'fontWeight', 'fontFamily', 'fontStyle', 'textAlign'
|
455 | ], function (propName) {
|
456 | if (inheritedStyle[propName] != null) {
|
457 | disp.style[propName] = inheritedStyle[propName];
|
458 | }
|
459 | });
|
460 | if (isTextGroup) {
|
461 | disp.__selfStyle = selfStyle;
|
462 | }
|
463 | if (inheritedStyle.lineDash) {
|
464 | disp.style.lineDash = map(splitNumberSequence(inheritedStyle.lineDash), function (str) {
|
465 | return parseFloat(str);
|
466 | });
|
467 | }
|
468 | if (inheritedStyle.visibility === 'hidden' || inheritedStyle.visibility === 'collapse') {
|
469 | disp.invisible = true;
|
470 | }
|
471 | if (inheritedStyle.display === 'none') {
|
472 | disp.ignore = true;
|
473 | }
|
474 | }
|
475 | function applyTextAlignment(text, parentGroup) {
|
476 | var parentSelfStyle = parentGroup.__selfStyle;
|
477 | if (parentSelfStyle) {
|
478 | var textBaseline = parentSelfStyle.textBaseline;
|
479 | var zrTextBaseline = textBaseline;
|
480 | if (!textBaseline || textBaseline === 'auto') {
|
481 | zrTextBaseline = 'alphabetic';
|
482 | }
|
483 | else if (textBaseline === 'baseline') {
|
484 | zrTextBaseline = 'alphabetic';
|
485 | }
|
486 | else if (textBaseline === 'before-edge' || textBaseline === 'text-before-edge') {
|
487 | zrTextBaseline = 'top';
|
488 | }
|
489 | else if (textBaseline === 'after-edge' || textBaseline === 'text-after-edge') {
|
490 | zrTextBaseline = 'bottom';
|
491 | }
|
492 | else if (textBaseline === 'central' || textBaseline === 'mathematical') {
|
493 | zrTextBaseline = 'middle';
|
494 | }
|
495 | text.style.textBaseline = zrTextBaseline;
|
496 | }
|
497 | var parentInheritedStyle = parentGroup.__inheritedStyle;
|
498 | if (parentInheritedStyle) {
|
499 | var textAlign = parentInheritedStyle.textAlign;
|
500 | var zrTextAlign = textAlign;
|
501 | if (textAlign) {
|
502 | if (textAlign === 'middle') {
|
503 | zrTextAlign = 'center';
|
504 | }
|
505 | text.style.textAlign = zrTextAlign;
|
506 | }
|
507 | }
|
508 | }
|
509 | var urlRegex = /^url\(\s*#(.*?)\)/;
|
510 | function getFillStrokeStyle(el, method, str, defsUsePending) {
|
511 | var urlMatch = str && str.match(urlRegex);
|
512 | if (urlMatch) {
|
513 | var url = trim(urlMatch[1]);
|
514 | defsUsePending.push([el, method, url]);
|
515 | return;
|
516 | }
|
517 | if (str === 'none') {
|
518 | str = null;
|
519 | }
|
520 | return str;
|
521 | }
|
522 | function applyDefs(defs, defsUsePending) {
|
523 | for (var i = 0; i < defsUsePending.length; i++) {
|
524 | var item = defsUsePending[i];
|
525 | item[0].style[item[1]] = defs[item[2]];
|
526 | }
|
527 | }
|
528 | var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
|
529 | function splitNumberSequence(rawStr) {
|
530 | return rawStr.match(numberReg) || [];
|
531 | }
|
532 | var transformRegex = /(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.eE,]*)\)/g;
|
533 | var DEGREE_TO_ANGLE = Math.PI / 180;
|
534 | function parseTransformAttribute(xmlNode, node) {
|
535 | var transform = xmlNode.getAttribute('transform');
|
536 | if (transform) {
|
537 | transform = transform.replace(/,/g, ' ');
|
538 | var transformOps_1 = [];
|
539 | var mt = null;
|
540 | transform.replace(transformRegex, function (str, type, value) {
|
541 | transformOps_1.push(type, value);
|
542 | return '';
|
543 | });
|
544 | for (var i = transformOps_1.length - 1; i > 0; i -= 2) {
|
545 | var value = transformOps_1[i];
|
546 | var type = transformOps_1[i - 1];
|
547 | var valueArr = splitNumberSequence(value);
|
548 | mt = mt || matrix.create();
|
549 | switch (type) {
|
550 | case 'translate':
|
551 | matrix.translate(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || '0')]);
|
552 | break;
|
553 | case 'scale':
|
554 | matrix.scale(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || valueArr[0])]);
|
555 | break;
|
556 | case 'rotate':
|
557 | matrix.rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE, [
|
558 | parseFloat(valueArr[1] || '0'),
|
559 | parseFloat(valueArr[2] || '0')
|
560 | ]);
|
561 | break;
|
562 | case 'skewX':
|
563 | var sx = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
|
564 | matrix.mul(mt, [1, 0, sx, 1, 0, 0], mt);
|
565 | break;
|
566 | case 'skewY':
|
567 | var sy = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
|
568 | matrix.mul(mt, [1, sy, 0, 1, 0, 0], mt);
|
569 | break;
|
570 | case 'matrix':
|
571 | mt[0] = parseFloat(valueArr[0]);
|
572 | mt[1] = parseFloat(valueArr[1]);
|
573 | mt[2] = parseFloat(valueArr[2]);
|
574 | mt[3] = parseFloat(valueArr[3]);
|
575 | mt[4] = parseFloat(valueArr[4]);
|
576 | mt[5] = parseFloat(valueArr[5]);
|
577 | break;
|
578 | }
|
579 | }
|
580 | node.setLocalTransform(mt);
|
581 | }
|
582 | }
|
583 | var styleRegex = /([^\s:;]+)\s*:\s*([^:;]+)/g;
|
584 | function parseInlineStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
|
585 | var style = xmlNode.getAttribute('style');
|
586 | if (!style) {
|
587 | return;
|
588 | }
|
589 | styleRegex.lastIndex = 0;
|
590 | var styleRegResult;
|
591 | while ((styleRegResult = styleRegex.exec(style)) != null) {
|
592 | var svgStlAttr = styleRegResult[1];
|
593 | var zrInheritableStlAttr = hasOwn(INHERITABLE_STYLE_ATTRIBUTES_MAP, svgStlAttr)
|
594 | ? INHERITABLE_STYLE_ATTRIBUTES_MAP[svgStlAttr]
|
595 | : null;
|
596 | if (zrInheritableStlAttr) {
|
597 | inheritableStyleResult[zrInheritableStlAttr] = styleRegResult[2];
|
598 | }
|
599 | var zrSelfStlAttr = hasOwn(SELF_STYLE_ATTRIBUTES_MAP, svgStlAttr)
|
600 | ? SELF_STYLE_ATTRIBUTES_MAP[svgStlAttr]
|
601 | : null;
|
602 | if (zrSelfStlAttr) {
|
603 | selfStyleResult[zrSelfStlAttr] = styleRegResult[2];
|
604 | }
|
605 | }
|
606 | }
|
607 | function parseAttributeStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
|
608 | for (var i = 0; i < INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
|
609 | var svgAttrName = INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS[i];
|
610 | var attrValue = xmlNode.getAttribute(svgAttrName);
|
611 | if (attrValue != null) {
|
612 | inheritableStyleResult[INHERITABLE_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
|
613 | }
|
614 | }
|
615 | for (var i = 0; i < SELF_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
|
616 | var svgAttrName = SELF_STYLE_ATTRIBUTES_MAP_KEYS[i];
|
617 | var attrValue = xmlNode.getAttribute(svgAttrName);
|
618 | if (attrValue != null) {
|
619 | selfStyleResult[SELF_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
|
620 | }
|
621 | }
|
622 | }
|
623 | export function makeViewBoxTransform(viewBoxRect, boundingRect) {
|
624 | var scaleX = boundingRect.width / viewBoxRect.width;
|
625 | var scaleY = boundingRect.height / viewBoxRect.height;
|
626 | var scale = Math.min(scaleX, scaleY);
|
627 | return {
|
628 | scale: scale,
|
629 | x: -(viewBoxRect.x + viewBoxRect.width / 2) * scale + (boundingRect.x + boundingRect.width / 2),
|
630 | y: -(viewBoxRect.y + viewBoxRect.height / 2) * scale + (boundingRect.y + boundingRect.height / 2)
|
631 | };
|
632 | }
|
633 | export function parseSVG(xml, opt) {
|
634 | var parser = new SVGParser();
|
635 | return parser.parse(xml, opt);
|
636 | }
|
637 | export { parseXML };
|