index.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. "use strict";
  2. /**
  3. * 快照插件,生成视图
  4. */
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.Snapshot = void 0;
  7. var Snapshot = /** @class */ (function () {
  8. function Snapshot(_a) {
  9. var _this = this;
  10. var lf = _a.lf;
  11. this.lf = lf;
  12. this.customCssRules = '';
  13. this.useGlobalRules = true;
  14. /* 下载快照 */
  15. lf.getSnapshot = function (fileName, backgroundColor) {
  16. _this.getSnapshot(fileName, backgroundColor);
  17. };
  18. /* 获取Blob对象,用户图片上传 */
  19. lf.getSnapshotBlob = function (backgroundColor) { return _this.getSnapshotBlob(backgroundColor); };
  20. /* 获取Base64对象,用户图片上传 */
  21. lf.getSnapshotBase64 = function (backgroundColor) { return _this.getSnapshotBase64(backgroundColor); };
  22. }
  23. /* 获取svgRoot对象 */
  24. Snapshot.prototype.getSvgRootElement = function (lf) {
  25. var _this = this;
  26. this.offsetX = Number.MAX_SAFE_INTEGER;
  27. this.offsetY = Number.MAX_SAFE_INTEGER;
  28. lf.graphModel.nodes.forEach(function (item) {
  29. var x = item.x, width = item.width, y = item.y, height = item.height;
  30. var offsetX = x - width / 2;
  31. var offsetY = y - height / 2;
  32. if (offsetX < _this.offsetX) {
  33. _this.offsetX = offsetX - 5;
  34. }
  35. if (offsetY < _this.offsetY) {
  36. _this.offsetY = offsetY - 5;
  37. }
  38. });
  39. lf.graphModel.edges.forEach(function (edge) {
  40. if (edge.pointsList) {
  41. edge.pointsList.forEach(function (point) {
  42. var x = point.x, y = point.y;
  43. if (x < _this.offsetX) {
  44. _this.offsetX = x - 5;
  45. }
  46. if (y < _this.offsetY) {
  47. _this.offsetY = y - 5;
  48. }
  49. });
  50. }
  51. });
  52. var svgRootElement = lf.container.querySelector('.lf-canvas-overlay');
  53. return svgRootElement;
  54. };
  55. Snapshot.prototype.triggerDownload = function (imgURI) {
  56. var evt = new MouseEvent('click', {
  57. view: window,
  58. bubbles: false,
  59. cancelable: true,
  60. });
  61. var a = document.createElement('a');
  62. a.setAttribute('download', this.fileName);
  63. a.setAttribute('href', imgURI);
  64. a.setAttribute('target', '_blank');
  65. a.dispatchEvent(evt);
  66. };
  67. Snapshot.prototype.removeAnchor = function (element) {
  68. var childNodes = element.childNodes;
  69. var childLength = element.childNodes && element.childNodes.length;
  70. for (var i = 0; i < childLength; i++) {
  71. var child = childNodes[i];
  72. var classList = (child.classList && Array.from(child.classList)) || [];
  73. if (classList.indexOf('lf-anchor') > -1) {
  74. element.removeChild(element.childNodes[i]);
  75. childLength--;
  76. i--;
  77. }
  78. }
  79. };
  80. /* 下载图片 */
  81. Snapshot.prototype.getSnapshot = function (fileName, backgroundColor) {
  82. var _this = this;
  83. this.fileName = fileName || "logic-flow." + Date.now() + ".png";
  84. var svg = this.getSvgRootElement(this.lf);
  85. this.getCanvasData(svg, backgroundColor).then(function (canvas) {
  86. var imgURI = canvas.toDataURL('image/png')
  87. .replace('image/png', 'image/octet-stream');
  88. _this.triggerDownload(imgURI);
  89. });
  90. };
  91. /* 获取base64对象 */
  92. Snapshot.prototype.getSnapshotBase64 = function (backgroundColor) {
  93. var _this = this;
  94. var svg = this.getSvgRootElement(this.lf);
  95. return new Promise(function (resolve) {
  96. _this.getCanvasData(svg, backgroundColor).then(function (canvas) {
  97. var base64 = canvas.toDataURL('image/png');
  98. // 输出图片数据以及图片宽高
  99. resolve({ data: base64, width: canvas.width, height: canvas.height });
  100. });
  101. });
  102. };
  103. /* 获取Blob对象 */
  104. Snapshot.prototype.getSnapshotBlob = function (backgroundColor) {
  105. var _this = this;
  106. var svg = this.getSvgRootElement(this.lf);
  107. return new Promise(function (resolve) {
  108. _this.getCanvasData(svg, backgroundColor).then(function (canvas) {
  109. canvas.toBlob(function (blob) {
  110. // 输出图片数据以及图片宽高
  111. resolve({ data: blob, width: canvas.width, height: canvas.height });
  112. }, 'image/png');
  113. });
  114. });
  115. };
  116. Snapshot.prototype.getClassRules = function () {
  117. var rules = '';
  118. if (this.useGlobalRules) {
  119. var styleSheets = document.styleSheets;
  120. for (var i = 0; i < styleSheets.length; i++) {
  121. var sheet = styleSheets[i];
  122. for (var j = 0; j < sheet.cssRules.length; j++) {
  123. rules += sheet.cssRules[j].cssText;
  124. }
  125. }
  126. }
  127. if (this.customCssRules) {
  128. rules += this.customCssRules;
  129. }
  130. return rules;
  131. };
  132. // 获取图片生成中中间产物canvas对象,用户转换为其他需要的格式
  133. Snapshot.prototype.getCanvasData = function (svg, backgroundColor) {
  134. var _this = this;
  135. var copy = svg.cloneNode(true);
  136. var graph = copy.lastChild;
  137. var childLength = graph.childNodes && graph.childNodes.length;
  138. if (childLength) {
  139. for (var i = 0; i < childLength; i++) {
  140. var lfLayer = graph.childNodes[i];
  141. // 只保留包含节点和边的基础图层进行下载,其他图层删除
  142. var layerClassList = lfLayer.classList && Array.from(lfLayer.classList);
  143. if (layerClassList && layerClassList.indexOf('lf-base') < 0) {
  144. graph.removeChild(graph.childNodes[i]);
  145. childLength--;
  146. i--;
  147. }
  148. else {
  149. // 删除锚点
  150. var lfBase = graph.childNodes[i];
  151. lfBase && lfBase.childNodes.forEach(function (item) {
  152. var element = item;
  153. _this.removeAnchor(element.firstChild);
  154. });
  155. }
  156. }
  157. }
  158. // offset值加10,保证图形不会紧贴着下载图片的左边和上边
  159. copy.lastChild.style.transform = "matrix(1, 0, 0, 1, " + (-this.offsetX + 10) + ", " + (-this.offsetY + 10) + ")";
  160. var dpr = window.devicePixelRatio || 1;
  161. var canvas = document.createElement('canvas');
  162. /*
  163. 为了计算真实宽高需要取图的真实dom
  164. 真实dom存在缩放影响其宽高数值
  165. 在得到真实宽高后除以缩放比例即可得到正常宽高
  166. */
  167. var base = this.lf.graphModel.rootEl.querySelector('.lf-base');
  168. var bbox = base.getBoundingClientRect();
  169. var graphModel = this.lf.graphModel;
  170. var transformModel = graphModel.transformModel;
  171. var SCALE_X = transformModel.SCALE_X, SCALE_Y = transformModel.SCALE_Y;
  172. var bboxWidth = Math.ceil(bbox.width / SCALE_X);
  173. var bboxHeight = Math.ceil(bbox.height / SCALE_Y);
  174. // width,height 值加40,保证图形不会紧贴着下载图片的右边和下边
  175. canvas.style.width = bboxWidth + "px";
  176. canvas.style.height = bboxHeight + "px";
  177. canvas.width = bboxWidth * dpr + 80;
  178. canvas.height = bboxHeight * dpr + 80;
  179. var ctx = canvas.getContext('2d');
  180. ctx.clearRect(0, 0, canvas.width, canvas.height);
  181. ctx.scale(dpr, dpr);
  182. // 如果有背景色,设置流程图导出的背景色
  183. if (backgroundColor) {
  184. ctx.fillStyle = backgroundColor;
  185. ctx.fillRect(0, 0, bboxWidth * dpr + 80, bboxHeight * dpr + 80);
  186. }
  187. else {
  188. ctx.clearRect(0, 0, bboxWidth, bboxHeight);
  189. }
  190. var img = new Image();
  191. var style = document.createElement('style');
  192. style.innerHTML = this.getClassRules();
  193. var foreignObject = document.createElement('foreignObject');
  194. foreignObject.appendChild(style);
  195. copy.appendChild(foreignObject);
  196. return new Promise(function (resolve) {
  197. img.onload = function () {
  198. ctx.drawImage(img, 0, 0);
  199. resolve(canvas);
  200. };
  201. /*
  202. 因为svg中存在dom存放在foreignObject元素中
  203. SVG图形转成img对象
  204. todo: 会导致一些清晰度问题这个需要再解决
  205. fixme: XMLSerializer的中的css background url不会下载图片
  206. */
  207. var svg2Img = "data:image/svg+xml;charset=utf-8," + new XMLSerializer().serializeToString(copy);
  208. var imgSrc = svg2Img.replace(/\n/g, '').replace(/\t/g, '').replace(/#/g, '%23');
  209. img.src = imgSrc;
  210. });
  211. };
  212. Snapshot.pluginName = 'snapshot';
  213. return Snapshot;
  214. }());
  215. exports.Snapshot = Snapshot;
  216. exports.default = Snapshot;