cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
428 lines (427 loc) • 14.6 kB
JavaScript
import { isLinearGradient, isRadialGradient, round4, normalizeColor, getIdURL, isImagePattern, getSRTTransformString, getPathPrecision, adjustTextY, TEXT_ALIGN_TO_ANCHOR, isGradient, isPattern, getMatrixStr, hasShadow, getShadowKey, isAroundZero } from "./helper.mjs";
import Path from "../graphic/Path.mjs";
import ZRImage from "../graphic/Image.mjs";
import { getLineHeight } from "../contain/text.mjs";
import TSpan from "../graphic/TSpan.mjs";
import SVGPathRebuilder from "./SVGPathRebuilder.mjs";
import mapStyleToAttrs from "./mapStyleToAttrs.mjs";
import { vNodeToString, createVNode } from "./core.mjs";
import { retrieve2, isString, assert, clone, isFunction, map } from "../core/util.mjs";
import { createOrUpdateImage } from "../graphic/helper/image.mjs";
import { createCSSAnimation } from "./cssAnimation.mjs";
import { hasSeparateFont, parseFontSize } from "../graphic/Text.mjs";
import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from "../core/platform.mjs";
var round = Math.round;
function isImageLike(val) {
return val && isString(val.src);
}
function isCanvasLike(val) {
return val && isFunction(val.toDataURL);
}
function setStyleAttrs(attrs, style, el, scope) {
mapStyleToAttrs(function(key, val) {
var isFillStroke = key === "fill" || key === "stroke";
if (isFillStroke && isGradient(val)) {
setGradient(style, attrs, key, scope);
} else if (isFillStroke && isPattern(val)) {
setPattern(el, attrs, key, scope);
} else {
attrs[key] = val;
}
}, style, el, false);
setShadow(el, attrs, scope);
}
function noRotateScale(m) {
return isAroundZero(m[0] - 1) && isAroundZero(m[1]) && isAroundZero(m[2]) && isAroundZero(m[3] - 1);
}
function noTranslate(m) {
return isAroundZero(m[4]) && isAroundZero(m[5]);
}
function setTransform(attrs, m, compress) {
if (m && !(noTranslate(m) && noRotateScale(m))) {
var mul = compress ? 10 : 1e4;
attrs.transform = noRotateScale(m) ? "translate(" + round(m[4] * mul) / mul + " " + round(m[5] * mul) / mul + ")" : getMatrixStr(m);
}
}
function convertPolyShape(shape, attrs, mul) {
var points = shape.points;
var strArr = [];
for (var i = 0; i < points.length; i++) {
strArr.push(round(points[i][0] * mul) / mul);
strArr.push(round(points[i][1] * mul) / mul);
}
attrs.points = strArr.join(" ");
}
function validatePolyShape(shape) {
return !shape.smooth;
}
function createAttrsConvert(desc) {
var normalizedDesc = map(desc, function(item) {
return typeof item === "string" ? [item, item] : item;
});
return function(shape, attrs, mul) {
for (var i = 0; i < normalizedDesc.length; i++) {
var item = normalizedDesc[i];
var val = shape[item[0]];
if (val != null) {
attrs[item[1]] = round(val * mul) / mul;
}
}
};
}
var builtinShapesDef = {
circle: [createAttrsConvert(["cx", "cy", "r"])],
polyline: [convertPolyShape, validatePolyShape],
polygon: [convertPolyShape, validatePolyShape]
};
function hasShapeAnimation(el) {
var animators = el.animators;
for (var i = 0; i < animators.length; i++) {
if (animators[i].targetName === "shape") {
return true;
}
}
return false;
}
function brushSVGPath(el, scope) {
var style = el.style;
var shape = el.shape;
var builtinShpDef = builtinShapesDef[el.type];
var attrs = {};
var needsAnimate = scope.animation;
var svgElType = "path";
var strokePercent = el.style.strokePercent;
var precision = scope.compress && getPathPrecision(el) || 4;
if (builtinShpDef && !scope.willUpdate && !(builtinShpDef[1] && !builtinShpDef[1](shape)) && !(needsAnimate && hasShapeAnimation(el)) && !(strokePercent < 1)) {
svgElType = el.type;
var mul = Math.pow(10, precision);
builtinShpDef[0](shape, attrs, mul);
} else {
var needBuildPath = !el.path || el.shapeChanged();
if (!el.path) {
el.createPathProxy();
}
var path = el.path;
if (needBuildPath) {
path.beginPath();
el.buildPath(path, el.shape);
el.pathUpdated();
}
var pathVersion = path.getVersion();
var elExt = el;
var svgPathBuilder = elExt.__svgPathBuilder;
if (elExt.__svgPathVersion !== pathVersion || !svgPathBuilder || strokePercent !== elExt.__svgPathStrokePercent) {
if (!svgPathBuilder) {
svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder();
}
svgPathBuilder.reset(precision);
path.rebuildPath(svgPathBuilder, strokePercent);
svgPathBuilder.generateStr();
elExt.__svgPathVersion = pathVersion;
elExt.__svgPathStrokePercent = strokePercent;
}
attrs.d = svgPathBuilder.getStr();
}
setTransform(attrs, el.transform);
setStyleAttrs(attrs, style, el, scope);
scope.animation && createCSSAnimation(el, attrs, scope);
return createVNode(svgElType, el.id + "", attrs);
}
function brushSVGImage(el, scope) {
var style = el.style;
var image = style.image;
if (image && !isString(image)) {
if (isImageLike(image)) {
image = image.src;
} else if (isCanvasLike(image)) {
image = image.toDataURL();
}
}
if (!image) {
return;
}
var x = style.x || 0;
var y = style.y || 0;
var dw = style.width;
var dh = style.height;
var attrs = {
href: image,
width: dw,
height: dh
};
if (x) {
attrs.x = x;
}
if (y) {
attrs.y = y;
}
setTransform(attrs, el.transform);
setStyleAttrs(attrs, style, el, scope);
scope.animation && createCSSAnimation(el, attrs, scope);
return createVNode("image", el.id + "", attrs);
}
function brushSVGTSpan(el, scope) {
var style = el.style;
var text = style.text;
text != null && (text += "");
if (!text || isNaN(style.x) || isNaN(style.y)) {
return;
}
var font = style.font || DEFAULT_FONT;
var x = style.x || 0;
var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline);
var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign] || style.textAlign;
var attrs = {
"dominant-baseline": "central",
"text-anchor": textAlign
};
if (hasSeparateFont(style)) {
var separatedFontStr = "";
var fontStyle = style.fontStyle;
var fontSize = parseFontSize(style.fontSize);
if (!parseFloat(fontSize)) {
return;
}
var fontFamily = style.fontFamily || DEFAULT_FONT_FAMILY;
var fontWeight = style.fontWeight;
separatedFontStr += "font-size:" + fontSize + ";font-family:" + fontFamily + ";";
if (fontStyle && fontStyle !== "normal") {
separatedFontStr += "font-style:" + fontStyle + ";";
}
if (fontWeight && fontWeight !== "normal") {
separatedFontStr += "font-weight:" + fontWeight + ";";
}
attrs.style = separatedFontStr;
} else {
attrs.style = "font: " + font;
}
if (text.match(/\s/)) {
attrs["xml:space"] = "preserve";
}
if (x) {
attrs.x = x;
}
if (y) {
attrs.y = y;
}
setTransform(attrs, el.transform);
setStyleAttrs(attrs, style, el, scope);
scope.animation && createCSSAnimation(el, attrs, scope);
return createVNode("text", el.id + "", attrs, void 0, text);
}
function brush(el, scope) {
if (el instanceof Path) {
return brushSVGPath(el, scope);
} else if (el instanceof ZRImage) {
return brushSVGImage(el, scope);
} else if (el instanceof TSpan) {
return brushSVGTSpan(el, scope);
}
}
function setShadow(el, attrs, scope) {
var style = el.style;
if (hasShadow(style)) {
var shadowKey = getShadowKey(el);
var shadowCache = scope.shadowCache;
var shadowId = shadowCache[shadowKey];
if (!shadowId) {
var globalScale = el.getGlobalScale();
var scaleX = globalScale[0];
var scaleY = globalScale[1];
if (!scaleX || !scaleY) {
return;
}
var offsetX = style.shadowOffsetX || 0;
var offsetY = style.shadowOffsetY || 0;
var blur_1 = style.shadowBlur;
var _a = normalizeColor(style.shadowColor), opacity = _a.opacity, color = _a.color;
var stdDx = blur_1 / 2 / scaleX;
var stdDy = blur_1 / 2 / scaleY;
var stdDeviation = stdDx + " " + stdDy;
shadowId = scope.zrId + "-s" + scope.shadowIdx++;
scope.defs[shadowId] = createVNode("filter", shadowId, {
"id": shadowId,
"x": "-100%",
"y": "-100%",
"width": "300%",
"height": "300%"
}, [
createVNode("feDropShadow", "", {
"dx": offsetX / scaleX,
"dy": offsetY / scaleY,
"stdDeviation": stdDeviation,
"flood-color": color,
"flood-opacity": opacity
})
]);
shadowCache[shadowKey] = shadowId;
}
attrs.filter = getIdURL(shadowId);
}
}
function setGradient(style, attrs, target, scope) {
var val = style[target];
var gradientTag;
var gradientAttrs = {
"gradientUnits": val.global ? "userSpaceOnUse" : "objectBoundingBox"
};
if (isLinearGradient(val)) {
gradientTag = "linearGradient";
gradientAttrs.x1 = val.x;
gradientAttrs.y1 = val.y;
gradientAttrs.x2 = val.x2;
gradientAttrs.y2 = val.y2;
} else if (isRadialGradient(val)) {
gradientTag = "radialGradient";
gradientAttrs.cx = retrieve2(val.x, 0.5);
gradientAttrs.cy = retrieve2(val.y, 0.5);
gradientAttrs.r = retrieve2(val.r, 0.5);
} else {
return;
}
var colors = val.colorStops;
var colorStops = [];
for (var i = 0, len = colors.length; i < len; ++i) {
var offset = round4(colors[i].offset) * 100 + "%";
var stopColor = colors[i].color;
var _a = normalizeColor(stopColor), color = _a.color, opacity = _a.opacity;
var stopsAttrs = {
"offset": offset
};
stopsAttrs["stop-color"] = color;
if (opacity < 1) {
stopsAttrs["stop-opacity"] = opacity;
}
colorStops.push(createVNode("stop", i + "", stopsAttrs));
}
var gradientVNode = createVNode(gradientTag, "", gradientAttrs, colorStops);
var gradientKey = vNodeToString(gradientVNode);
var gradientCache = scope.gradientCache;
var gradientId = gradientCache[gradientKey];
if (!gradientId) {
gradientId = scope.zrId + "-g" + scope.gradientIdx++;
gradientCache[gradientKey] = gradientId;
gradientAttrs.id = gradientId;
scope.defs[gradientId] = createVNode(gradientTag, gradientId, gradientAttrs, colorStops);
}
attrs[target] = getIdURL(gradientId);
}
function setPattern(el, attrs, target, scope) {
var val = el.style[target];
var boundingRect = el.getBoundingRect();
var patternAttrs = {};
var repeat = val.repeat;
var noRepeat = repeat === "no-repeat";
var repeatX = repeat === "repeat-x";
var repeatY = repeat === "repeat-y";
var child;
if (isImagePattern(val)) {
var imageWidth_1 = val.imageWidth;
var imageHeight_1 = val.imageHeight;
var imageSrc = void 0;
var patternImage = val.image;
if (isString(patternImage)) {
imageSrc = patternImage;
} else if (isImageLike(patternImage)) {
imageSrc = patternImage.src;
} else if (isCanvasLike(patternImage)) {
imageSrc = patternImage.toDataURL();
}
if (typeof Image === "undefined") {
var errMsg = "Image width/height must been given explictly in svg-ssr renderer.";
assert(imageWidth_1, errMsg);
assert(imageHeight_1, errMsg);
} else if (imageWidth_1 == null || imageHeight_1 == null) {
var setSizeToVNode_1 = function(vNode, img) {
if (vNode) {
var svgEl = vNode.elm;
var width = imageWidth_1 || img.width;
var height = imageHeight_1 || img.height;
if (vNode.tag === "pattern") {
if (repeatX) {
height = 1;
width /= boundingRect.width;
} else if (repeatY) {
width = 1;
height /= boundingRect.height;
}
}
vNode.attrs.width = width;
vNode.attrs.height = height;
if (svgEl) {
svgEl.setAttribute("width", width);
svgEl.setAttribute("height", height);
}
}
};
var createdImage = createOrUpdateImage(imageSrc, null, el, function(img) {
noRepeat || setSizeToVNode_1(patternVNode, img);
setSizeToVNode_1(child, img);
});
if (createdImage && createdImage.width && createdImage.height) {
imageWidth_1 = imageWidth_1 || createdImage.width;
imageHeight_1 = imageHeight_1 || createdImage.height;
}
}
child = createVNode("image", "img", {
href: imageSrc,
width: imageWidth_1,
height: imageHeight_1
});
patternAttrs.width = imageWidth_1;
patternAttrs.height = imageHeight_1;
} else if (val.svgElement) {
child = clone(val.svgElement);
patternAttrs.width = val.svgWidth;
patternAttrs.height = val.svgHeight;
}
if (!child) {
return;
}
var patternWidth;
var patternHeight;
if (noRepeat) {
patternWidth = patternHeight = 1;
} else if (repeatX) {
patternHeight = 1;
patternWidth = patternAttrs.width / boundingRect.width;
} else if (repeatY) {
patternWidth = 1;
patternHeight = patternAttrs.height / boundingRect.height;
} else {
patternAttrs.patternUnits = "userSpaceOnUse";
}
if (patternWidth != null && !isNaN(patternWidth)) {
patternAttrs.width = patternWidth;
}
if (patternHeight != null && !isNaN(patternHeight)) {
patternAttrs.height = patternHeight;
}
var patternTransform = getSRTTransformString(val);
patternTransform && (patternAttrs.patternTransform = patternTransform);
var patternVNode = createVNode("pattern", "", patternAttrs, [child]);
var patternKey = vNodeToString(patternVNode);
var patternCache = scope.patternCache;
var patternId = patternCache[patternKey];
if (!patternId) {
patternId = scope.zrId + "-p" + scope.patternIdx++;
patternCache[patternKey] = patternId;
patternAttrs.id = patternId;
patternVNode = scope.defs[patternId] = createVNode("pattern", patternId, patternAttrs, [child]);
}
attrs[target] = getIdURL(patternId);
}
function setClipPath(clipPath, attrs, scope) {
var clipPathCache = scope.clipPathCache, defs = scope.defs;
var clipPathId = clipPathCache[clipPath.id];
if (!clipPathId) {
clipPathId = scope.zrId + "-c" + scope.clipPathIdx++;
var clipPathAttrs = {
id: clipPathId
};
clipPathCache[clipPath.id] = clipPathId;
defs[clipPathId] = createVNode("clipPath", clipPathId, clipPathAttrs, [brushSVGPath(clipPath, scope)]);
}
attrs["clip-path"] = getIdURL(clipPathId);
}
export { brush, brushSVGImage, brushSVGPath, brushSVGTSpan, setClipPath, setGradient, setPattern };