html2canvas节点导出为图片的相关方法总结,如:等待函数、文件流转Blob函数、节点导出为单个图片、多个图片合成一张长图
需要提前安装html2canvas,安装方法:npm install html2canvas
具体方法:
import html2canvas from 'html2canvas';
/**
* 等待几毫秒后执行
* @param {number} ms 等待时间, 单位毫秒
*/
function waitTimeMS(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
}
/**
* 只要函数条件不满足就一直等待, 直到超时
* @param {Function} fun [async] fun要运行的函数, 可以是异步函数
* @param {number} [timeout=3] 超时时间, 单位秒
* @returns {*} 函数计算结果
*/
async function waitFun(fun, timeout = 5) {
let i = 0;
let f = async() => {
return await fun().catch(() => false);
}
let r = await f();
while (!r && i < timeout * 10) {
await waitTimeMS(100);
r = await f();
i = i + 1;
}
return r;
}
function dataURLToBlob(o) {
const t = o.split(","),
n = t[0].match(/:(.*?);/)[1],
i = atob(t[1]);
let s = i.length;
const l = new Uint8Array(s);
for (; s--;) l[s] = i.charCodeAt(s);
return new Blob([l], { type: n });
// return new File([l], fileName, { type: n }); // 文件流
}
// 单个图片
function saveFun() {
let n = "png",
i = "图片名称";
let ele = document.body.querySelector(".background-box");
const y = document.createElement("canvas");
y.style.backgroundColor = getComputedStyle(ele.parentElement, null).backgroundColor;
let width = ele.offsetWidth,
height = ele.offsetHeight;
y.style.width = width;
y.style.height = height;
y.width = width;
y.height = height;
let cxt = y.getContext('2d')
cxt.translate(100, -10000) // 元素下载为图片的开始位置, 默认是cxt.translate(0, 0)
html2canvas(ele, {
tainttest: true,
backgroundColor: y.style.backgroundColor,
scale: 1,
canvas: y,
logging: !0,
width: width,
height: height,
useCORS: !0,
allowTaint: !0,
imageTimeout: 60000,
}).then((canvas) => {
const c = document.body.appendChild(canvas);
c.style.display = "none";
console.log(11, 222, "createImage_html2canvas_2", c.toDataURL(`image/${n}`));
const a = dataURLToBlob(c.toDataURL(`image/${n}`));
document.body.removeChild(c);
const r = document.createElement("a");
r.style.display = "none";
try {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// 兼容IE/Edge
window.navigator.msSaveOrOpenBlob(a, `${i}.${n}`)
} else {
let url = window.URL.createObjectURL(a)
r.setAttribute('href', url)
r.setAttribute('download', `${i}.${n}`)
document.body.appendChild(r)
r.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(r)
}
} catch (h) {}
});
}
// 多个图片合成一张长图 解决画布超过16300px后渲染问题,但是仍需注意 在 60000 * 1000,40000 *1500以内
function mergeImgs(list, cwidth = 500, cheight = 1000, sumHeight = 7800, urlType = 'image/png') {
return new Promise((resolve, reject) => {
const baseList = [];
// 创建 canvas 节点并初始化
const canvas = document.createElement('canvas');
canvas.width = cwidth;
canvas.height = sumHeight;
const context = canvas.getContext('2d');
list.map((item, index) => {
const img = new Image();
img.src = item; // base64,或者图片路径
// 跨域
img.crossOrigin = 'Anonymous';
img.onload = () => {
let canvasHeight = cheight * (index + 1) > sumHeight ? sumHeight - cheight * index : cheight;
context.drawImage(img, 0, cheight * index, cwidth, canvasHeight);
const base64 = canvas.toDataURL(urlType);
baseList.push(base64);
if (baseList[list.length - 1]) {
// 返回新的图片
resolve(baseList[list.length - 1]);
}
};
});
});
}
async function saveBatchFun(cheight = 10000) {
let n = "png",
i = "图片名称";
let ele = document.body.querySelector(".background-box");
const y = document.createElement("canvas");
y.style.backgroundColor = getComputedStyle(ele.parentElement, null).backgroundColor;
let scale = 1; // 图片放大倍数
let width = ele.offsetWidth * scale,
height = ele.offsetHeight * scale;
let nums = Math.ceil(height / cheight)
let arr = []
for (let ns = 0; ns < nums; ns++) {
arr.push(cheight * ns)
}
arr.push(height)
let urlList = []
for (let idx = 0; idx < arr.length - 1; idx++) {
let imgHeight = arr[idx + 1] - arr[idx];
y.style.width = width;
y.style.height = imgHeight;
y.width = width;
y.height = imgHeight;
let cxt = y.getContext('2d')
cxt.translate(0, -arr[idx]) // 元素下载为图片的开始位置, 默认是cxt.translate(0, 0)
html2canvas(ele, {
tainttest: true,
backgroundColor: y.style.backgroundColor,
scale: scale,
canvas: y,
logging: !0,
width: width,
height: imgHeight,
useCORS: !0,
allowTaint: !0,
imageTimeout: 60000,
}).then((canvas) => {
const c = document.body.appendChild(canvas);
c.style.display = "none";
const baseStr = c.toDataURL(`image/${n}`);
document.body.removeChild(c);
urlList.push(baseStr)
});
await waitFun(() => urlList[idx], 30)
}
mergeImgs(urlList, width, cheight, height, `image/${n}`).then((base64) => {
const a = dataURLToBlob(base64);
const r = document.createElement("a");
r.style.display = "none";
try {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// 兼容IE/Edge
window.navigator.msSaveOrOpenBlob(a, `${i}.${n}`)
} else {
let url = window.URL.createObjectURL(a)
r.setAttribute('href', url)
r.setAttribute('download', `${i}.${n}`)
document.body.appendChild(r)
r.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(r)
}
} catch (h) {}
});
}
export default {
dataURLToBlob,
saveFun,
saveBatchFun,
mergeImgs
}
1万+

被折叠的 条评论
为什么被折叠?



