js|jsPlumb使用html2canvas无法识别svg

使用VFD流程设计器图片下载问题 利用html2canvas处理svg生成canvas,之后在利用canvas转成base64进行图片展示
使用html2canvas对svg线条没有显示问题,
实际画出的流程图为
js|jsPlumb使用html2canvas无法识别svg
文章图片

但是点击生成流程图片的时候线条却不见了
js|jsPlumb使用html2canvas无法识别svg
文章图片

【js|jsPlumb使用html2canvas无法识别svg】原因是因为利用html2canvas处理svg成canvas时是异步进行,还没有生成出来就画canvas肯定就没有了呀
解决办法
这个是点击生成图片的方法 VFD流程设计器的图片生成的源码解析

exportFlowPicture () { const that = this; // 获取节点VFD流程编辑器里面画的节点 let $Container = that.$refs.flowArea.$el.children[0] // 获取线条放进数组 let svgElems = $($Container).find('svg[id^="link-"]') let removeArr = []; svgElems.each(function(index, svgElem) { // 创建canvas let linkCanvas = document.createElement('canvas'); // 设置canvas的id,可自行设置 let canvasId = 'linkCanvas-' + ZFSN.getId(); linkCanvas.id = canvasId; removeArr.push(canvasId); // 获取线条转成字符串 let svgContent = svgElem.outerHTML.trim(); // 利用canvg处理svg转png 注意这里canvg的插件是2.0.0版本。其他版本可能不是这样的用法 canvg(linkCanvas, svgContent) //设置线条的位置,保证跟画的流程节点位置一致 if (svgElem.style.position) { linkCanvas.style.position += svgElem.style.position; linkCanvas.style.left += svgElem.style.left; linkCanvas.style.top += svgElem.style.top; } // 把生成的canvas线条放进$Container里 $($Container).append(linkCanvas); }); // 这个方法是生成图片(节点)的位置大小 let canvasSize = that.computeCanvasSize(); let pbd = flowConfig.defaultStyle.photoBlankDistance; let offsetPbd = ZFSN.div(pbd, 2); html2canvas($Container, { width: canvasSize.width + pbd, height: canvasSize.height + pbd, scrollX: -canvasSize.minX + offsetPbd, scrollY: -canvasSize.minY + offsetPbd, logging: false, onclone: function(args) { removeArr.forEach(function(id, index) { //删除前面添加的canvas节点 $('#' + id).remove(); }); } }).then(canvas => { let dataURL = canvas.toDataURL('image/png'); that.flowPicture.url = dataURL; that.flowPicture.modalVisible = true; }); }, computeCanvasSize () { const that = this; //流程画的节点数据 let nodeList = Object.assign([], that.flowData.nodeList), minX = nodeList[0].x, minY = nodeList[0].y, maxX = nodeList[0].x + nodeList[0].width, maxY = nodeList[0].y + nodeList[0].height; nodeList.forEach(function(node, index) { minX = Math.min(minX, node.x); minY = Math.min(minY, node.y); maxX = Math.max(maxX, node.x + node.width); maxY = Math.max(maxY, node.y + node.height); }); let canvasWidth = maxX - minX; let canvasHeight = maxY - minY; return { width: canvasWidth, height: canvasHeight, minX: minX, minY: minY, maxX: maxX, maxY: maxY }; },

下面是对图片线条无法展示使的改进,利用Promise实现
exportFlowPicture () { const that = this; // 获取节点VFD流程编辑器里面画的节点 let $Container = that.$refs.flowArea.$el.children[0] // 获取线条放进数组 let svgElems = $($Container).find('svg[id^="link-"]') let removeArr = []; const callback = [] svgElems.each(function(index, svgElem) { // 创建canvas let linkCanvas = document.createElement('canvas'); // 设置canvas的id,可自行设置 let canvasId = 'linkCanvas-' + ZFSN.getId(); linkCanvas.id = canvasId; removeArr.push(canvasId); // 获取线条转成字符串 let svgContent = svgElem.outerHTML.trim(); //设置线条的位置,保证跟画的流程节点位置一致 if (svgElem.style.position) { linkCanvas.style.position += svgElem.style.position; linkCanvas.style.left += svgElem.style.left; linkCanvas.style.top += svgElem.style.top; } //设置画布大小跟真实线条一样大小 linkCanvas.width = svgElem.width.animVal.value linkCanvas.height= svgElem.height.animVal.value //利用promise实现异步(改动的地方(核心)) let promiseType = new Promise((resole,reject)=>{ // 把这个放进promise就好 canvg(linkCanvas, svgContent) // 把生成的canvas线条放进$Container里 $($Container).append(linkCanvas); resole() }) //把生成的promise放进callback数组里 callback.push(promiseType ) }); // 利用Promise的all方法,当所有的都成功画出来的时候才执行生成总的canvas生成 Promise.all(callback).then(()=>{ // 这个方法是生成图片(节点)的位置大小 let canvasSize = that.computeCanvasSize(); // let pbd = flowConfig.defaultStyle.photoBlankDistance; // let offsetPbd = ZFSN.div(pbd, 2); html2canvas($Container, { //width: canvasSize.width + pbd, //height: canvasSize.height + pbd, //scrollX: -canvasSize.minX + offsetPbd, //scrollY: -canvasSize.minY + offsetPbd, width: canvasSize.width, height: canvasSize.height, scrollX: -canvasSize.minX, scrollY: -canvasSize.minY logging: false, onclone: function(args) { removeArr.forEach(function(id, index) { //删除前面添加的canvas节点 $('#' + id).remove(); }); } }).then(canvas => { let dataURL = canvas.toDataURL('image/png'); that.flowPicture.url = dataURL; that.flowPicture.modalVisible = true; }); }) },

    推荐阅读