cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
625 lines (624 loc) • 21.6 kB
JavaScript
import Group from "../graphic/Group.mjs";
import ZRImage from "../graphic/Image.mjs";
import Circle from "../graphic/shape/Circle.mjs";
import Rect from "../graphic/shape/Rect.mjs";
import Ellipse from "../graphic/shape/Ellipse.mjs";
import Line from "../graphic/shape/Line.mjs";
import Polygon from "../graphic/shape/Polygon.mjs";
import Polyline from "../graphic/shape/Polyline.mjs";
import { mul, rotate, scale, translate, create } from "../core/matrix.mjs";
import { createFromString } from "./path.mjs";
import { keys, hasOwn, defaults, each, map, trim } from "../core/util.mjs";
import LinearGradient from "../graphic/LinearGradient.mjs";
import RadialGradient from "../graphic/RadialGradient.mjs";
import TSpan from "../graphic/TSpan.mjs";
import { parseXML } from "./parseXML.mjs";
export { parseXML } from "./parseXML.mjs";
var nodeParsers;
var INHERITABLE_STYLE_ATTRIBUTES_MAP = {
"fill": "fill",
"stroke": "stroke",
"stroke-width": "lineWidth",
"opacity": "opacity",
"fill-opacity": "fillOpacity",
"stroke-opacity": "strokeOpacity",
"stroke-dasharray": "lineDash",
"stroke-dashoffset": "lineDashOffset",
"stroke-linecap": "lineCap",
"stroke-linejoin": "lineJoin",
"stroke-miterlimit": "miterLimit",
"font-family": "fontFamily",
"font-size": "fontSize",
"font-style": "fontStyle",
"font-weight": "fontWeight",
"text-anchor": "textAlign",
"visibility": "visibility",
"display": "display"
};
var INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS = keys(INHERITABLE_STYLE_ATTRIBUTES_MAP);
var SELF_STYLE_ATTRIBUTES_MAP = {
"alignment-baseline": "textBaseline",
"stop-color": "stopColor"
};
var SELF_STYLE_ATTRIBUTES_MAP_KEYS = keys(SELF_STYLE_ATTRIBUTES_MAP);
var SVGParser = function() {
function SVGParser2() {
this._defs = {};
this._root = null;
}
SVGParser2.prototype.parse = function(xml, opt) {
opt = opt || {};
var svg = parseXML(xml);
this._defsUsePending = [];
var root = new Group();
this._root = root;
var named = [];
var viewBox = svg.getAttribute("viewBox") || "";
var width = parseFloat(svg.getAttribute("width") || opt.width);
var height = parseFloat(svg.getAttribute("height") || opt.height);
isNaN(width) && (width = null);
isNaN(height) && (height = null);
parseAttributes(svg, root, null, true, false);
var child = svg.firstChild;
while (child) {
this._parseNode(child, root, named, null, false, false);
child = child.nextSibling;
}
applyDefs(this._defs, this._defsUsePending);
this._defsUsePending = [];
var viewBoxRect;
var viewBoxTransform;
if (viewBox) {
var viewBoxArr = splitNumberSequence(viewBox);
if (viewBoxArr.length >= 4) {
viewBoxRect = {
x: parseFloat(viewBoxArr[0] || 0),
y: parseFloat(viewBoxArr[1] || 0),
width: parseFloat(viewBoxArr[2]),
height: parseFloat(viewBoxArr[3])
};
}
}
if (viewBoxRect && width != null && height != null) {
viewBoxTransform = makeViewBoxTransform(viewBoxRect, { x: 0, y: 0, width, height });
if (!opt.ignoreViewBox) {
var elRoot = root;
root = new Group();
root.add(elRoot);
elRoot.scaleX = elRoot.scaleY = viewBoxTransform.scale;
elRoot.x = viewBoxTransform.x;
elRoot.y = viewBoxTransform.y;
}
}
if (!opt.ignoreRootClip && width != null && height != null) {
root.setClipPath(new Rect({
shape: { x: 0, y: 0, width, height }
}));
}
return {
root,
width,
height,
viewBoxRect,
viewBoxTransform,
named
};
};
SVGParser2.prototype._parseNode = function(xmlNode, parentGroup, named, namedFrom, isInDefs, isInText) {
var nodeName = xmlNode.nodeName.toLowerCase();
var el;
var namedFromForSub = namedFrom;
if (nodeName === "defs") {
isInDefs = true;
}
if (nodeName === "text") {
isInText = true;
}
if (nodeName === "defs" || nodeName === "switch") {
el = parentGroup;
} else {
if (!isInDefs) {
var parser_1 = nodeParsers[nodeName];
if (parser_1 && hasOwn(nodeParsers, nodeName)) {
el = parser_1.call(this, xmlNode, parentGroup);
var nameAttr = xmlNode.getAttribute("name");
if (nameAttr) {
var newNamed = {
name: nameAttr,
namedFrom: null,
svgNodeTagLower: nodeName,
el
};
named.push(newNamed);
if (nodeName === "g") {
namedFromForSub = newNamed;
}
} else if (namedFrom) {
named.push({
name: namedFrom.name,
namedFrom,
svgNodeTagLower: nodeName,
el
});
}
parentGroup.add(el);
}
}
var parser = paintServerParsers[nodeName];
if (parser && hasOwn(paintServerParsers, nodeName)) {
var def = parser.call(this, xmlNode);
var id = xmlNode.getAttribute("id");
if (id) {
this._defs[id] = def;
}
}
}
if (el && el.isGroup) {
var child = xmlNode.firstChild;
while (child) {
if (child.nodeType === 1) {
this._parseNode(child, el, named, namedFromForSub, isInDefs, isInText);
} else if (child.nodeType === 3 && isInText) {
this._parseText(child, el);
}
child = child.nextSibling;
}
}
};
SVGParser2.prototype._parseText = function(xmlNode, parentGroup) {
var text = new TSpan({
style: {
text: xmlNode.textContent
},
silent: true,
x: this._textX || 0,
y: this._textY || 0
});
inheritStyle(parentGroup, text);
parseAttributes(xmlNode, text, this._defsUsePending, false, false);
applyTextAlignment(text, parentGroup);
var textStyle = text.style;
var fontSize = textStyle.fontSize;
if (fontSize && fontSize < 9) {
textStyle.fontSize = 9;
text.scaleX *= fontSize / 9;
text.scaleY *= fontSize / 9;
}
var font = (textStyle.fontSize || textStyle.fontFamily) && [
textStyle.fontStyle,
textStyle.fontWeight,
(textStyle.fontSize || 12) + "px",
textStyle.fontFamily || "sans-serif"
].join(" ");
textStyle.font = font;
var rect = text.getBoundingRect();
this._textX += rect.width;
parentGroup.add(text);
return text;
};
SVGParser2.internalField = function() {
nodeParsers = {
"g": function(xmlNode, parentGroup) {
var g = new Group();
inheritStyle(parentGroup, g);
parseAttributes(xmlNode, g, this._defsUsePending, false, false);
return g;
},
"rect": function(xmlNode, parentGroup) {
var rect = new Rect();
inheritStyle(parentGroup, rect);
parseAttributes(xmlNode, rect, this._defsUsePending, false, false);
rect.setShape({
x: parseFloat(xmlNode.getAttribute("x") || "0"),
y: parseFloat(xmlNode.getAttribute("y") || "0"),
width: parseFloat(xmlNode.getAttribute("width") || "0"),
height: parseFloat(xmlNode.getAttribute("height") || "0")
});
rect.silent = true;
return rect;
},
"circle": function(xmlNode, parentGroup) {
var circle = new Circle();
inheritStyle(parentGroup, circle);
parseAttributes(xmlNode, circle, this._defsUsePending, false, false);
circle.setShape({
cx: parseFloat(xmlNode.getAttribute("cx") || "0"),
cy: parseFloat(xmlNode.getAttribute("cy") || "0"),
r: parseFloat(xmlNode.getAttribute("r") || "0")
});
circle.silent = true;
return circle;
},
"line": function(xmlNode, parentGroup) {
var line = new Line();
inheritStyle(parentGroup, line);
parseAttributes(xmlNode, line, this._defsUsePending, false, false);
line.setShape({
x1: parseFloat(xmlNode.getAttribute("x1") || "0"),
y1: parseFloat(xmlNode.getAttribute("y1") || "0"),
x2: parseFloat(xmlNode.getAttribute("x2") || "0"),
y2: parseFloat(xmlNode.getAttribute("y2") || "0")
});
line.silent = true;
return line;
},
"ellipse": function(xmlNode, parentGroup) {
var ellipse = new Ellipse();
inheritStyle(parentGroup, ellipse);
parseAttributes(xmlNode, ellipse, this._defsUsePending, false, false);
ellipse.setShape({
cx: parseFloat(xmlNode.getAttribute("cx") || "0"),
cy: parseFloat(xmlNode.getAttribute("cy") || "0"),
rx: parseFloat(xmlNode.getAttribute("rx") || "0"),
ry: parseFloat(xmlNode.getAttribute("ry") || "0")
});
ellipse.silent = true;
return ellipse;
},
"polygon": function(xmlNode, parentGroup) {
var pointsStr = xmlNode.getAttribute("points");
var pointsArr;
if (pointsStr) {
pointsArr = parsePoints(pointsStr);
}
var polygon = new Polygon({
shape: {
points: pointsArr || []
},
silent: true
});
inheritStyle(parentGroup, polygon);
parseAttributes(xmlNode, polygon, this._defsUsePending, false, false);
return polygon;
},
"polyline": function(xmlNode, parentGroup) {
var pointsStr = xmlNode.getAttribute("points");
var pointsArr;
if (pointsStr) {
pointsArr = parsePoints(pointsStr);
}
var polyline = new Polyline({
shape: {
points: pointsArr || []
},
silent: true
});
inheritStyle(parentGroup, polyline);
parseAttributes(xmlNode, polyline, this._defsUsePending, false, false);
return polyline;
},
"image": function(xmlNode, parentGroup) {
var img = new ZRImage();
inheritStyle(parentGroup, img);
parseAttributes(xmlNode, img, this._defsUsePending, false, false);
img.setStyle({
image: xmlNode.getAttribute("xlink:href") || xmlNode.getAttribute("href"),
x: +xmlNode.getAttribute("x"),
y: +xmlNode.getAttribute("y"),
width: +xmlNode.getAttribute("width"),
height: +xmlNode.getAttribute("height")
});
img.silent = true;
return img;
},
"text": function(xmlNode, parentGroup) {
var x = xmlNode.getAttribute("x") || "0";
var y = xmlNode.getAttribute("y") || "0";
var dx = xmlNode.getAttribute("dx") || "0";
var dy = xmlNode.getAttribute("dy") || "0";
this._textX = parseFloat(x) + parseFloat(dx);
this._textY = parseFloat(y) + parseFloat(dy);
var g = new Group();
inheritStyle(parentGroup, g);
parseAttributes(xmlNode, g, this._defsUsePending, false, true);
return g;
},
"tspan": function(xmlNode, parentGroup) {
var x = xmlNode.getAttribute("x");
var y = xmlNode.getAttribute("y");
if (x != null) {
this._textX = parseFloat(x);
}
if (y != null) {
this._textY = parseFloat(y);
}
var dx = xmlNode.getAttribute("dx") || "0";
var dy = xmlNode.getAttribute("dy") || "0";
var g = new Group();
inheritStyle(parentGroup, g);
parseAttributes(xmlNode, g, this._defsUsePending, false, true);
this._textX += parseFloat(dx);
this._textY += parseFloat(dy);
return g;
},
"path": function(xmlNode, parentGroup) {
var d = xmlNode.getAttribute("d") || "";
var path = createFromString(d);
inheritStyle(parentGroup, path);
parseAttributes(xmlNode, path, this._defsUsePending, false, false);
path.silent = true;
return path;
}
};
}();
return SVGParser2;
}();
var paintServerParsers = {
"lineargradient": function(xmlNode) {
var x1 = parseInt(xmlNode.getAttribute("x1") || "0", 10);
var y1 = parseInt(xmlNode.getAttribute("y1") || "0", 10);
var x2 = parseInt(xmlNode.getAttribute("x2") || "10", 10);
var y2 = parseInt(xmlNode.getAttribute("y2") || "0", 10);
var gradient = new LinearGradient(x1, y1, x2, y2);
parsePaintServerUnit(xmlNode, gradient);
parseGradientColorStops(xmlNode, gradient);
return gradient;
},
"radialgradient": function(xmlNode) {
var cx = parseInt(xmlNode.getAttribute("cx") || "0", 10);
var cy = parseInt(xmlNode.getAttribute("cy") || "0", 10);
var r = parseInt(xmlNode.getAttribute("r") || "0", 10);
var gradient = new RadialGradient(cx, cy, r);
parsePaintServerUnit(xmlNode, gradient);
parseGradientColorStops(xmlNode, gradient);
return gradient;
}
};
function parsePaintServerUnit(xmlNode, gradient) {
var gradientUnits = xmlNode.getAttribute("gradientUnits");
if (gradientUnits === "userSpaceOnUse") {
gradient.global = true;
}
}
function parseGradientColorStops(xmlNode, gradient) {
var stop = xmlNode.firstChild;
while (stop) {
if (stop.nodeType === 1 && stop.nodeName.toLocaleLowerCase() === "stop") {
var offsetStr = stop.getAttribute("offset");
var offset = void 0;
if (offsetStr && offsetStr.indexOf("%") > 0) {
offset = parseInt(offsetStr, 10) / 100;
} else if (offsetStr) {
offset = parseFloat(offsetStr);
} else {
offset = 0;
}
var styleVals = {};
parseInlineStyle(stop, styleVals, styleVals);
var stopColor = styleVals.stopColor || stop.getAttribute("stop-color") || "#000000";
gradient.colorStops.push({
offset,
color: stopColor
});
}
stop = stop.nextSibling;
}
}
function inheritStyle(parent, child) {
if (parent && parent.__inheritedStyle) {
if (!child.__inheritedStyle) {
child.__inheritedStyle = {};
}
defaults(child.__inheritedStyle, parent.__inheritedStyle);
}
}
function parsePoints(pointsString) {
var list = splitNumberSequence(pointsString);
var points = [];
for (var i = 0; i < list.length; i += 2) {
var x = parseFloat(list[i]);
var y = parseFloat(list[i + 1]);
points.push([x, y]);
}
return points;
}
function parseAttributes(xmlNode, el, defsUsePending, onlyInlineStyle, isTextGroup) {
var disp = el;
var inheritedStyle = disp.__inheritedStyle = disp.__inheritedStyle || {};
var selfStyle = {};
if (xmlNode.nodeType === 1) {
parseTransformAttribute(xmlNode, el);
parseInlineStyle(xmlNode, inheritedStyle, selfStyle);
if (!onlyInlineStyle) {
parseAttributeStyle(xmlNode, inheritedStyle, selfStyle);
}
}
disp.style = disp.style || {};
if (inheritedStyle.fill != null) {
disp.style.fill = getFillStrokeStyle(disp, "fill", inheritedStyle.fill, defsUsePending);
}
if (inheritedStyle.stroke != null) {
disp.style.stroke = getFillStrokeStyle(disp, "stroke", inheritedStyle.stroke, defsUsePending);
}
each([
"lineWidth",
"opacity",
"fillOpacity",
"strokeOpacity",
"miterLimit",
"fontSize"
], function(propName) {
if (inheritedStyle[propName] != null) {
disp.style[propName] = parseFloat(inheritedStyle[propName]);
}
});
each([
"lineDashOffset",
"lineCap",
"lineJoin",
"fontWeight",
"fontFamily",
"fontStyle",
"textAlign"
], function(propName) {
if (inheritedStyle[propName] != null) {
disp.style[propName] = inheritedStyle[propName];
}
});
if (isTextGroup) {
disp.__selfStyle = selfStyle;
}
if (inheritedStyle.lineDash) {
disp.style.lineDash = map(splitNumberSequence(inheritedStyle.lineDash), function(str) {
return parseFloat(str);
});
}
if (inheritedStyle.visibility === "hidden" || inheritedStyle.visibility === "collapse") {
disp.invisible = true;
}
if (inheritedStyle.display === "none") {
disp.ignore = true;
}
}
function applyTextAlignment(text, parentGroup) {
var parentSelfStyle = parentGroup.__selfStyle;
if (parentSelfStyle) {
var textBaseline = parentSelfStyle.textBaseline;
var zrTextBaseline = textBaseline;
if (!textBaseline || textBaseline === "auto") {
zrTextBaseline = "alphabetic";
} else if (textBaseline === "baseline") {
zrTextBaseline = "alphabetic";
} else if (textBaseline === "before-edge" || textBaseline === "text-before-edge") {
zrTextBaseline = "top";
} else if (textBaseline === "after-edge" || textBaseline === "text-after-edge") {
zrTextBaseline = "bottom";
} else if (textBaseline === "central" || textBaseline === "mathematical") {
zrTextBaseline = "middle";
}
text.style.textBaseline = zrTextBaseline;
}
var parentInheritedStyle = parentGroup.__inheritedStyle;
if (parentInheritedStyle) {
var textAlign = parentInheritedStyle.textAlign;
var zrTextAlign = textAlign;
if (textAlign) {
if (textAlign === "middle") {
zrTextAlign = "center";
}
text.style.textAlign = zrTextAlign;
}
}
}
var urlRegex = /^url\(\s*#(.*?)\)/;
function getFillStrokeStyle(el, method, str, defsUsePending) {
var urlMatch = str && str.match(urlRegex);
if (urlMatch) {
var url = trim(urlMatch[1]);
defsUsePending.push([el, method, url]);
return;
}
if (str === "none") {
str = null;
}
return str;
}
function applyDefs(defs, defsUsePending) {
for (var i = 0; i < defsUsePending.length; i++) {
var item = defsUsePending[i];
item[0].style[item[1]] = defs[item[2]];
}
}
var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
function splitNumberSequence(rawStr) {
return rawStr.match(numberReg) || [];
}
var transformRegex = /(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.eE,]*)\)/g;
var DEGREE_TO_ANGLE = Math.PI / 180;
function parseTransformAttribute(xmlNode, node) {
var transform = xmlNode.getAttribute("transform");
if (transform) {
transform = transform.replace(/,/g, " ");
var transformOps_1 = [];
var mt = null;
transform.replace(transformRegex, function(str, type2, value2) {
transformOps_1.push(type2, value2);
return "";
});
for (var i = transformOps_1.length - 1; i > 0; i -= 2) {
var value = transformOps_1[i];
var type = transformOps_1[i - 1];
var valueArr = splitNumberSequence(value);
mt = mt || create();
switch (type) {
case "translate":
translate(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || "0")]);
break;
case "scale":
scale(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || valueArr[0])]);
break;
case "rotate":
rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
break;
case "skewX":
var sx = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
mul(mt, [1, 0, sx, 1, 0, 0], mt);
break;
case "skewY":
var sy = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE);
mul(mt, [1, sy, 0, 1, 0, 0], mt);
break;
case "matrix":
mt[0] = parseFloat(valueArr[0]);
mt[1] = parseFloat(valueArr[1]);
mt[2] = parseFloat(valueArr[2]);
mt[3] = parseFloat(valueArr[3]);
mt[4] = parseFloat(valueArr[4]);
mt[5] = parseFloat(valueArr[5]);
break;
}
}
node.setLocalTransform(mt);
}
}
var styleRegex = /([^\s:;]+)\s*:\s*([^:;]+)/g;
function parseInlineStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
var style = xmlNode.getAttribute("style");
if (!style) {
return;
}
styleRegex.lastIndex = 0;
var styleRegResult;
while ((styleRegResult = styleRegex.exec(style)) != null) {
var svgStlAttr = styleRegResult[1];
var zrInheritableStlAttr = hasOwn(INHERITABLE_STYLE_ATTRIBUTES_MAP, svgStlAttr) ? INHERITABLE_STYLE_ATTRIBUTES_MAP[svgStlAttr] : null;
if (zrInheritableStlAttr) {
inheritableStyleResult[zrInheritableStlAttr] = styleRegResult[2];
}
var zrSelfStlAttr = hasOwn(SELF_STYLE_ATTRIBUTES_MAP, svgStlAttr) ? SELF_STYLE_ATTRIBUTES_MAP[svgStlAttr] : null;
if (zrSelfStlAttr) {
selfStyleResult[zrSelfStlAttr] = styleRegResult[2];
}
}
}
function parseAttributeStyle(xmlNode, inheritableStyleResult, selfStyleResult) {
for (var i = 0; i < INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
var svgAttrName = INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS[i];
var attrValue = xmlNode.getAttribute(svgAttrName);
if (attrValue != null) {
inheritableStyleResult[INHERITABLE_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
}
}
for (var i = 0; i < SELF_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) {
var svgAttrName = SELF_STYLE_ATTRIBUTES_MAP_KEYS[i];
var attrValue = xmlNode.getAttribute(svgAttrName);
if (attrValue != null) {
selfStyleResult[SELF_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue;
}
}
}
function makeViewBoxTransform(viewBoxRect, boundingRect) {
var scaleX = boundingRect.width / viewBoxRect.width;
var scaleY = boundingRect.height / viewBoxRect.height;
var scale2 = Math.min(scaleX, scaleY);
return {
scale: scale2,
x: -(viewBoxRect.x + viewBoxRect.width / 2) * scale2 + (boundingRect.x + boundingRect.width / 2),
y: -(viewBoxRect.y + viewBoxRect.height / 2) * scale2 + (boundingRect.y + boundingRect.height / 2)
};
}
function parseSVG(xml, opt) {
var parser = new SVGParser();
return parser.parse(xml, opt);
}
export { makeViewBoxTransform, parseSVG };