使用html2canvas中有很多bug,影响最深刻的就是svg不显示,那怎么解决它呢?
我也是在网上找到一位老哥的最优解!!
逻辑: 先获取到svg节点,把这个svg元素用canvas元素替代,截图完成后删除canvas元素。
附上代码参考,当然我这里的大屏里面可能有很多svg,所以我要遍历svg数组,你们可以不用这样。
下面是我项目导出截图的全部代码 ↓↓↓
handleBUILD() {
this.$nextTick(() => {
//Svgdom数组
let svgNodesToRemove = [];
// 获取到所有的SVG得到一个数组
let svgElements = document.body.querySelectorAll('#content .avue-echart-
progress svg');
console.log(svgElements,'获取到的svg---')
// 遍历这个数组
svgElements.forEach(function(item) {
console.log(item,'svg数据---')
let children = item.childNodes
console.log(children,'svgElements foreach::children')
// 处理 SVG子节点 children 透明度
children.forEach(function(child) {
//解决svg透明度问题
child.style.opacity = 1;
})
//去除空白字符
let svg = item.outerHTML.trim();
// 创建一个 canvas DOM元素
let canvas = document.createElement('canvas');
//设置 canvas 元素的宽高
canvas.width = item.getBoundingClientRect().width;
canvas.height = item.getBoundingClientRect().height;
// 将 SVG转化 成 canvas
canvg(canvas, svg);
//设置生成 canvas 元素的坐标 保证与原SVG坐标保持一致
if (item.style.position) {
canvas.style.position += item.style.position;
canvas.style.left += item.style.left;
canvas.style.top += item.style.top;
}
//添加到 你需要截图的DOM节点中
item.parentNode.appendChild(canvas);
// 删除这个元素
svgNodesToRemove.push(canvas)
item.style.display = "none"
});
html2canvas(document.querySelector(".canvas"), {
useCORS: true,
backgroundColor: null,
allowTaint: true,
}).then((canvas) => {
if(this.contain.nav.length != 0){
//截取所有组件所在的矩形画布
var croppedCanvas = document.createElement('canvas');
var croppedCtx = croppedCanvas.getContext('2d');
let x = this.position.x * this.zoomFactor;
let y = this.position.y * this.zoomFactor;
let width = this.position.width * this.zoomFactor;
let height = this.position.height * this.zoomFactor;
console.log(x,y,width,height,'我是要截取的位置');
let rate = 258/180
if( width/height > rate){
// console.log('宽比高长得多');
let changedHeight,yChange
changedHeight = width/rate
yChange = (changedHeight-height)/2
y = y - yChange
if(y < 0){
y = 0
}else if(y + changedHeight > this.contain.config.height){
y = this.contain.config.height - changedHeight
}
height = changedHeight
}
if( width/height < rate){
// console.log('宽比高短得多');
let changedWidth,xChange
changedWidth = height * rate
xChange = (changedWidth-width)/2
x = x - xChange
if(x < 0){
x = 0
}else if(x + changedWidth > this.contain.config.width){
x = this.contain.config.width - changedWidth
}
width = changedWidth
}
croppedCanvas.width = width * this.zoomFactor;
croppedCanvas.height = height * this.zoomFactor;
croppedCtx.scale(this.zoomFactor, this.zoomFactor);
console.log("x, y, width, height",x, y, width, height);
croppedCtx.drawImage(canvas, x, y, width, height, 0, 0, width, height);
}
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: mime,
});
}
if(this.contain.nav.length != 0){
var file = dataURLtoFile(
croppedCanvas.toDataURL("image/jpeg", 0.92),
new Date().getTime() + ".jpg"
);
}else{
var file = dataURLtoFile(
canvas.toDataURL("image/jpeg", 0.92),
new Date().getTime() + ".jpg"
);
}
// 截取完成后
// 删除 canvas 元素
document.querySelectorAll("#content .avue-echart-progress
canvas").forEach(item => {
item.remove()
})
let svgElements = document.body.querySelectorAll('#content .avue-echart-
progress svg');
console.log(svgElements,'隐藏svgElements后重新获取到的svg');
svgElements.forEach(function(item){
item.style.display = 'inline-block'
})
var formdata = new FormData();
formdata.append("file", file);
console.log("360");
console.log(this.contain);
console.log(this.contain.obj);
axios
.post(this.url + "/upload/img", formdata, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
const data = res.data.data;
const url = data.baseUrl + "/" + data.url;
const formdata = {
backgroundUrl: url,
category: this.$route.query.category,
config: {
component: JSON.stringify(this.contain.nav),
createTime: this.contain.obj.config.createTime,
detail: JSON.stringify(this.contain.config),
id: this.contain.obj.config.id,
updateTime: this.contain.obj.config.updateTime,
version: this.visial.version,
visualId: this.contain.obj.config.id,
},
createTime: this.contain.obj.createTime,
createUser: this.contain.obj.createUser,
// currentVersion: '',
id: this.contain.obj.id,
isDeleted: this.contain.obj.isDeleted,
password: this.contain.obj.password,
status: this.contain.obj.status,
title: this.contain.obj.title,
updateTime: this.contain.obj.updateTime,
};
return new Promise((resolve, reject) => {
console.log("这边有有一个接口请求-------------");
console.log(updateComponent);
updateComponent(formdata).then((res) => {
console.log("接口处理请求成功回来");
console.log(res);
let data = res && res.data;
if (data.code == 401) {
reject();
} else {
resolve();
}
});
});
})
.then(() => {})
.catch(() => {
// this.$message.error('模版例子不能修改')
loading.close();
});
});
});