481 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			481 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
import { adjustTextY, getIdURL, getMatrixStr, getPathPrecision, getShadowKey, getSRTTransformString, hasShadow, isAroundZero, isGradient, isImagePattern, isLinearGradient, isPattern, isRadialGradient, normalizeColor, round4, TEXT_ALIGN_TO_ANCHOR } from './helper.js';
 | 
						|
import Path from '../graphic/Path.js';
 | 
						|
import ZRImage from '../graphic/Image.js';
 | 
						|
import { getLineHeight } from '../contain/text.js';
 | 
						|
import TSpan from '../graphic/TSpan.js';
 | 
						|
import SVGPathRebuilder from './SVGPathRebuilder.js';
 | 
						|
import mapStyleToAttrs from './mapStyleToAttrs.js';
 | 
						|
import { createVNode, vNodeToString, META_DATA_PREFIX } from './core.js';
 | 
						|
import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util.js';
 | 
						|
import { createOrUpdateImage } from '../graphic/helper/image.js';
 | 
						|
import { createCSSAnimation } from './cssAnimation.js';
 | 
						|
import { hasSeparateFont, parseFontSize } from '../graphic/Text.js';
 | 
						|
import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform.js';
 | 
						|
import { createCSSEmphasis } from './cssEmphasis.js';
 | 
						|
import { getElementSSRData } from '../zrender.js';
 | 
						|
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 if (isFillStroke && val === 'none') {
 | 
						|
            attrs[key] = 'transparent';
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            attrs[key] = val;
 | 
						|
        }
 | 
						|
    }, style, el, false);
 | 
						|
    setShadow(el, attrs, scope);
 | 
						|
}
 | 
						|
function setMetaData(attrs, el) {
 | 
						|
    var metaData = getElementSSRData(el);
 | 
						|
    if (metaData) {
 | 
						|
        metaData.each(function (val, key) {
 | 
						|
            val != null && (attrs[(META_DATA_PREFIX + key).toLowerCase()] = val + '');
 | 
						|
        });
 | 
						|
        if (el.isSilent()) {
 | 
						|
            attrs[META_DATA_PREFIX + 'silent'] = 'true';
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
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;
 | 
						|
}
 | 
						|
export 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);
 | 
						|
    setMetaData(attrs, el);
 | 
						|
    scope.animation && createCSSAnimation(el, attrs, scope);
 | 
						|
    scope.emphasis && createCSSEmphasis(el, attrs, scope);
 | 
						|
    return createVNode(svgElType, el.id + '', attrs);
 | 
						|
}
 | 
						|
export 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);
 | 
						|
    setMetaData(attrs, el);
 | 
						|
    scope.animation && createCSSAnimation(el, attrs, scope);
 | 
						|
    return createVNode('image', el.id + '', attrs);
 | 
						|
}
 | 
						|
;
 | 
						|
export 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);
 | 
						|
    setMetaData(attrs, el);
 | 
						|
    scope.animation && createCSSAnimation(el, attrs, scope);
 | 
						|
    return createVNode('text', el.id + '', attrs, undefined, text);
 | 
						|
}
 | 
						|
export 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);
 | 
						|
    }
 | 
						|
}
 | 
						|
export 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 {
 | 
						|
        if (process.env.NODE_ENV !== 'production') {
 | 
						|
            logError('Illegal gradient type.');
 | 
						|
        }
 | 
						|
        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);
 | 
						|
}
 | 
						|
export 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);
 | 
						|
}
 | 
						|
export 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);
 | 
						|
}
 |