"use strict"; /** * 快照插件,生成视图 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Snapshot = void 0; var Snapshot = /** @class */ (function () { function Snapshot(_a) { var _this = this; var lf = _a.lf; this.lf = lf; this.customCssRules = ''; this.useGlobalRules = true; /* 下载快照 */ lf.getSnapshot = function (fileName, backgroundColor) { _this.getSnapshot(fileName, backgroundColor); }; /* 获取Blob对象,用户图片上传 */ lf.getSnapshotBlob = function (backgroundColor) { return _this.getSnapshotBlob(backgroundColor); }; /* 获取Base64对象,用户图片上传 */ lf.getSnapshotBase64 = function (backgroundColor) { return _this.getSnapshotBase64(backgroundColor); }; } /* 获取svgRoot对象 */ Snapshot.prototype.getSvgRootElement = function (lf) { var _this = this; this.offsetX = Number.MAX_SAFE_INTEGER; this.offsetY = Number.MAX_SAFE_INTEGER; lf.graphModel.nodes.forEach(function (item) { var x = item.x, width = item.width, y = item.y, height = item.height; var offsetX = x - width / 2; var offsetY = y - height / 2; if (offsetX < _this.offsetX) { _this.offsetX = offsetX - 5; } if (offsetY < _this.offsetY) { _this.offsetY = offsetY - 5; } }); lf.graphModel.edges.forEach(function (edge) { if (edge.pointsList) { edge.pointsList.forEach(function (point) { var x = point.x, y = point.y; if (x < _this.offsetX) { _this.offsetX = x - 5; } if (y < _this.offsetY) { _this.offsetY = y - 5; } }); } }); var svgRootElement = lf.container.querySelector('.lf-canvas-overlay'); return svgRootElement; }; Snapshot.prototype.triggerDownload = function (imgURI) { var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true, }); var a = document.createElement('a'); a.setAttribute('download', this.fileName); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); }; Snapshot.prototype.removeAnchor = function (element) { var childNodes = element.childNodes; var childLength = element.childNodes && element.childNodes.length; for (var i = 0; i < childLength; i++) { var child = childNodes[i]; var classList = (child.classList && Array.from(child.classList)) || []; if (classList.indexOf('lf-anchor') > -1) { element.removeChild(element.childNodes[i]); childLength--; i--; } } }; /* 下载图片 */ Snapshot.prototype.getSnapshot = function (fileName, backgroundColor) { var _this = this; this.fileName = fileName || "logic-flow." + Date.now() + ".png"; var svg = this.getSvgRootElement(this.lf); this.getCanvasData(svg, backgroundColor).then(function (canvas) { var imgURI = canvas.toDataURL('image/png') .replace('image/png', 'image/octet-stream'); _this.triggerDownload(imgURI); }); }; /* 获取base64对象 */ Snapshot.prototype.getSnapshotBase64 = function (backgroundColor) { var _this = this; var svg = this.getSvgRootElement(this.lf); return new Promise(function (resolve) { _this.getCanvasData(svg, backgroundColor).then(function (canvas) { var base64 = canvas.toDataURL('image/png'); // 输出图片数据以及图片宽高 resolve({ data: base64, width: canvas.width, height: canvas.height }); }); }); }; /* 获取Blob对象 */ Snapshot.prototype.getSnapshotBlob = function (backgroundColor) { var _this = this; var svg = this.getSvgRootElement(this.lf); return new Promise(function (resolve) { _this.getCanvasData(svg, backgroundColor).then(function (canvas) { canvas.toBlob(function (blob) { // 输出图片数据以及图片宽高 resolve({ data: blob, width: canvas.width, height: canvas.height }); }, 'image/png'); }); }); }; Snapshot.prototype.getClassRules = function () { var rules = ''; if (this.useGlobalRules) { var styleSheets = document.styleSheets; for (var i = 0; i < styleSheets.length; i++) { var sheet = styleSheets[i]; for (var j = 0; j < sheet.cssRules.length; j++) { rules += sheet.cssRules[j].cssText; } } } if (this.customCssRules) { rules += this.customCssRules; } return rules; }; // 获取图片生成中中间产物canvas对象,用户转换为其他需要的格式 Snapshot.prototype.getCanvasData = function (svg, backgroundColor) { var _this = this; var copy = svg.cloneNode(true); var graph = copy.lastChild; var childLength = graph.childNodes && graph.childNodes.length; if (childLength) { for (var i = 0; i < childLength; i++) { var lfLayer = graph.childNodes[i]; // 只保留包含节点和边的基础图层进行下载,其他图层删除 var layerClassList = lfLayer.classList && Array.from(lfLayer.classList); if (layerClassList && layerClassList.indexOf('lf-base') < 0) { graph.removeChild(graph.childNodes[i]); childLength--; i--; } else { // 删除锚点 var lfBase = graph.childNodes[i]; lfBase && lfBase.childNodes.forEach(function (item) { var element = item; _this.removeAnchor(element.firstChild); }); } } } // offset值加10,保证图形不会紧贴着下载图片的左边和上边 copy.lastChild.style.transform = "matrix(1, 0, 0, 1, " + (-this.offsetX + 10) + ", " + (-this.offsetY + 10) + ")"; var dpr = window.devicePixelRatio || 1; var canvas = document.createElement('canvas'); /* 为了计算真实宽高需要取图的真实dom 真实dom存在缩放影响其宽高数值 在得到真实宽高后除以缩放比例即可得到正常宽高 */ var base = this.lf.graphModel.rootEl.querySelector('.lf-base'); var bbox = base.getBoundingClientRect(); var graphModel = this.lf.graphModel; var transformModel = graphModel.transformModel; var SCALE_X = transformModel.SCALE_X, SCALE_Y = transformModel.SCALE_Y; var bboxWidth = Math.ceil(bbox.width / SCALE_X); var bboxHeight = Math.ceil(bbox.height / SCALE_Y); // width,height 值加40,保证图形不会紧贴着下载图片的右边和下边 canvas.style.width = bboxWidth + "px"; canvas.style.height = bboxHeight + "px"; canvas.width = bboxWidth * dpr + 80; canvas.height = bboxHeight * dpr + 80; var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.scale(dpr, dpr); // 如果有背景色,设置流程图导出的背景色 if (backgroundColor) { ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, bboxWidth * dpr + 80, bboxHeight * dpr + 80); } else { ctx.clearRect(0, 0, bboxWidth, bboxHeight); } var img = new Image(); var style = document.createElement('style'); style.innerHTML = this.getClassRules(); var foreignObject = document.createElement('foreignObject'); foreignObject.appendChild(style); copy.appendChild(foreignObject); return new Promise(function (resolve) { img.onload = function () { ctx.drawImage(img, 0, 0); resolve(canvas); }; /* 因为svg中存在dom存放在foreignObject元素中 SVG图形转成img对象 todo: 会导致一些清晰度问题这个需要再解决 fixme: XMLSerializer的中的css background url不会下载图片 */ var svg2Img = "data:image/svg+xml;charset=utf-8," + new XMLSerializer().serializeToString(copy); var imgSrc = svg2Img.replace(/\n/g, '').replace(/\t/g, '').replace(/#/g, '%23'); img.src = imgSrc; }); }; Snapshot.pluginName = 'snapshot'; return Snapshot; }()); exports.Snapshot = Snapshot; exports.default = Snapshot;