工具介绍
- html2canvas1.3.2
- 百度地图3.0
- Canvg4.0.1
功能介绍
将弹出框里面的内容导出成图片格式保存在本地。弹出框中使用了百度地图,并且绘制了坐标点和线段链接功能。
html2canvas导出图片遇到问题
百度地图点坐标定位的原生图片跨域问题,线段链接(svg)导出失效
解决问题
百度地图原生图片跨域问题
方法1
- html2canvas原生配置应该可以解决跨域问题,就和vue.config.js差不多,会的教我一下,感谢。
方法2
- 不使用原生的定位图标图片,使用本地的
let marker = new BMap.Marker(point, {
icon: new BMap.Icon(
require("../../../assets/weizhia.png"),//图片大小30px*30px
new BMap.Size(30, 30),
{
anchor: new BMap.Size(15, 30),
}
),
});
this.map.addOverlay(marker);
百度地图线段链接(svg)导出失效
方法逻辑解释
- 使用Canvg把百度地图中的线段(svg)转为canvas
- 将canvas定位到svg的位置,删除svg
//target弹出框元素
svgToCanvas(target) {
const svgElems = Array.from(target.getElementsByTagName("svg"));
svgElems.forEach(async (el) => {
const parentNode = el.parentNode;
const canvas = document.createElement("canvas");
canvas.style.zIndex = "0";
if (el.tagName === "svg") {
//这一行注意!网上搜的一般都不带.querySelector("path")
//但是百度地图的svg(线段)就需要(不是百度地图的svg我也不清楚,谁试过能说说最好)。
const svg = el.querySelector("path").outerHTML.trim();
const { width, height } = el.getBoundingClientRect();
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
//CSS颜色,渐变,或图案,默认设置是#000000(黑色)
// ctx.fillStyle = "red";
//x-横坐标 y-纵坐标 w-宽 h-高
// ctx.fillRect(0, 0, 200, 200);
//工具方法
const v = await Canvg.from(ctx, svg);
v.start();
if (el.style.position) {
canvas.style.position = 999;
// canvas.style.position = el.style.position;
// canvas.style.left = el.style.left;
// canvas.style.top = el.style.top;
}
}
parentNode.appendChild(canvas);
parentNode.removeChild(el);
});
return target;
},
- html2canvas导出
saveImage(divText, imgText) {
let canvasID = this.$refs[divText];
let that = this;
let a = document.createElement("a");
this.svgToCanvas(canvasID);
setTimeout(() => {
html2canvas(canvasID, {
useCORS: true,
onclone: () => {
// this.svgToCanvas(canvasID);
},
}).then((canvas) => {
let dom = document.body.appendChild(canvas);
dom.style.display = "none";
a.style.display = "none";
document.body.removeChild(dom);
let blob = that.dataURLToBlob(dom.toDataURL("image/png"));
a.setAttribute("href", URL.createObjectURL(blob));
//这块是保存图片操作 可以设置保存的图片的信息
a.setAttribute("download", imgText + ".png");
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(blob);
document.body.removeChild(a);
});
}, 0);
},
//转成blob?这一步有啥用我不太清楚,维护时候就带这部分内容的。
dataURLToBlob(dataurl) {
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
提醒
- 导出时候必须要让Canvg(svg->canvas)走完才能导出,所以使用了setTimeout包裹住
- 不要在html2canvas中的onclone方法运行(svg->canvas)的方法。没用!按照html2canvas的官方文档我感觉应该可以的!这样就不需要使用setTimeout包裹住了啊。为啥?!(凑合用吧)
- 一般需要配着jsPDf导出为pdf文档的,需要裸跑 this.svgToCanvas(canvasID)方法