@antv/g-svg
Version:
A renderer implemented by SVG
1,268 lines (1,230 loc) • 95.2 kB
JavaScript
/*!
* @antv/g-svg
* @description A renderer implemented by SVG
* @version 2.1.1
* @date 12/24/2025, 11:57:09 AM
* @author AntVis
* @docs https://g.antv.antgroup.com/
*/
'use strict';
var _createClass = require('@babel/runtime/helpers/createClass');
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
var _callSuper = require('@babel/runtime/helpers/callSuper');
var _inherits = require('@babel/runtime/helpers/inherits');
var gLite = require('@antv/g-lite');
var util = require('@antv/util');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var glMatrix = require('gl-matrix');
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _createForOfIteratorHelper = require('@babel/runtime/helpers/createForOfIteratorHelper');
var _regeneratorRuntime = require('@babel/runtime/helpers/regeneratorRuntime');
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var ElementSVG = /*#__PURE__*/_createClass(function ElementSVG() {
_classCallCheck(this, ElementSVG);
});
ElementSVG.tag = 'c-svg-element';
function updateImageElementAttribute($el, parsedStyle) {
var _parsedStyle$src = parsedStyle.src,
src = _parsedStyle$src === void 0 ? '' : _parsedStyle$src,
_parsedStyle$x = parsedStyle.x,
x = _parsedStyle$x === void 0 ? 0 : _parsedStyle$x,
_parsedStyle$y = parsedStyle.y,
y = _parsedStyle$y === void 0 ? 0 : _parsedStyle$y,
width = parsedStyle.width,
height = parsedStyle.height;
$el.setAttribute('x', "".concat(x));
$el.setAttribute('y', "".concat(y));
if (util.isString(src)) {
$el.setAttribute('href', src);
} else if (src instanceof Image) {
if (!width) {
$el.setAttribute('width', "".concat(src.width));
}
if (!height) {
$el.setAttribute('height', "".concat(src.height));
}
$el.setAttribute('href', src.src);
} else if (
// @ts-ignore
src instanceof HTMLElement && util.isString(src.nodeName) && src.nodeName.toUpperCase() === 'CANVAS') {
$el.setAttribute('href', src.toDataURL());
// @ts-ignore
} else if (src instanceof ImageData) {
var canvas = document.createElement('canvas');
// @ts-ignore
canvas.setAttribute('width', "".concat(src.width));
// @ts-ignore
canvas.setAttribute('height', "".concat(src.height));
var context = canvas.getContext('2d');
if (context) {
context.putImageData(src, 0, 0);
if (!width) {
// @ts-ignore
$el.setAttribute('width', "".concat(src.width));
}
if (!height) {
// @ts-ignore
$el.setAttribute('height', "".concat(src.height));
}
$el.setAttribute('href', canvas.toDataURL());
}
}
}
function updateLineElementAttribute($el, parsedStyle) {
var x1 = parsedStyle.x1,
y1 = parsedStyle.y1,
x2 = parsedStyle.x2,
y2 = parsedStyle.y2,
markerStart = parsedStyle.markerStart,
markerEnd = parsedStyle.markerEnd,
markerStartOffset = parsedStyle.markerStartOffset,
markerEndOffset = parsedStyle.markerEndOffset;
var startOffsetX = 0;
var startOffsetY = 0;
var endOffsetX = 0;
var endOffsetY = 0;
var rad = 0;
var x;
var y;
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
x = x2 - x1;
y = y2 - y1;
rad = Math.atan2(y, x);
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
}
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
x = x1 - x2;
y = y1 - y2;
rad = Math.atan2(y, x);
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
}
// @see https://github.com/antvis/g/issues/1038
$el.setAttribute('x1', "".concat(x1 + startOffsetX));
$el.setAttribute('y1', "".concat(y1 + startOffsetY));
$el.setAttribute('x2', "".concat(x2 + endOffsetX));
$el.setAttribute('y2', "".concat(y2 + endOffsetY));
}
function updatePathElementAttribute($el, parsedStyle) {
var d = parsedStyle.d,
markerStart = parsedStyle.markerStart,
markerEnd = parsedStyle.markerEnd,
markerStartOffset = parsedStyle.markerStartOffset,
markerEndOffset = parsedStyle.markerEndOffset;
var startOffsetX = 0;
var startOffsetY = 0;
var endOffsetX = 0;
var endOffsetY = 0;
var rad = 0;
var x;
var y;
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
var _getStartTangent = markerStart.parentNode.getStartTangent(),
_getStartTangent2 = _slicedToArray(_getStartTangent, 2),
p1 = _getStartTangent2[0],
p2 = _getStartTangent2[1];
x = p1[0] - p2[0];
y = p1[1] - p2[1];
rad = Math.atan2(y, x);
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
}
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
var _getEndTangent = markerEnd.parentNode.getEndTangent(),
_getEndTangent2 = _slicedToArray(_getEndTangent, 2),
_p = _getEndTangent2[0],
_p2 = _getEndTangent2[1];
x = _p[0] - _p2[0];
y = _p[1] - _p2[1];
rad = Math.atan2(y, x);
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
}
$el.setAttribute('d', gLite.translatePathToString(d.absolutePath, startOffsetX, startOffsetY, endOffsetX, endOffsetY));
}
function updatePolylineElementAttribute($el, parsedStyle) {
var points = parsedStyle.points.points,
markerStart = parsedStyle.markerStart,
markerStartOffset = parsedStyle.markerStartOffset,
markerEnd = parsedStyle.markerEnd,
markerEndOffset = parsedStyle.markerEndOffset;
var length = points.length;
if (points && length >= 2) {
var startOffsetX = 0;
var startOffsetY = 0;
var endOffsetX = 0;
var endOffsetY = 0;
var rad = 0;
var x;
var y;
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
x = points[1][0] - points[0][0];
y = points[1][1] - points[0][1];
rad = Math.atan2(y, x);
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
}
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
x = points[length - 2][0] - points[length - 1][0];
y = points[length - 2][1] - points[length - 1][1];
rad = Math.atan2(y, x);
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
}
$el.setAttribute('points', points.map(function (point, i) {
var offsetX = 0;
var offsetY = 0;
if (i === 0) {
offsetX = startOffsetX;
offsetY = startOffsetY;
} else if (i === length - 1) {
offsetX = endOffsetX;
offsetY = endOffsetY;
}
return "".concat(point[0] + offsetX, ",").concat(point[1] + offsetY);
}).join(' '));
}
}
function updateRectElementAttribute($el, parsedStyle) {
var radius = parsedStyle.radius,
_parsedStyle$x = parsedStyle.x,
x = _parsedStyle$x === void 0 ? 0 : _parsedStyle$x,
_parsedStyle$y = parsedStyle.y,
y = _parsedStyle$y === void 0 ? 0 : _parsedStyle$y,
width = parsedStyle.width,
height = parsedStyle.height;
// CSSKeyword: auto
if (!isFinite(width) || !isFinite(height)) {
return;
}
var hasRadius = radius && radius.some(function (r) {
return r !== 0;
});
var d = '';
if (!hasRadius) {
d = "M ".concat(x, ",").concat(y, " l ").concat(width, ",0 l 0,").concat(height, " l").concat(-width, " 0 z");
} else {
var _radius$map = radius.map(function (r) {
return util.clamp(r, 0, Math.min(Math.abs(width) / 2, Math.abs(height) / 2));
}),
_radius$map2 = _slicedToArray(_radius$map, 4),
tlr = _radius$map2[0],
trr = _radius$map2[1],
brr = _radius$map2[2],
blr = _radius$map2[3];
var signX = width > 0 ? 1 : -1;
var signY = height > 0 ? 1 : -1;
// sweep-flag @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths#arcs
var sweepFlag = signX + signY !== 0 ? 1 : 0;
d = [["M ".concat(signX * tlr + x, ",").concat(y)], ["l ".concat(width - signX * (tlr + trr), ",0")], ["a ".concat(trr, ",").concat(trr, ",0,0,").concat(sweepFlag, ",").concat(signX * trr, ",").concat(signY * trr)], ["l 0,".concat(height - signY * (trr + brr))], ["a ".concat(brr, ",").concat(brr, ",0,0,").concat(sweepFlag, ",").concat(-signX * brr, ",").concat(signY * brr)], ["l ".concat(signX * (brr + blr) - width, ",0")], ["a ".concat(blr, ",").concat(blr, ",0,0,").concat(sweepFlag, ",").concat(-signX * blr, ",").concat(-signY * blr)], ["l 0,".concat(signY * (blr + tlr) - height)], ["a ".concat(tlr, ",").concat(tlr, ",0,0,").concat(sweepFlag, ",").concat(signX * tlr, ",").concat(-signY * tlr)], ['z']].join(' ');
}
$el.setAttribute('d', d);
}
function createSVGElement(type, doc) {
return (doc || document).createElementNS('http://www.w3.org/2000/svg', type);
}
var FILTER_PREFIX = 'g-filter-';
/**
* use SVG filters, eg. blur, brightness, contrast...
* @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/filter
*/
function createOrUpdateFilter(document, $def, object, $el, filters) {
// eg. filter="url(#f1) url(#f2)"
var filterName = FILTER_PREFIX + object.entity;
var $existedFilters = $def.querySelectorAll("[name=".concat(filterName, "]"));
if ($existedFilters.length) {
$existedFilters.forEach(function ($filter) {
$def.removeChild($filter);
});
}
if (filters.length === 0) {
// 'none'
$el === null || $el === void 0 || $el.removeAttribute('filter');
} else {
var filterIds = filters.map(function (_ref, i) {
var name = _ref.name,
params = _ref.params;
var $filter = createSVGElement('filter', document);
// @see https://github.com/antvis/g/issues/1025
$filter.setAttribute('filterUnits', 'userSpaceOnUse');
if (name === 'blur') {
createBlur(document, $filter, params);
} else if (name === 'brightness') {
createBrightness(document, $filter, params);
} else if (name === 'drop-shadow') {
createDropShadow(document, $filter, params);
} else if (name === 'contrast') {
createContrast(document, $filter, params);
} else if (name === 'grayscale') {
createGrayscale(document, $filter, params);
} else if (name === 'sepia') {
createSepia(document, $filter, params);
} else if (name === 'saturate') {
createSaturate(document, $filter, params);
} else if (name === 'hue-rotate') {
createHueRotate(document, $filter, params);
} else if (name === 'invert') {
createInvert(document, $filter, params);
}
$filter.id = "".concat(filterName, "-").concat(i);
$filter.setAttribute('name', filterName);
$def.appendChild($filter);
return $filter.id;
});
// @see https://github.com/antvis/G/issues/1114
setTimeout(function () {
$el === null || $el === void 0 || $el.setAttribute('filter', filterIds.map(function (filterId) {
return "url(#".concat(filterId, ")");
}).join(' '));
});
}
}
function convertToAbsoluteValue(param) {
return param.unit === gLite.UnitType.kPercentage ? param.value / 100 : param.value;
}
/**
* @see https://drafts.fxtf.org/filter-effects/#blurEquivalent
*/
function createBlur(document, $filter, params) {
var $feGaussianBlur = createSVGElement('feGaussianBlur', document);
$feGaussianBlur.setAttribute('in', 'SourceGraphic');
$feGaussianBlur.setAttribute('stdDeviation', "".concat(params[0].value));
$filter.appendChild($feGaussianBlur);
}
function createFeComponentTransfer(document, $filter, _ref2) {
var type = _ref2.type,
slope = _ref2.slope,
intercept = _ref2.intercept,
tableValues = _ref2.tableValues;
var $feComponentTransfer = createSVGElement('feComponentTransfer', document);
[createSVGElement('feFuncR', document), createSVGElement('feFuncG', document), createSVGElement('feFuncB', document)].forEach(function ($feFunc) {
$feFunc.setAttribute('type', type);
if (type === 'table') {
$feFunc.setAttribute('tableValues', "".concat(tableValues));
} else {
$feFunc.setAttribute('slope', "".concat(slope));
$feFunc.setAttribute('intercept', "".concat(intercept));
}
$feComponentTransfer.appendChild($feFunc);
});
$filter.appendChild($feComponentTransfer);
}
function createContrast(document, $filter, params) {
var slope = convertToAbsoluteValue(params[0]);
createFeComponentTransfer(document, $filter, {
type: 'linear',
slope: slope,
intercept: -(0.5 * slope) + 0.5
});
}
function createInvert(document, $filter, params) {
var amount = convertToAbsoluteValue(params[0]);
createFeComponentTransfer(document, $filter, {
type: 'table',
tableValues: "".concat(amount, " ").concat(1 - amount)
});
}
function createBrightness(document, $filter, params) {
var slope = convertToAbsoluteValue(params[0]);
createFeComponentTransfer(document, $filter, {
type: 'linear',
slope: slope,
intercept: 0
});
}
function createSaturate(document, $filter, params) {
var amount = convertToAbsoluteValue(params[0]);
var $feColorMatrix = createSVGElement('feColorMatrix', document);
$feColorMatrix.setAttribute('type', 'saturate');
$feColorMatrix.setAttribute('values', "".concat(amount));
$filter.appendChild($feColorMatrix);
}
function createHueRotate(document, $filter, params) {
var $feColorMatrix = createSVGElement('feColorMatrix', document);
$feColorMatrix.setAttribute('type', 'hueRotate');
// $feColorMatrix.setAttribute('values', `${params[0].to(UnitType.kDegrees).value}`);
// FIXME: convert to degrees
$feColorMatrix.setAttribute('values', "".concat(params[0].value));
$filter.appendChild($feColorMatrix);
}
function createDropShadow(document, $filter, params) {
var shadowOffsetX = params[0].value;
var shadowOffsetY = params[1].value;
var shadowBlur = params[2].value;
// @ts-ignore
var shadowColor = params[3].formatted;
var $feGaussianBlur = createSVGElement('feGaussianBlur', document);
$feGaussianBlur.setAttribute('in', 'SourceAlpha');
$feGaussianBlur.setAttribute('stdDeviation', "".concat(shadowBlur));
$filter.appendChild($feGaussianBlur);
var $feOffset = createSVGElement('feOffset', document);
$feOffset.setAttribute('dx', "".concat(shadowOffsetX));
$feOffset.setAttribute('dy', "".concat(shadowOffsetY));
$feOffset.setAttribute('result', 'offsetblur');
$filter.appendChild($feOffset);
var $feFlood = createSVGElement('feFlood', document);
$feFlood.setAttribute('flood-color', shadowColor);
$filter.appendChild($feFlood);
var $feComposite = createSVGElement('feComposite', document);
$feComposite.setAttribute('in2', 'offsetblur');
$feComposite.setAttribute('operator', 'in');
$filter.appendChild($feComposite);
var $feMerge = createSVGElement('feMerge', document);
$filter.appendChild($feMerge);
var $feMergeNode1 = createSVGElement('feMergeNode', document);
var $feMergeNode2 = createSVGElement('feMergeNode', document);
$feMergeNode2.setAttribute('in', 'SourceGraphic');
$feMerge.appendChild($feMergeNode1);
$feMerge.appendChild($feMergeNode2);
}
function createFeColorMatrix(document, $filter, matrix) {
var $feColorMatrix = createSVGElement('feColorMatrix', document);
$feColorMatrix.setAttribute('type', 'matrix');
$feColorMatrix.setAttribute('values', matrix.join(' '));
$filter.appendChild($feColorMatrix);
}
/**
* @see https://drafts.fxtf.org/filter-effects/#grayscaleEquivalent
*/
function createGrayscale(document, $filter, params) {
var amount = convertToAbsoluteValue(params[0]);
createFeColorMatrix(document, $filter, [0.2126 + 0.7874 * (1 - amount), 0.7152 - 0.7152 * (1 - amount), 0.0722 - 0.0722 * (1 - amount), 0, 0, 0.2126 - 0.2126 * (1 - amount), 0.7152 + 0.2848 * (1 - amount), 0.0722 - 0.0722 * (1 - amount), 0, 0, 0.2126 - 0.2126 * (1 - amount), 0.7152 - 0.7152 * (1 - amount), 0.0722 + 0.9278 * (1 - amount), 0, 0, 0, 0, 0, 1, 0]);
}
/**
* @see https://drafts.fxtf.org/filter-effects/#sepiaEquivalent
*/
function createSepia(document, $filter, params) {
var amount = convertToAbsoluteValue(params[0]);
createFeColorMatrix(document, $filter, [0.393 + 0.607 * (1 - amount), 0.769 - 0.769 * (1 - amount), 0.189 - 0.189 * (1 - amount), 0, 0, 0.349 - 0.349 * (1 - amount), 0.686 + 0.314 * (1 - amount), 0.168 - 0.168 * (1 - amount), 0, 0, 0.272 - 0.272 * (1 - amount), 0.534 - 0.534 * (1 - amount), 0.131 + 0.869 * (1 - amount), 0, 0, 0, 0, 0, 1, 0]);
}
var PATTERN_PREFIX = 'g-pattern-';
var cacheKey2IDMap = {};
var counter = 0;
function resetPatternCounter() {
counter = 0;
cacheKey2IDMap = {};
}
function createOrUpdateGradientAndPattern(document, $def, object, $el, parsedColor, name, createImage, plugin) {
// eg. clipPath don't have fill/stroke
if (!parsedColor) {
return '';
}
if (gLite.isCSSRGB(parsedColor)) {
// keep using currentColor @see https://github.com/d3/d3-axis/issues/49
if (object.style[name] === 'currentColor') {
$el === null || $el === void 0 || $el.setAttribute(name, 'currentColor');
} else {
// constant value, eg. '#fff'
$el === null || $el === void 0 || $el.setAttribute(name, parsedColor.isNone ? 'none' : parsedColor.toString());
}
} else if (gLite.isPattern(parsedColor)) {
var patternId = createOrUpdatePattern(document, $def, object, parsedColor, createImage, plugin);
// use style instead of attribute when applying <pattern>
// @see https://stackoverflow.com/a/7723115
$el.style[name] = "url(#".concat(patternId, ")");
return patternId;
} else {
if (parsedColor.length === 1) {
var gradientId = createOrUpdateGradient(document, object, $def, $el, parsedColor[0]);
$el === null || $el === void 0 || $el.setAttribute(name, "url(#".concat(gradientId, ")"));
return gradientId;
}
// @see https://stackoverflow.com/questions/20671502/can-i-blend-gradients-in-svg
var filterId = createOrUpdateMultiGradient(document, object, $def, $el, parsedColor);
$el === null || $el === void 0 || $el.setAttribute('filter', "url(#".concat(filterId, ")"));
$el === null || $el === void 0 || $el.setAttribute('fill', 'black');
return filterId;
}
return '';
}
function generateCacheKey(src) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var cacheKey = '';
if (gLite.isCSSGradientValue(src)) {
var type = src.type,
value = src.value;
if (type === gLite.GradientType.LinearGradient || type === gLite.GradientType.RadialGradient) {
// @ts-ignore
var _value$options = _objectSpread(_objectSpread({}, value), options),
_type = _value$options.type,
x = _value$options.x,
y = _value$options.y,
width = _value$options.width,
height = _value$options.height,
steps = _value$options.steps,
angle = _value$options.angle,
cx = _value$options.cx,
cy = _value$options.cy,
size = _value$options.size;
cacheKey = "gradient-".concat(_type, "-").concat((x === null || x === void 0 ? void 0 : x.toString()) || 0, "-").concat((y === null || y === void 0 ? void 0 : y.toString()) || 0, "-").concat((angle === null || angle === void 0 ? void 0 : angle.toString()) || 0, "-").concat((cx === null || cx === void 0 ? void 0 : cx.toString()) || 0, "-").concat((cy === null || cy === void 0 ? void 0 : cy.toString()) || 0, "-").concat((size === null || size === void 0 ? void 0 : size.toString()) || 0, "-").concat(width, "-").concat(height, "-").concat(steps.map(function (_ref) {
var offset = _ref.offset,
color = _ref.color;
return "".concat(offset).concat(color);
}).join('-'));
}
} else if (gLite.isPattern(src)) {
if (util.isString(src.image)) {
cacheKey = "pattern-".concat(src.image, "-").concat(src.repetition);
} else if (src.image.nodeName === 'rect') {
// use rect's entity as key
cacheKey = "pattern-rect-".concat(src.image.entity);
} else {
cacheKey = "pattern-".concat(counter);
}
}
if (cacheKey) {
if (!cacheKey2IDMap[cacheKey]) {
cacheKey2IDMap[cacheKey] = "".concat(PATTERN_PREFIX).concat(counter++);
}
}
return cacheKey2IDMap[cacheKey];
}
function formatTransform(transform) {
// @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/patternTransform
// should remove unit: rotate(20deg) -> rotate(20)
return gLite.parseTransform(transform).map(function (parsed) {
var t = parsed.t,
d = parsed.d;
if (t === 'translate') {
return "translate(".concat(d[0].value, " ").concat(d[1].value, ")");
}
if (t === 'translateX') {
return "translate(".concat(d[0].value, " 0)");
}
if (t === 'translateY') {
return "translate(0 ".concat(d[0].value, ")");
}
if (t === 'rotate') {
return "rotate(".concat(d[0].value, ")");
}
if (t === 'scale') {
// scale(1) scale(1, 1)
var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [1, 1];
return "scale(".concat(newScale[0], ", ").concat(newScale[1], ")");
}
if (t === 'scaleX') {
var _newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [1];
return "scale(".concat(_newScale[0], ", 1)");
}
if (t === 'scaleY') {
var _newScale2 = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [1];
return "scale(1, ".concat(_newScale2[0], ")");
}
if (t === 'skew') {
var newSkew = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [0, 0];
return "skewX(".concat(newSkew[0], ") skewY(").concat(newSkew[1], ")");
}
if (t === 'skewZ') {
var _newSkew = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [0];
return "skewX(".concat(_newSkew[0], ")");
}
if (t === 'skewY') {
var _newSkew2 = (d === null || d === void 0 ? void 0 : d.map(function (s) {
return s.value;
})) || [0];
return "skewY(".concat(_newSkew2[0], ")");
}
if (t === 'matrix') {
var _d$map = d.map(function (s) {
return s.value;
}),
_d$map2 = _slicedToArray(_d$map, 6),
a = _d$map2[0],
b = _d$map2[1],
c = _d$map2[2],
dd = _d$map2[3],
tx = _d$map2[4],
ty = _d$map2[5];
return "matrix(".concat(a, " ").concat(b, " ").concat(c, " ").concat(dd, " ").concat(tx, " ").concat(ty, ")");
}
return null;
}).filter(function (item) {
return item !== null;
}).join(' ');
}
function create$Pattern(document, $def, object, pattern, patternId, width, height) {
var repetition = pattern.repetition,
transform = pattern.transform;
// @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/pattern
var $pattern = createSVGElement('pattern', document);
if (transform) {
$pattern.setAttribute('patternTransform', formatTransform(transform));
}
$pattern.setAttribute('patternUnits', 'userSpaceOnUse');
$pattern.id = patternId;
$def.appendChild($pattern);
var _object$getGeometryBo = object.getGeometryBounds(),
halfExtents = _object$getGeometryBo.halfExtents,
min = _object$getGeometryBo.min;
$pattern.setAttribute('x', "".concat(min[0]));
$pattern.setAttribute('y', "".concat(min[1]));
// There is no equivalent to CSS no-repeat for SVG patterns
// @see https://stackoverflow.com/a/33481956
var patternWidth = width;
var patternHeight = height;
if (repetition === 'repeat-x') {
patternHeight = halfExtents[1] * 2;
} else if (repetition === 'repeat-y') {
patternWidth = halfExtents[0] * 2;
} else if (repetition === 'no-repeat') {
patternWidth = halfExtents[0] * 2;
patternHeight = halfExtents[1] * 2;
}
$pattern.setAttribute('width', "".concat(patternWidth));
$pattern.setAttribute('height', "".concat(patternHeight));
return $pattern;
}
function createOrUpdatePattern(document, $def, object, pattern, createImage, plugin) {
var patternId = generateCacheKey(pattern);
var $existed = $def.querySelector("#".concat(patternId));
if (!$existed) {
var image = pattern.image;
var imageURL = '';
if (util.isString(image)) {
imageURL = image;
} else if (gLite.isBrowser) {
if (image instanceof HTMLImageElement) {
imageURL = image.src;
} else if (image instanceof HTMLCanvasElement) {
imageURL = image.toDataURL();
} else ;
}
if (imageURL) {
var $image = createSVGElement('image', document);
// use href instead of xlink:href
// @see https://stackoverflow.com/a/13379007
$image.setAttribute('href', imageURL);
var img = createImage();
if (!imageURL.match(/^data:/i)) {
img.crossOrigin = 'Anonymous';
$image.setAttribute('crossorigin', 'anonymous');
}
img.src = imageURL;
var onload = function onload() {
var $pattern = create$Pattern(document, $def, object, pattern, patternId, img.width, img.height);
$def.appendChild($pattern);
$pattern.appendChild($image);
$image.setAttribute('x', '0');
$image.setAttribute('y', '0');
$image.setAttribute('width', "".concat(img.width));
$image.setAttribute('height', "".concat(img.height));
};
if (img.complete) {
onload();
} else {
img.onload = onload;
// Fix onload() bug in IE9
// img.src = img.src;
}
}
if (image.nodeName === 'rect') {
var _parsedStyle = image.parsedStyle,
width = _parsedStyle.width,
height = _parsedStyle.height;
var $pattern = create$Pattern(document, $def, image, pattern, patternId, width, height);
// traverse subtree of pattern
image.forEach(function (object) {
plugin.createSVGDom(document, object, null);
// @ts-ignore
var svgElement = object.elementSVG;
// apply local RTS transformation to <group> wrapper
var localTransform = object.getLocalTransform();
plugin.applyTransform(svgElement.$groupEl, localTransform);
});
// @ts-ignore
var svgElement = image.elementSVG;
$pattern.appendChild(svgElement.$groupEl);
}
}
return patternId;
}
function createOrUpdateGradient(document, object, $def, $el, parsedColor) {
var bounds = object.getGeometryBounds();
var width = bounds && bounds.halfExtents[0] * 2 || 0;
var height = bounds && bounds.halfExtents[1] * 2 || 0;
var min = bounds && bounds.min || [0, 0];
var gradientId = generateCacheKey(parsedColor, {
x: min[0],
y: min[1],
width: width,
height: height
});
var $existed = $def.querySelector("#".concat(gradientId));
if (!$existed) {
// <linearGradient> <radialGradient>
// @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/linearGradient
// @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/radialGradient
$existed = createSVGElement(parsedColor.type === gLite.GradientType.LinearGradient ? 'linearGradient' : 'radialGradient', document);
// @see https://github.com/antvis/g/issues/1025
$existed.setAttribute('gradientUnits', 'userSpaceOnUse');
// add stops
var innerHTML = '';
parsedColor.value.steps
// sort by offset @see https://github.com/antvis/G/issues/1171
.sort(function (a, b) {
return a.offset.value - b.offset.value;
}).forEach(function (_ref2) {
var offset = _ref2.offset,
color = _ref2.color;
// TODO: support absolute unit like `px`
innerHTML += "<stop offset=\"".concat(offset.value / 100, "\" stop-color=\"").concat(color, "\"></stop>");
});
$existed.innerHTML = innerHTML;
$existed.id = gradientId;
$def.appendChild($existed);
}
if (parsedColor.type === gLite.GradientType.LinearGradient) {
var _ref3 = parsedColor.value,
angle = _ref3.angle;
var _computeLinearGradien = gLite.computeLinearGradient([min[0], min[1]], width, height, angle),
x1 = _computeLinearGradien.x1,
y1 = _computeLinearGradien.y1,
x2 = _computeLinearGradien.x2,
y2 = _computeLinearGradien.y2;
$existed.setAttribute('x1', "".concat(x1));
$existed.setAttribute('y1', "".concat(y1));
$existed.setAttribute('x2', "".concat(x2));
$existed.setAttribute('y2', "".concat(y2));
// $existed.setAttribute('gradientTransform', `rotate(${angle})`);
} else {
var _ref4 = parsedColor.value,
cx = _ref4.cx,
cy = _ref4.cy,
size = _ref4.size;
var _computeRadialGradien = gLite.computeRadialGradient([min[0], min[1]], width, height, cx, cy, size),
x = _computeRadialGradien.x,
y = _computeRadialGradien.y,
r = _computeRadialGradien.r;
$existed.setAttribute('cx', "".concat(x));
$existed.setAttribute('cy', "".concat(y));
$existed.setAttribute('r', "".concat(r));
}
return gradientId;
}
function createOrUpdateMultiGradient(document, object, $def, $el, gradients) {
var filterId = "".concat(FILTER_PREFIX + object.entity, "-gradient");
var $existed = $def.querySelector("#".concat(filterId));
if (!$existed) {
$existed = createSVGElement('filter', document);
$existed.setAttribute('filterUnits', 'userSpaceOnUse');
// @see https://github.com/antvis/g/issues/1025
$existed.setAttribute('x', '0%');
$existed.setAttribute('y', '0%');
$existed.setAttribute('width', '100%');
$existed.setAttribute('height', '100%');
$existed.id = filterId;
$def.appendChild($existed);
}
/**
* <rect id="wave-rect" x="0" y="0" width="100%" height="100%" fill="url(#wave)"></rect>
* <filter id="blend-it" x="0%" y="0%" width="100%" height="100%">
<feImage xlink:href="#wave-rect" result="myWave" x="100" y="100"/>
<feImage xlink:href="#ry-rect" result="myRY" x="100" y="100"/>
<feBlend in="myWave" in2="myRY" mode="multiply" result="blendedGrad"/>
<feComposite in="blendedGrad" in2="SourceGraphic" operator="in"/>
</filter>
*/
var blended = 0;
gradients.forEach(function (gradient, i) {
var gradientId = createOrUpdateGradient(document, object, $def, $el, gradient);
var rectId = "".concat(gradientId, "_rect");
var $rect = createSVGElement('rect', document);
$rect.setAttribute('x', '0');
$rect.setAttribute('y', '0');
$rect.setAttribute('width', '100%');
$rect.setAttribute('height', '100%');
$rect.setAttribute('fill', "url(#".concat(gradientId, ")"));
$rect.id = rectId;
$def.appendChild($rect);
var $feImage = createSVGElement('feImage', document);
$feImage.setAttribute('href', "#".concat(rectId));
$feImage.setAttribute('result', "".concat(filterId, "-").concat(i));
$existed.appendChild($feImage);
if (i > 0) {
var $feBlend = createSVGElement('feBlend', document);
$feBlend.setAttribute('in', i === 1 ? "".concat(filterId, "-").concat(i - 1) : "".concat(filterId, "-blended-").concat(blended - 1));
$feBlend.setAttribute('in2', "".concat(filterId, "-").concat(i));
$feBlend.setAttribute('result', "".concat(filterId, "-blended-").concat(blended++));
// @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/blend-mode
$feBlend.setAttribute('mode', 'multiply');
$existed.appendChild($feBlend);
}
});
var $feComposite = createSVGElement('feComposite', document);
$feComposite.setAttribute('in', "".concat(filterId, "-blended-").concat(blended));
$feComposite.setAttribute('in2', 'SourceGraphic');
$feComposite.setAttribute('operator', 'in');
$existed.appendChild($feComposite);
return filterId;
}
var FILTER_DROPSHADOW_PREFIX = 'g-filter-dropshadow-';
/**
* use SVG filters
* @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/filter
*/
function createOrUpdateShadow(document, $def, object, $el, name) {
var _object$parsedStyle = object.parsedStyle,
_object$parsedStyle$s = _object$parsedStyle.shadowType,
shadowType = _object$parsedStyle$s === void 0 ? 'outer' : _object$parsedStyle$s,
shadowBlur = _object$parsedStyle.shadowBlur,
shadowColor = _object$parsedStyle.shadowColor,
shadowOffsetX = _object$parsedStyle.shadowOffsetX,
shadowOffsetY = _object$parsedStyle.shadowOffsetY;
var hasShadow = !util.isNil(shadowColor) && shadowBlur > 0;
var shadowId = FILTER_DROPSHADOW_PREFIX + object.entity;
var $existedFilter = $def.querySelector("#".concat(shadowId));
if ($existedFilter) {
var existedShadowType = $existedFilter.getAttribute('data-type');
if (existedShadowType !== shadowType || !hasShadow) {
// remove existed shadow
$existedFilter.remove();
$existedFilter = null;
}
}
// <Group> also has shadowType as its default value
// only apply shadow when blur > 0
if (hasShadow) {
// use filter <feDropShadow>
// @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDropShadow
$el === null || $el === void 0 || $el.setAttribute('filter', "url(#".concat(shadowId, ")"));
} else {
$el === null || $el === void 0 || $el.removeAttribute('filter');
return;
}
if (!$existedFilter) {
$existedFilter = createSVGElement('filter', document);
$existedFilter.setAttribute('data-type', shadowType);
if (shadowType === 'outer') {
var $feDropShadow = createSVGElement('feDropShadow', document);
$feDropShadow.setAttribute('dx', "".concat((shadowOffsetX || 0) / 2));
$feDropShadow.setAttribute('dy', "".concat((shadowOffsetY || 0) / 2));
$feDropShadow.setAttribute('stdDeviation', "".concat((shadowBlur || 0) / 4));
$feDropShadow.setAttribute('flood-color', shadowColor.toString());
$existedFilter.appendChild($feDropShadow);
} else if (shadowType === 'inner') {
var $feComponentTransfer = createSVGElement('feComponentTransfer', document);
$feComponentTransfer.setAttribute('in', 'SourceAlpha');
var $feFuncA = createSVGElement('feFuncA', document);
$feFuncA.setAttribute('type', 'table');
$feFuncA.setAttribute('tableValues', '1 0');
$feComponentTransfer.appendChild($feFuncA);
$existedFilter.appendChild($feComponentTransfer);
var $feGaussianBlur = createSVGElement('feGaussianBlur', document);
$feGaussianBlur.setAttribute('stdDeviation', "".concat((shadowBlur || 0) / 4));
$existedFilter.appendChild($feGaussianBlur);
var $feOffset = createSVGElement('feOffset', document);
$feOffset.setAttribute('dx', "".concat((shadowOffsetX || 0) / 2));
$feOffset.setAttribute('dy', "".concat((shadowOffsetY || 0) / 2));
$feOffset.setAttribute('result', 'offsetblur');
$existedFilter.appendChild($feOffset);
var $feFlood = createSVGElement('feFlood', document);
$feFlood.setAttribute('flood-color', shadowColor.toString());
$feFlood.setAttribute('result', 'color');
$existedFilter.appendChild($feFlood);
var $feComposite = createSVGElement('feComposite', document);
$feComposite.setAttribute('in2', 'offsetblur');
$feComposite.setAttribute('operator', 'in');
$existedFilter.appendChild($feComposite);
var $feComposite2 = createSVGElement('feComposite', document);
$feComposite2.setAttribute('in2', 'SourceAlpha');
$feComposite2.setAttribute('operator', 'in');
$existedFilter.appendChild($feComposite2);
var $feMerge = createSVGElement('feMerge', document);
$existedFilter.appendChild($feMerge);
var $feMergeNode = createSVGElement('feMergeNode', document);
$feMergeNode.setAttribute('in', 'SourceGraphic');
var $feMergeNode2 = createSVGElement('feMergeNode', document);
$feMerge.appendChild($feMergeNode);
$feMerge.appendChild($feMergeNode2);
}
$existedFilter.id = shadowId;
// @see https://github.com/antvis/g/issues/1025
$existedFilter.setAttribute('filterUnits', 'userSpaceOnUse');
$def.appendChild($existedFilter);
return;
}
if (shadowType === 'inner') {
var _$feGaussianBlur = $existedFilter.children[1];
var _$feOffset = $existedFilter.children[2];
var _$feFlood = $existedFilter.children[3];
if (name === 'shadowColor') {
_$feFlood.setAttribute('flood-color', shadowColor.toString());
} else if (name === 'shadowBlur') {
// half the blur radius
// @see https://drafts.csswg.org/css-backgrounds/#shadow-blur
// @see https://css-tricks.com/breaking-css-box-shadow-vs-drop-shadow/
_$feGaussianBlur.setAttribute('stdDeviation', "".concat((shadowBlur || 0) / 4));
} else if (name === 'shadowOffsetX') {
_$feOffset.setAttribute('dx', "".concat((shadowOffsetX || 0) / 2));
} else if (name === 'shadowOffsetY') {
_$feOffset.setAttribute('dy', "".concat((shadowOffsetY || 0) / 2));
}
} else if (shadowType === 'outer') {
var _$feDropShadow = $existedFilter.children[0];
if (name === 'shadowColor') {
_$feDropShadow.setAttribute('flood-color', shadowColor.toString());
} else if (name === 'shadowBlur') {
// half the blur radius
// @see https://drafts.csswg.org/css-backgrounds/#shadow-blur
// @see https://css-tricks.com/breaking-css-box-shadow-vs-drop-shadow/
_$feDropShadow.setAttribute('stdDeviation', "".concat((shadowBlur || 0) / 4));
} else if (name === 'shadowOffsetX') {
_$feDropShadow.setAttribute('dx', "".concat((shadowOffsetX || 0) / 2));
} else if (name === 'shadowOffsetY') {
_$feDropShadow.setAttribute('dy', "".concat((shadowOffsetY || 0) / 2));
}
}
}
var urlRegexp = /url\("?#(.*)\)/;
var DefElementManager = /*#__PURE__*/function () {
function DefElementManager(context) {
_classCallCheck(this, DefElementManager);
this.gradientCache = {};
this.context = context;
}
/**
* container for <gradient> <clipPath>...
*/
return _createClass(DefElementManager, [{
key: "getDefElement",
value: function getDefElement() {
return this.$def;
}
}, {
key: "init",
value: function init() {
var document = this.context.config.document;
var $svg = this.context.contextService.getContext();
this.$def = createSVGElement('defs', document);
$svg.appendChild(this.$def);
}
}, {
key: "clear",
value: function clear(entity) {
var _this = this;
Object.keys(this.gradientCache).forEach(function (id) {
_this.clearUnusedDefElement(_this.gradientCache, id, entity);
});
}
}, {
key: "clearUnusedDefElement",
value: function clearUnusedDefElement(cache, id, entity) {
if (cache[id] && cache[id].size === 1 && cache[id].has(entity)) {
var targetElement = this.$def.querySelector("#".concat(id));
if (targetElement) {
this.$def.removeChild(targetElement);
}
}
}
}, {
key: "createOrUpdateGradientAndPattern",
value: function createOrUpdateGradientAndPattern$1(object, $el, parsedColor, name, plugin) {
var _this$context$config = this.context.config,
doc = _this$context$config.document,
createImage = _this$context$config.createImage;
if ($el) {
var attributeValue = '';
if (gLite.isPattern(parsedColor)) {
// `fill: url(#${patternId})`
attributeValue = $el.style[name];
} else {
// `url(#${gradientId})`
attributeValue = $el.getAttribute(name) || '';
}
var matches = attributeValue.match(urlRegexp);
if (matches && matches.length > 1) {
this.clearUnusedDefElement(this.gradientCache, matches[1].replace('"', ''), object.entity);
}
var newDefElementId = createOrUpdateGradientAndPattern(doc || document, this.$def, object, $el, parsedColor, name, createImage, plugin);
if (newDefElementId) {
if (!this.gradientCache[newDefElementId]) {
this.gradientCache[newDefElementId] = new Set();
}
this.gradientCache[newDefElementId].add(object.entity);
}
}
}
}, {
key: "createOrUpdateShadow",
value: function createOrUpdateShadow$1(object, $el, name) {
var doc = this.context.config.document;
createOrUpdateShadow(doc || document, this.$def, object, $el, name);
}
}, {
key: "createOrUpdateFilter",
value: function createOrUpdateFilter$1(object, $el, filters) {
var doc = this.context.config.document;
createOrUpdateFilter(doc || document, this.$def, object, $el, filters);
}
}]);
}();
function numberToLongString(x) {
return x.toFixed(6).replace('.000000', '');
}
function convertHTML(str) {
var regex = /[&|<|>|"|']/g;
return str.replace(regex, function (match) {
if (match === '&') {
return '&';
}
if (match === '<') {
return '<';
}
if (match === '>') {
return '>';
}
if (match === '"') {
return '"';
}
return ''';
});
}
var SVG_ATTR_MAP = {
opacity: 'opacity',
fillStyle: 'fill',
fill: 'fill',
fillRule: 'fill-rule',
fillOpacity: 'fill-opacity',
strokeStyle: 'stroke',
strokeOpacity: 'stroke-opacity',
stroke: 'stroke',
clipPath: 'clip-path',
textPath: 'text-path',
r: 'r',
cx: 'cx',
cy: 'cy',
rx: 'rx',
ry: 'ry',
x: 'x',
y: 'y',
width: 'width',
height: 'height',
lineCap: 'stroke-linecap',
lineJoin: 'stroke-linejoin',
lineWidth: 'stroke-width',
lineDash: 'stroke-dasharray',
lineDashOffset: 'stroke-dashoffset',
miterLimit: 'stroke-miterlimit',
font: 'font',
fontSize: 'font-size',
fontStyle: 'font-style',
fontVariant: 'font-variant',
fontWeight: 'font-weight',
fontFamily: 'font-family',
letterSpacing: 'letter-spacing',
startArrow: 'marker-start',
endArrow: 'marker-end',
"class": 'class',
id: 'id',
// style: 'style',
preserveAspectRatio: 'preserveAspectRatio',
visibility: 'visibility',
shadowColor: 'flood-color',
shadowBlur: 'stdDeviation',
shadowOffsetX: 'dx',
shadowOffsetY: 'dy',
filter: 'filter',
innerHTML: 'innerHTML',
textAlign: 'text-anchor',
pointerEvents: 'pointer-events'
};
var FORMAT_VALUE_MAP = {
textAlign: {
inherit: 'inherit',
left: 'left',
start: 'left',
center: 'middle',
right: 'end',
end: 'end'
}
};
var DEFAULT_VALUE_MAP = {
textAlign: 'inherit',
// textBaseline: 'alphabetic',
// @see https://www.w3.org/TR/SVG/painting.html#LineCaps
lineCap: 'butt',
// @see https://www.w3.org/TR/SVG/painting.html#LineJoin
lineJoin: 'miter',
// @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-width
lineWidth: '1px',
opacity: '1',
fillOpacity: '1',
fillRule: 'nonzero',
strokeOpacity: '1',
strokeWidth: '0',
strokeMiterLimit: '4',
letterSpacing: '0',
fontSize: 'inherit',
fontFamily: 'inherit',
pointerEvents: 'auto',
transform: 'matrix(1,0,0,1,0,0)'
};
/**
* G_SVG_PREFIX + nodeName + entity
*
* eg. g_svg_circle_345
*/
var G_SVG_PREFIX = 'g-svg';
var CLIP_PATH_PREFIX = 'clip-path-';
var TEXT_PATH_PREFIX = 'text-path-';
var SVGRendererPlugin = /*#__PURE__*/function () {
function SVGRendererPlugin(pluginOptions, defElementManager, context) {
_classCallCheck(this, SVGRendererPlugin);
/**
* Will be used in svg-picker for finding relative SVG element of current DisplayObject.
*/
this.svgElementMap = new WeakMap();
/**
* render at the end of frame
*/
this.renderQueue = [];
/**
* dirty attributes at the end of frame
*/
this.dirtyAttributes = new WeakMap();
/**
* reorder after mounted
*/
this.pendingReorderQueue = new Set();
/**
* <use> elements in <clipPath>, which should be sync with clipPath
*
* @example
* <clipPath transform="matrix(1,0,0,1,-100,-155)" id="clip-path-0-2">
* <use href="#g_svg_circle_0" transform="matrix(1.477115,0,0,1.477115,150,150)">
* </use>
* </clipPath>
*/
this.clipPathUseMap = new WeakMap();
this.pluginOptions = pluginOptions;
this.defElementManager = defElementManager;
this.context = context;
}
return _createClass(SVGRendererPlugin, [{
key: "apply",
value: function apply(context) {
var _this = this;
var renderingService = context.renderingService,
renderingContext = context.renderingContext;
this.context = context;
// @ts-ignore
this.context.svgElementMap = this.svgElementMap;
var canvas = renderingContext.root.ownerDocument.defaultView;
var document = this.context.config.document;
var handleMounted = function handleMounted(e) {
var object = e.target;
// should remove clipPath already existed in <defs>
var $useRefs = _this.clipPathUseMap.get(object);
if ($useRefs) {
var $def = _this.defElementManager.getDefElement();
var existed = $def.querySelector("#".concat(_this.getId(object)));
if (existed) {
existed.remove();
}
}
// create SVG DOM Node
_this.createSVGDom(document, object, _this.$camera);
};
var handleUnmounted = function handleUnmounted(e) {
var object = e.target;
_this.defElementManager.clear(object.entity);
_this.clipPathUseMap["delete"](object);
_this.removeSVGDom(object);
};
var reorderChildren = function reorderChildren(object) {
var _object$parentNode;
var parent = object.parentNode;
// @ts-ignore
var $groupEl = (_object$parentNode = object.parentNode) === null || _object$parentNode === void 0 || (_object$parentNode = _object$parentNode.elementSVG) === null || _object$parentNode === void 0 ? void 0 : _object$parentNode.$groupEl;
var children = ((parent === null || parent === void 0 ? void 0 : parent.children) || []).slice();
if ($groupEl) {
_this.reorderChildren(document, $groupEl, children);
}
};
var handleReparent = function handleReparent(e) {
var object = e.target;
reorderChildren(object);
};
var handleAttributeChanged = function handleAttributeChanged(e) {
var object = e.target;
// @see https://github.com/antvis/g/issues/994
// @ts-ignore
if (!object.elementSVG) {
return;
}
var attrName = e.attrName;
var attribtues = _this.dirtyAttributes.get(object);
if (!attribtues) {
_this.dirtyAttributes.set(object, []);
attribtues = _this.dirtyAttributes.get(object);
}
attribtues.push(attrName);
};
var handleGeometryBoundsChanged = function handleGeometryBoundsChanged(e) {
var records = e.detail;
var _loop = function _loop() {
var record = records[i];
var object = record.target;
var nodes = object.nodeName === gLite.Shape.FRAGMENT ? object.childNodes : [object];
nodes.forEach(function (node) {
var _object$elementSVG;
// @ts-ignore
var $el = (_object$elementSVG = object.elementSVG) === null || _object$elementSVG === void 0 ? void 0 : _object$elementSVG.$el;
var _object$parsedStyle = object.parsedStyle,
fill = _object$parsedStyle.fill,
stroke = _object$parsedStyle.stroke,
clipPath = _object$parsedStyle.clipPath;
if (fill && !gLite.isCSSRGB(fill)) {
_this.defElementManager.createOrUpdateGradientAndPattern(object, $el, fill, 'fill', _this);
}
if (stroke && !gLite.isCSSRGB(stroke)) {
_this.defElementManager.createOrUpdateGradientAndPattern(object, $el, stroke, 'stroke', _this);
}
if (clipPath) {
var parentInvert = glMatrix.mat4.invert(glMatrix.mat4.create(), object.getWorldTransform());
var clipPathId = "".concat(CLIP_PATH_PREFIX + clipPath.entity, "-").concat(object.entity);
var $def = _this.defElementManager.getDefElement();
var $existed = $def.querySelector("#".concat(clipPathId));
if ($existed) {
_this.applyTransform($existed, parentInvert);
}
}
});
};
for (var i = 0; i < records.length; i++) {
_loop();
}
};
renderingService.hooks.init.tap(SVGRendererPlugin.tag, function () {
var _this$context$config = _this.context.config,
background = _this$context$config.background,
document = _this$context$config.document;
// <defs>
_this.defElementManager.init();
var $svg = _this.context.contextService.getContext();
if (background) {
$svg.style.background = background;
}
// @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/color-interpolation-filters
$svg.setAttribute('color-interpolation-filters', 'sRGB');
_this.$camera = createSVGElement('g', document);
_this.$camera.id = "".concat(G_SVG_PREFIX, "-camera");
_this.applyTransform(_this.$camera, _this.context.camera.getOrthoMatrix());
$svg.appendChild(_this.$camera);
canvas.addEventListener(gLite.ElementEvent.MOUNTED, handleMounted);
canvas.addEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted);
canvas.addEventListener(gLite.ElementEvent.REPARENT, handleReparent);
canvas.addEventListener(gLite.ElementEvent.ATTR_MODIFIED, hand