UNPKG

@logicflow/extension

Version:
750 lines (749 loc) 39.9 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Snapshot = void 0; var utils_1 = require("./utils"); /** * 快照插件,生成视图 */ var Snapshot = /** @class */ (function () { function Snapshot(_a) { var lf = _a.lf; var _this = this; this.lf = lf; this.customCssRules = ''; this.useGlobalRules = true; // TODO: 设置fileType为gif但是下载下来的还是png // TODO: 完善静默模式不允许添加、操作元素能力 /* 导出画布快照 */ lf.getSnapshot = function (fileName, toImageOptions) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getSnapshot(fileName, toImageOptions) /* 获取Blob对象 */ ]; case 1: return [2 /*return*/, _a.sent() /* 获取Blob对象 */ ]; } }); }); }; /* 获取Blob对象 */ lf.getSnapshotBlob = function (backgroundColor, // 兼容老的使用方式 fileType, toImageOptions) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getSnapshotBlob(backgroundColor, fileType, toImageOptions) /* 获取Base64对象 */ ]; case 1: return [2 /*return*/, _a.sent() /* 获取Base64对象 */ ]; } }); }); }; /* 获取Base64对象 */ lf.getSnapshotBase64 = function (backgroundColor, // 兼容老的使用方式 fileType, toImageOptions) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getSnapshotBase64(backgroundColor, fileType, toImageOptions)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; } /** * 获取svgRoot对象dom: 画布元素(不包含grid背景) * @param lf * @returns */ Snapshot.prototype.getSvgRootElement = function (lf) { var svgRootElement = lf.container.querySelector('.lf-canvas-overlay'); return svgRootElement; }; /** * 通过 imgUrl 下载图片 * @param imgUrl */ Snapshot.prototype.triggerDownload = function (imgUrl) { var evt = new MouseEvent('click', { view: document.defaultView, bubbles: false, cancelable: true, }); var a = document.createElement('a'); a.setAttribute('download', this.fileName); a.setAttribute('href', imgUrl); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); }; /** * 删除锚点 * @param element */ 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--; } } }; /** * 删除旋转按钮 * @param element */ Snapshot.prototype.removeRotateControl = 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-rotate-control') > -1) { element.removeChild(element.childNodes[i]); childLength--; i--; } } }; /** * 将图片转换为base64格式 * @param url - 图片URL * @returns Promise<string> - base64字符串 */ Snapshot.prototype.convertImageToBase64 = function (url) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve, reject) { var img = new Image(); img.crossOrigin = 'anonymous'; // 处理跨域问题 img.onload = function () { var canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext('2d'); ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(img, 0, 0); var base64 = canvas.toDataURL('image/png'); resolve(base64); }; img.onerror = function () { reject(new Error("Failed to load image: ".concat(url))); }; img.src = url; })]; }); }); }; /** * 检查URL是否为相对路径 * @param url - 要检查的URL * @returns boolean - 是否为相对路径 */ Snapshot.prototype.isRelativePath = function (url) { return (!url.startsWith('data:') && !url.startsWith('http://') && !url.startsWith('https://') && !url.startsWith('//')); }; /** * 处理SVG中的图片元素 * @param element - SVG元素 */ Snapshot.prototype.processImages = function (element) { return __awaiter(this, void 0, void 0, function () { var images, i, image, href, base64, error_1, foreignObjects, i, foreignObject, images_1, j, image, src, base64, error_2; return __generator(this, function (_a) { switch (_a.label) { case 0: images = element.getElementsByTagName('image'); i = 0; _a.label = 1; case 1: if (!(i < images.length)) return [3 /*break*/, 6]; image = images[i]; href = image.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || image.getAttribute('href'); if (!(href && this.isRelativePath(href))) return [3 /*break*/, 5]; _a.label = 2; case 2: _a.trys.push([2, 4, , 5]); return [4 /*yield*/, this.convertImageToBase64(href)]; case 3: base64 = _a.sent(); image.setAttributeNS('http://www.w3.org/1999/xlink', 'href', base64); image.setAttribute('href', base64); return [3 /*break*/, 5]; case 4: error_1 = _a.sent(); console.warn("Failed to convert image to base64: ".concat(href), error_1); return [3 /*break*/, 5]; case 5: i++; return [3 /*break*/, 1]; case 6: foreignObjects = element.getElementsByTagName('foreignObject'); i = 0; _a.label = 7; case 7: if (!(i < foreignObjects.length)) return [3 /*break*/, 14]; foreignObject = foreignObjects[i]; images_1 = foreignObject.getElementsByTagName('img'); j = 0; _a.label = 8; case 8: if (!(j < images_1.length)) return [3 /*break*/, 13]; image = images_1[j]; src = image.getAttribute('src'); if (!(src && this.isRelativePath(src))) return [3 /*break*/, 12]; _a.label = 9; case 9: _a.trys.push([9, 11, , 12]); return [4 /*yield*/, this.convertImageToBase64(src)]; case 10: base64 = _a.sent(); image.setAttribute('src', base64); return [3 /*break*/, 12]; case 11: error_2 = _a.sent(); console.warn("Failed to convert image to base64: ".concat(src), error_2); return [3 /*break*/, 12]; case 12: j++; return [3 /*break*/, 8]; case 13: i++; return [3 /*break*/, 7]; case 14: return [2 /*return*/]; } }); }); }; /** * 克隆并处理画布节点 * @param svg * @returns */ Snapshot.prototype.cloneSvg = function (svg_1) { return __awaiter(this, arguments, void 0, function (svg, addStyle) { var copy, graph, childLength, i, lfLayer, layerClassList, lfBase, style, foreignObject; var _this = this; var _a; if (addStyle === void 0) { addStyle = true; } return __generator(this, function (_b) { switch (_b.label) { case 0: copy = svg.cloneNode(true); graph = copy.lastChild; childLength = (_a = graph === null || graph === void 0 ? void 0 : graph.childNodes) === null || _a === void 0 ? void 0 : _a.length; if (childLength) { for (i = 0; i < childLength; i++) { lfLayer = graph === null || graph === void 0 ? void 0 : graph.childNodes[i]; layerClassList = lfLayer.classList && Array.from(lfLayer.classList); if (layerClassList && layerClassList.indexOf('lf-base') < 0) { graph === null || graph === void 0 ? void 0 : graph.removeChild(graph.childNodes[i]); childLength--; i--; } else { lfBase = graph === null || graph === void 0 ? void 0 : graph.childNodes[i]; lfBase && lfBase.childNodes.forEach(function (item) { var element = item; _this.removeAnchor(element.firstChild); _this.removeRotateControl(element.firstChild); }); } } } // 处理图片路径 return [4 /*yield*/, this.processImages(copy) // 设置css样式 ]; case 1: // 处理图片路径 _b.sent(); // 设置css样式 if (addStyle) { style = document.createElement('style'); style.innerHTML = this.getClassRules(); foreignObject = document.createElement('foreignObject'); foreignObject.appendChild(style); copy.appendChild(foreignObject); } return [2 /*return*/, copy]; } }); }); }; /** * 获取脚本 css 样式 * @returns */ 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]; // 这里是为了过滤掉不同源 css 脚本,防止报错终止导出 try { for (var j = 0; j < sheet.cssRules.length; j++) { rules += sheet.cssRules[j].cssText; } } catch (error) { console.log('CSS scripts from different sources have been filtered out'); } } } if (this.customCssRules) { rules += this.customCssRules; } return rules; }; /** * 根据浏览器类型获取Canvas尺寸限制 * @returns 包含最大主维度和次维度的对象 */ Snapshot.prototype.getCanvasDimensionsByBrowser = function () { var userAgent = navigator.userAgent; // 默认值 var maxCanvasDimension = 65535; var otherMaxCanvasDimension = 4096; if (userAgent.indexOf('Chrome') !== -1 || userAgent.indexOf('Edge') !== -1) { maxCanvasDimension = 65535; otherMaxCanvasDimension = 4096; } else if (userAgent.indexOf('Firefox') !== -1) { maxCanvasDimension = 32767; otherMaxCanvasDimension = 3814; } return { maxCanvasDimension: maxCanvasDimension, otherMaxCanvasDimension: otherMaxCanvasDimension }; }; /** * 将 svg 转化为 canvas * @param svg - svg 元素 * @param toImageOptions - 图像选项 * @returns Promise<canvas> - 返回 canvas 对象 */ Snapshot.prototype.getCanvasData = function (svg, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var width, height, backgroundColor, _a, padding, copy, dpr, base, bbox, layoutCanvas, layout, offsetX, offsetY, graphModel, transformModel, SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y, safetyFactor, actualWidth, actualHeight, bboxWidth, bboxHeight, canvas, safetyMargin, _b, maxCanvasDimension, otherMaxCanvasDimension, MAX_CANVAS_DIMENSION, OTHER_MAX_CANVAS_DIMENSION, targetWidth, targetHeight, scaleWidth, scaleHeight, ctx, img, style, foreignObject; return __generator(this, function (_c) { switch (_c.label) { case 0: width = toImageOptions.width, height = toImageOptions.height, backgroundColor = toImageOptions.backgroundColor, _a = toImageOptions.padding, padding = _a === void 0 ? 40 : _a; return [4 /*yield*/, this.cloneSvg(svg, false)]; case 1: copy = _c.sent(); dpr = window.devicePixelRatio || 1; if (dpr < 1) { // https://github.com/didi/LogicFlow/issues/1222 // canvas.width = bboxWidth * dpr配合ctx.scale(dpr, dpr)是为了解决绘制模糊 // 比如dpr=2,先让canvas.width放大到等同于屏幕的物理像素宽高,然后自适应缩放适配canvas.style.width // 由于所有元素都缩放了一半,因此需要ctx.scale(dpr, dpr)放大2倍整体绘制的内容 // 当用户缩放浏览器时,window.devicePixelRatio会随着变小 // 当window.devicePixelRatio变小到一定程度,会导致canvas.width<canvas.style.width // 由于导出图片的svg的大小是canvas.style.width+canvas.style.height // 因此会导致导出的svg图片无法完整绘制到canvas(因为canvas.width小于svg的宽) // 从而导致canvas导出图片是缺失的svg // 而dpr>=1就能保证canvas.width>=canvas.style.width // 当dpr小于1的时候,我们强制转化为1,并不会产生绘制模糊等问题 dpr = 1; } base = this.lf.graphModel.rootEl.querySelector('.lf-base'); bbox = base.getBoundingClientRect(); layoutCanvas = this.lf.container.querySelector('.lf-canvas-overlay'); layout = layoutCanvas.getBoundingClientRect(); offsetX = bbox.x - layout.x; offsetY = bbox.y - layout.y; graphModel = this.lf.graphModel; transformModel = graphModel.transformModel; SCALE_X = transformModel.SCALE_X, SCALE_Y = transformModel.SCALE_Y, TRANSLATE_X = transformModel.TRANSLATE_X, TRANSLATE_Y = transformModel.TRANSLATE_Y; safetyFactor = 1.1 // 安全系数,增加20%的空间 ; actualWidth = (bbox.width / SCALE_X) * safetyFactor; actualHeight = (bbox.height / SCALE_Y) * safetyFactor; bboxWidth = Math.ceil(actualWidth); bboxHeight = Math.ceil(actualHeight); canvas = document.createElement('canvas'); canvas.style.width = "".concat(bboxWidth, "px"); canvas.style.height = "".concat(bboxHeight, "px"); safetyMargin = 40 // 额外的安全边距 ; _b = this.getCanvasDimensionsByBrowser(), maxCanvasDimension = _b.maxCanvasDimension, otherMaxCanvasDimension = _b.otherMaxCanvasDimension; MAX_CANVAS_DIMENSION = maxCanvasDimension; OTHER_MAX_CANVAS_DIMENSION = otherMaxCanvasDimension; targetWidth = bboxWidth * dpr + padding * 2 + safetyMargin; targetHeight = bboxHeight * dpr + padding * 2 + safetyMargin; scaleWidth = 1 //宽 缩放 ; scaleHeight = 1 //高 缩放 ; // 对宽和高分别进行缩放,如chrome,矩形单边最大宽度不超过65535,如宽超过65535,那么高不能超过4096,否则像素会超,也会显示不出。 if (targetWidth > MAX_CANVAS_DIMENSION && targetHeight > OTHER_MAX_CANVAS_DIMENSION) { scaleWidth = MAX_CANVAS_DIMENSION / targetWidth; scaleHeight = OTHER_MAX_CANVAS_DIMENSION / targetHeight; } else if (targetWidth > OTHER_MAX_CANVAS_DIMENSION && targetHeight > MAX_CANVAS_DIMENSION) { scaleWidth = OTHER_MAX_CANVAS_DIMENSION / targetWidth; scaleHeight = MAX_CANVAS_DIMENSION / targetHeight; } else if (targetWidth > MAX_CANVAS_DIMENSION && targetHeight < OTHER_MAX_CANVAS_DIMENSION) { scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetWidth; } else if (targetWidth < OTHER_MAX_CANVAS_DIMENSION && targetHeight > MAX_CANVAS_DIMENSION) { scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetHeight; } if (scaleWidth < 1 || scaleHeight < 1) { targetWidth = Math.floor(targetWidth * scaleWidth); targetHeight = Math.floor(targetHeight * scaleHeight); } // 将导出区域移动到左上角,canvas 绘制的时候是从左上角开始绘制的 // 在transform矩阵中加入padding值,确保左侧元素不会被截断 // 对这个矩阵进行缩放,否则会导致截断 ; copy.lastChild.style.transform = "matrix(".concat(scaleWidth, ", 0, 0, ").concat(scaleHeight, ", ").concat((-offsetX + TRANSLATE_X) * (1 / SCALE_X) * scaleWidth + padding / dpr, ", ").concat((-offsetY + TRANSLATE_Y) * (1 / SCALE_Y) * scaleHeight + padding / dpr, ")"); canvas.width = targetWidth; canvas.height = targetHeight; ctx = canvas.getContext('2d'); if (ctx) { // 清空canvas ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.scale(dpr * scaleWidth, dpr * scaleHeight); // 如果有背景色,设置流程图导出的背景色 if (backgroundColor) { ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, canvas.width, canvas.height); } else { ctx.clearRect(0, 0, canvas.width, canvas.height); } } img = new Image(); style = document.createElement('style'); style.innerHTML = this.getClassRules(); foreignObject = document.createElement('foreignObject'); foreignObject.appendChild(style); copy.appendChild(foreignObject); return [2 /*return*/, new Promise(function (resolve) { img.onload = function () { var isFirefox = navigator.userAgent.indexOf('Firefox') > -1; try { if (isFirefox) { createImageBitmap(img, { resizeWidth: width && height ? (0, utils_1.copyCanvas)(canvas, width, height).width : canvas.width, resizeHeight: width && height ? (0, utils_1.copyCanvas)(canvas, width, height).height : canvas.height, }).then(function (imageBitmap) { // 由于在transform矩阵中已经考虑了padding,这里不再需要额外的padding偏移 ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(imageBitmap, 0, 0); resolve(width && height ? (0, utils_1.copyCanvas)(canvas, width, height) : canvas); }); } else { // 由于在transform矩阵中已经考虑了padding,这里不再需要额外的padding偏移 ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(img, 0, 0); resolve(width && height ? (0, utils_1.copyCanvas)(canvas, width, height) : canvas); } } catch (e) { // 由于在transform矩阵中已经考虑了padding,这里不再需要额外的padding偏移 ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(img, 0, 0); resolve(width && height ? (0, utils_1.copyCanvas)(canvas, width, height) : canvas); } }; /* 因为svg中存在dom存放在foreignObject元素中 svg dom => Base64编码字符串 挂载到img上 fixme: XMLSerializer的中的css background url不会下载图片 */ var svg2Img = "data:image/svg+xml;charset=utf-8,".concat(new XMLSerializer().serializeToString(copy)); var imgSrc = svg2Img .replace(/\n/g, '') .replace(/\t/g, '') .replace(/#/g, '%23'); img.src = imgSrc; })]; } }); }); }; /** * 封装导出前的通用处理逻辑:局部渲染模式处理、静默模式处理 * @param callback 实际执行的导出操作回调函数 * @param toImageOptions 导出图片选项 * @returns 返回回调函数的执行结果 */ Snapshot.prototype.withExportPreparation = function (callback, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var curPartial, _a, partial, editConfig, result; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: curPartial = this.lf.graphModel.getPartial(); _a = (toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}).partial, partial = _a === void 0 ? curPartial : _a; editConfig = this.lf.getEditConfig(); // 开启静默模式:如果元素多的话 避免用户交互 感知卡顿 this.lf.updateEditConfig({ isSilentMode: true, stopScrollGraph: true, stopMoveGraph: true, }); _b.label = 1; case 1: _b.trys.push([1, , 6, 7]); if (!(curPartial !== partial)) return [3 /*break*/, 3]; this.lf.graphModel.setPartial(partial); return [4 /*yield*/, new Promise(function (resolve) { _this.lf.graphModel.eventCenter.once('graph:updated', function () { return __awaiter(_this, void 0, void 0, function () { var callbackResult; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, callback() // 恢复原来渲染模式 ]; case 1: callbackResult = _a.sent(); // 恢复原来渲染模式 this.lf.graphModel.setPartial(curPartial); resolve(callbackResult); return [2 /*return*/]; } }); }); }); })]; case 2: // 等待画布更新完成 result = _b.sent(); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, callback()]; case 4: // 直接执行回调 result = _b.sent(); _b.label = 5; case 5: return [3 /*break*/, 7]; case 6: // 恢复原来配置 this.lf.updateEditConfig(editConfig); return [7 /*endfinally*/]; case 7: return [2 /*return*/, result]; } }); }); }; /** * 导出画布:导出前的处理画布工作,局部渲染模式处理、静默模式处理 * @param fileName * @param toImageOptions */ Snapshot.prototype.getSnapshot = function (fileName, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.withExportPreparation(function () { return _this.snapshot(fileName, toImageOptions); }, toImageOptions)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * 下载图片 * @param fileName * @param toImageOptions */ Snapshot.prototype.snapshot = function (fileName, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var _a, _b, fileType, quality, svg, copy, svgString, blob, url; var _this = this; return __generator(this, function (_c) { switch (_c.label) { case 0: _a = toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}, _b = _a.fileType, fileType = _b === void 0 ? 'png' : _b, quality = _a.quality; this.fileName = "".concat(fileName !== null && fileName !== void 0 ? fileName : "logic-flow.".concat(Date.now()), ".").concat(fileType); svg = this.getSvgRootElement(this.lf); return [4 /*yield*/, (0, utils_1.updateImageSource)(svg)]; case 1: _c.sent(); if (!(fileType === 'svg')) return [3 /*break*/, 3]; return [4 /*yield*/, this.cloneSvg(svg)]; case 2: copy = _c.sent(); svgString = new XMLSerializer().serializeToString(copy); blob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8', }); url = URL.createObjectURL(blob); this.triggerDownload(url); return [3 /*break*/, 4]; case 3: this.getCanvasData(svg, toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}).then(function (canvas) { // canvas元素 => base64 url image/octet-stream: 确保所有浏览器都能正常下载 var imgUrl = canvas .toDataURL("image/".concat(fileType), quality) .replace("image/".concat(fileType), 'image/octet-stream'); _this.triggerDownload(imgUrl); }); _c.label = 4; case 4: return [2 /*return*/]; } }); }); }; /** * 获取Blob对象 * @param fileType * @param toImageOptions * @returns */ Snapshot.prototype.getSnapshotBlob = function (backgroundColor, fileType, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.withExportPreparation(function () { return _this.snapshotBlob(toImageOptions, fileType, backgroundColor); }, toImageOptions)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; // 内部方法处理blob转换 Snapshot.prototype.snapshotBlob = function (toImageOptions, baseFileType, backgroundColor) { return __awaiter(this, void 0, void 0, function () { var _a, fileType, svg; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = (toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}).fileType, fileType = _a === void 0 ? baseFileType : _a; svg = this.getSvgRootElement(this.lf); return [4 /*yield*/, (0, utils_1.updateImageSource)(svg)]; case 1: _b.sent(); return [2 /*return*/, new Promise(function (resolve) { _this.getCanvasData(svg, __assign({ backgroundColor: backgroundColor }, (toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}))).then(function (canvas) { canvas.toBlob(function (blob) { // 输出图片数据以及图片宽高 resolve({ data: blob, width: canvas.width, height: canvas.height, }); }, "image/".concat(fileType !== null && fileType !== void 0 ? fileType : 'png')); }); })]; } }); }); }; /** * 获取base64对象 * @param backgroundColor * @param fileType * @param toImageOptions * @returns */ Snapshot.prototype.getSnapshotBase64 = function (backgroundColor, fileType, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: console.log('getSnapshotBase64---------------', backgroundColor, fileType, toImageOptions); return [4 /*yield*/, this.withExportPreparation(function () { return _this._getSnapshotBase64(backgroundColor, fileType, toImageOptions); }, toImageOptions)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; // 内部方法处理实际的base64转换 Snapshot.prototype._getSnapshotBase64 = function (backgroundColor, baseFileType, toImageOptions) { return __awaiter(this, void 0, void 0, function () { var _a, fileType, svg; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = (toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}).fileType, fileType = _a === void 0 ? baseFileType : _a; svg = this.getSvgRootElement(this.lf); return [4 /*yield*/, (0, utils_1.updateImageSource)(svg)]; case 1: _b.sent(); return [2 /*return*/, new Promise(function (resolve) { _this.getCanvasData(svg, __assign({ backgroundColor: backgroundColor }, (toImageOptions !== null && toImageOptions !== void 0 ? toImageOptions : {}))).then(function (canvas) { var base64 = canvas.toDataURL("image/".concat(fileType !== null && fileType !== void 0 ? fileType : 'png')); resolve({ data: base64, width: canvas.width, height: canvas.height, }); }); })]; } }); }); }; Snapshot.pluginName = 'snapshot'; return Snapshot; }()); exports.Snapshot = Snapshot; exports.default = Snapshot;