jsPlumb使用html2canvas无法识别svg

使用VFD流程设计器图片下载问题

利用html2canvas处理svg生成canvas,之后在利用canvas转成base64进行图片展示
使用html2canvas对svg线条没有显示问题,
实际画出的流程图为
jsPlumb使用html2canvas无法识别svg_第1张图片
但是点击生成流程图片的时候线条却不见了
jsPlumb使用html2canvas无法识别svg_第2张图片

原因是因为利用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;
			});
		})
	},

你可能感兴趣的:(js,vfd,jsPlumb)