123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- import { brush, setClipPath, setGradient, setPattern } from './graphic.js';
- import { createElement, createVNode, vNodeToString, getCssString, createBrushScope, createSVGVNode } from './core.js';
- import { normalizeColor, encodeBase64, isGradient, isPattern } from './helper.js';
- import { extend, keys, logError, map, noop, retrieve2 } from '../core/util.js';
- import patch, { updateAttrs } from './patch.js';
- import { getSize } from '../canvas/helper.js';
- var svgId = 0;
- var SVGPainter = (function () {
- function SVGPainter(root, storage, opts) {
- this.type = 'svg';
- this.refreshHover = createMethodNotSupport('refreshHover');
- this.configLayer = createMethodNotSupport('configLayer');
- this.storage = storage;
- this._opts = opts = extend({}, opts);
- this.root = root;
- this._id = 'zr' + svgId++;
- this._oldVNode = createSVGVNode(opts.width, opts.height);
- if (root && !opts.ssr) {
- var viewport = this._viewport = document.createElement('div');
- viewport.style.cssText = 'position:relative;overflow:hidden';
- var svgDom = this._svgDom = this._oldVNode.elm = createElement('svg');
- updateAttrs(null, this._oldVNode);
- viewport.appendChild(svgDom);
- root.appendChild(viewport);
- }
- this.resize(opts.width, opts.height);
- }
- SVGPainter.prototype.getType = function () {
- return this.type;
- };
- SVGPainter.prototype.getViewportRoot = function () {
- return this._viewport;
- };
- SVGPainter.prototype.getViewportRootOffset = function () {
- var viewportRoot = this.getViewportRoot();
- if (viewportRoot) {
- return {
- offsetLeft: viewportRoot.offsetLeft || 0,
- offsetTop: viewportRoot.offsetTop || 0
- };
- }
- };
- SVGPainter.prototype.getSvgDom = function () {
- return this._svgDom;
- };
- SVGPainter.prototype.refresh = function () {
- if (this.root) {
- var vnode = this.renderToVNode({
- willUpdate: true
- });
- vnode.attrs.style = 'position:absolute;left:0;top:0;user-select:none';
- patch(this._oldVNode, vnode);
- this._oldVNode = vnode;
- }
- };
- SVGPainter.prototype.renderOneToVNode = function (el) {
- return brush(el, createBrushScope(this._id));
- };
- SVGPainter.prototype.renderToVNode = function (opts) {
- opts = opts || {};
- var list = this.storage.getDisplayList(true);
- var width = this._width;
- var height = this._height;
- var scope = createBrushScope(this._id);
- scope.animation = opts.animation;
- scope.willUpdate = opts.willUpdate;
- scope.compress = opts.compress;
- scope.emphasis = opts.emphasis;
- var children = [];
- var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);
- bgVNode && children.push(bgVNode);
- var mainVNode = !opts.compress
- ? (this._mainVNode = createVNode('g', 'main', {}, [])) : null;
- this._paintList(list, scope, mainVNode ? mainVNode.children : children);
- mainVNode && children.push(mainVNode);
- var defs = map(keys(scope.defs), function (id) { return scope.defs[id]; });
- if (defs.length) {
- children.push(createVNode('defs', 'defs', {}, defs));
- }
- if (opts.animation) {
- var animationCssStr = getCssString(scope.cssNodes, scope.cssAnims, { newline: true });
- if (animationCssStr) {
- var styleNode = createVNode('style', 'stl', {}, [], animationCssStr);
- children.push(styleNode);
- }
- }
- return createSVGVNode(width, height, children, opts.useViewBox);
- };
- SVGPainter.prototype.renderToString = function (opts) {
- opts = opts || {};
- return vNodeToString(this.renderToVNode({
- animation: retrieve2(opts.cssAnimation, true),
- emphasis: retrieve2(opts.cssEmphasis, true),
- willUpdate: false,
- compress: true,
- useViewBox: retrieve2(opts.useViewBox, true)
- }), { newline: true });
- };
- SVGPainter.prototype.setBackgroundColor = function (backgroundColor) {
- this._backgroundColor = backgroundColor;
- };
- SVGPainter.prototype.getSvgRoot = function () {
- return this._mainVNode && this._mainVNode.elm;
- };
- SVGPainter.prototype._paintList = function (list, scope, out) {
- var listLen = list.length;
- var clipPathsGroupsStack = [];
- var clipPathsGroupsStackDepth = 0;
- var currentClipPathGroup;
- var prevClipPaths;
- var clipGroupNodeIdx = 0;
- for (var i = 0; i < listLen; i++) {
- var displayable = list[i];
- if (!displayable.invisible) {
- var clipPaths = displayable.__clipPaths;
- var len = clipPaths && clipPaths.length || 0;
- var prevLen = prevClipPaths && prevClipPaths.length || 0;
- var lca = void 0;
- for (lca = Math.max(len - 1, prevLen - 1); lca >= 0; lca--) {
- if (clipPaths && prevClipPaths
- && clipPaths[lca] === prevClipPaths[lca]) {
- break;
- }
- }
- for (var i_1 = prevLen - 1; i_1 > lca; i_1--) {
- clipPathsGroupsStackDepth--;
- currentClipPathGroup = clipPathsGroupsStack[clipPathsGroupsStackDepth - 1];
- }
- for (var i_2 = lca + 1; i_2 < len; i_2++) {
- var groupAttrs = {};
- setClipPath(clipPaths[i_2], groupAttrs, scope);
- var g = createVNode('g', 'clip-g-' + clipGroupNodeIdx++, groupAttrs, []);
- (currentClipPathGroup ? currentClipPathGroup.children : out).push(g);
- clipPathsGroupsStack[clipPathsGroupsStackDepth++] = g;
- currentClipPathGroup = g;
- }
- prevClipPaths = clipPaths;
- var ret = brush(displayable, scope);
- if (ret) {
- (currentClipPathGroup ? currentClipPathGroup.children : out).push(ret);
- }
- }
- }
- };
- SVGPainter.prototype.resize = function (width, height) {
- var opts = this._opts;
- var root = this.root;
- var viewport = this._viewport;
- width != null && (opts.width = width);
- height != null && (opts.height = height);
- if (root && viewport) {
- viewport.style.display = 'none';
- width = getSize(root, 0, opts);
- height = getSize(root, 1, opts);
- viewport.style.display = '';
- }
- if (this._width !== width || this._height !== height) {
- this._width = width;
- this._height = height;
- if (viewport) {
- var viewportStyle = viewport.style;
- viewportStyle.width = width + 'px';
- viewportStyle.height = height + 'px';
- }
- if (!isPattern(this._backgroundColor)) {
- var svgDom = this._svgDom;
- if (svgDom) {
- svgDom.setAttribute('width', width);
- svgDom.setAttribute('height', height);
- }
- var bgEl = this._bgVNode && this._bgVNode.elm;
- if (bgEl) {
- bgEl.setAttribute('width', width);
- bgEl.setAttribute('height', height);
- }
- }
- else {
- this.refresh();
- }
- }
- };
- SVGPainter.prototype.getWidth = function () {
- return this._width;
- };
- SVGPainter.prototype.getHeight = function () {
- return this._height;
- };
- SVGPainter.prototype.dispose = function () {
- if (this.root) {
- this.root.innerHTML = '';
- }
- this._svgDom =
- this._viewport =
- this.storage =
- this._oldVNode =
- this._bgVNode =
- this._mainVNode = null;
- };
- SVGPainter.prototype.clear = function () {
- if (this._svgDom) {
- this._svgDom.innerHTML = null;
- }
- this._oldVNode = null;
- };
- SVGPainter.prototype.toDataURL = function (base64) {
- var str = this.renderToString();
- var prefix = 'data:image/svg+xml;';
- if (base64) {
- str = encodeBase64(str);
- return str && prefix + 'base64,' + str;
- }
- return prefix + 'charset=UTF-8,' + encodeURIComponent(str);
- };
- return SVGPainter;
- }());
- function createMethodNotSupport(method) {
- return function () {
- if (process.env.NODE_ENV !== 'production') {
- logError('In SVG mode painter not support method "' + method + '"');
- }
- };
- }
- function createBackgroundVNode(width, height, backgroundColor, scope) {
- var bgVNode;
- if (backgroundColor && backgroundColor !== 'none') {
- bgVNode = createVNode('rect', 'bg', {
- width: width,
- height: height,
- x: '0',
- y: '0'
- });
- if (isGradient(backgroundColor)) {
- setGradient({ fill: backgroundColor }, bgVNode.attrs, 'fill', scope);
- }
- else if (isPattern(backgroundColor)) {
- setPattern({
- style: {
- fill: backgroundColor
- },
- dirty: noop,
- getBoundingRect: function () { return ({ width: width, height: height }); }
- }, bgVNode.attrs, 'fill', scope);
- }
- else {
- var _a = normalizeColor(backgroundColor), color = _a.color, opacity = _a.opacity;
- bgVNode.attrs.fill = color;
- opacity < 1 && (bgVNode.attrs['fill-opacity'] = opacity);
- }
- }
- return bgVNode;
- }
- export default SVGPainter;
|