项目中要实现下载dom的快照,或者生产截图,可以使用html2canvas 这个库,
npm install --save html2canvas
封装成类可以在任何项目中使用
import html2canvas from "html2canvas";
class ImageSnapshot {
constructor(dom, url) {
this.dom = dom;
this.url = url;
this.loadingMessage = null; // 用于存储加载提示信息的 DOM 元素
}
handleDown() {
this.showLoadingMessage(); // 显示加载提示信息
// 转换传递过来的图片为 base64
this.convertImageToBase64(this.url)
.then((base64) => {
// 找到所有 img 元素并设置 src 为 base64
let images = this.dom.querySelectorAll("img");
images.forEach((img) => {
img.src = base64;
});
return html2canvas(this.dom, {
useCORS: true,
backgroundColor: "#002F4F", // 设置背景颜色为 #002F4F
logging: true,
onclone: (clonedDoc) => {
// 处理克隆文档中的 SVG 元素或其他可能的问题
let svgElements = clonedDoc.querySelectorAll("svg");
svgElements.forEach((svg) => {
let transform = svg.getAttribute("transform");
if (transform) {
svg.setAttribute(
"transform",
transform.replace(/rotate\(NaN\)/g, "")
);
}
});
},
});
})
.then((canvas) => {
// 创建链接元素
const link = document.createElement("a");
// 将 canvas 转换为 Blob 对象
canvas.toBlob((blob) => {
if (blob) {
// 设置链接地址为生成的 Blob 对象 URL
link.href = URL.createObjectURL(blob);
// 设置下载的文件名和类型
link.download = `snapshot_${Date.now().toString()}.png`;
// 模拟点击下载链接
link.dispatchEvent(new MouseEvent("click"));
this.hideLoadingMessage(); // 隐藏加载提示信息
} else {
console.error("Canvas to Blob conversion failed.");
this.hideLoadingMessage(); // 隐藏加载提示信息
}
}, "image/png");
})
.catch((error) => {
console.error("html2canvas error:", error);
this.handleImageError(); // 调用错误处理方法
this.hideLoadingMessage(); // 隐藏加载提示信息
});
}
convertImageToBase64(url) {
return new Promise((resolve, reject) => {
let img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
resolve(canvas.toDataURL("image/png"));
};
img.onerror = reject;
img.src = url;
});
}
handleImageError() {
// 创建一个提示信息元素
let errorMessage = document.createElement("div");
errorMessage.textContent = "图片加载失败,请检查网络连接或图片地址。";
errorMessage.style.color = "red";
errorMessage.style.position = "absolute";
errorMessage.style.top = "10px";
errorMessage.style.left = "10px";
errorMessage.style.backgroundColor = "white";
errorMessage.style.padding = "5px";
errorMessage.style.border = "1px solid red";
// 将提示信息元素添加到 dom 中
this.dom.appendChild(errorMessage);
// 使用 html2canvas 捕获不含图片的 dom
html2canvas(this.dom, {
useCORS: true,
backgroundColor: "#002F4F", // 设置背景颜色为 #002F4F
logging: true,
})
.then((canvas) => {
const link = document.createElement("a");
canvas.toBlob((blob) => {
if (blob) {
link.href = URL.createObjectURL(blob);
link.download = `snapshot_${Date.now().toString()}.png`;
link.dispatchEvent(new MouseEvent("click"));
this.hideLoadingMessage(); // 隐藏加载提示信息
} else {
console.error("Canvas to Blob conversion failed.");
this.hideLoadingMessage(); // 隐藏加载提示信息
}
}, "image/png");
})
.catch((error) => {
console.error("html2canvas error during fallback:", error);
this.hideLoadingMessage(); // 隐藏加载提示信息
});
}
showLoadingMessage() {
// 创建一个加载提示信息元素
this.loadingMessage = document.createElement("div");
this.loadingMessage.textContent = "正在生成快照,请稍候...";
this.loadingMessage.style.color = "blue";
this.loadingMessage.style.position = "absolute";
this.loadingMessage.style.top = "10px";
this.loadingMessage.style.left = "10px";
this.loadingMessage.style.backgroundColor = "white";
this.loadingMessage.style.padding = "5px";
this.loadingMessage.style.border = "1px solid blue";
// 将加载提示信息元素添加到 dom 中
this.dom.appendChild(this.loadingMessage);
}
hideLoadingMessage() {
// 移除加载提示信息元素
if (this.loadingMessage) {
this.dom.removeChild(this.loadingMessage);
this.loadingMessage = null;
}
}
}
// 导出 ImageSnapshot 类
export default ImageSnapshot;
// 使用示例
// const domElement = document.querySelector(".dialogWrap");
// const imageUrl = 'https://example.com/image.png';
// const snapshot = new ImageSnapshot(domElement, imageUrl);
// snapshot.handleDown();