核心是在html2canvas执行前先替换所有图片转换为Blob,这种方式不会出现图片缺失的情况
/** * @description 替换 去全部图片真实地址为blob 渲染 截图 * @param {element} el 截图的dom区域 * @param {function} success 成功 * @param {function} error 错误 */ function getHandle({ el, success, error } = {}) { let imgArr = el.querySelectorAll('img') imgArr = Array.from(imgArr) let i = 0 if (imgArr[0]) { let timer = setInterval(() => { clearInterval(timer) if (imgArr.length !== i) { error && error('超时') } }, 10000); [...imgArr].forEach((dom) => { dom.src = `${dom.src}?${Math.random()}`; getUrlBlob(dom.src, ((blob) => { if (blob !== false) { dom.src = blob } i++ // 校验是否全部替换完毕 if ((imgArr.length) === i) { clearInterval(timer) IsRender.call(this, el, success, error) } })) }) return } IsRender.call(this, el, success, error) }
/** * @description blob转换处理 * @param {string} url 传 url 和 一个回调 * @param {function} callback false 说明已是blob 或者 当前img 无 src * 返回值 转成的blob临时地址(成功) * 原图的img src (转换失败 返回原图) */ const getUrlBlob = (url, callback) => { const str = url.substring(0, 50) // 避免重复加载 if (str.includes('blob:')) { return callback(false) } // 避免img未有src属性的情况,导致未返回 if (!str) { return callback(false) } let canvas = document.createElement("canvas") let ctx = canvas.getContext("2d") let img = new Image img.crossOrigin = 'Anonymous' img.src = url img.onload = function () { canvas.height = img.height canvas.width = img.width ctx.drawImage(img, 0, 0) try { canvas.toBlob((blob) => { callback(URL.createObjectURL(blob)) }) } catch (err) { callback(img.src) console.error('转换失败,使用原图', err) } canvas = null } // img.error = function () { // callback(img.src) // console.error('转换失败,使用原图', img.error) // } }
/** * @description 截图操作 * @param {element} el 截图的dom区域 * @param {function} success 成功 返回完整的base64 * @param {function} error 错误 返回err信息 */ function IsRender(el, success, error) { setTimeout(() => { var width = el.offsetWidth; //获取dom 宽度 var height = el.offsetHeight; //获取dom 高度 var canvas = document.createElement("canvas"); //创建一个canvas节点 // 兼容清晰度 const scale = window.devicePixelRatio; //定义任意放大倍数 支持小数 canvas.width = width * scale; //定义canvas 宽度 * 缩放 canvas.height = height * scale; //定义canvas高度 *缩放 var context = canvas.getContext('2d'); // 去图片锯齿 官网 context.mozImageSmoothingEnabled = false; context.webkitImageSmoothingEnabled = false; context.msImageSmoothingEnabled = false; context.imageSmoothingEnabled = false; // options配置 var opts = { scale: scale, canvas: canvas, logging: false, width, height: height, dpi: 300, useCORS: true, backgroundColor: "transparent", allowTaint: false, }; // 进行截图 html2canvas(el, opts) .then(canvas => { try { const base64 = canvas.toDataURL('image/png'); success && success.call(this, base64) } catch (err) { error && error(err) } }) .catch(err => { error && error(err) }) }, 500) }
// 调用方法 getHandle.call(this, { el: document.querySelector('.card_jt'), // 成功回调 async success(val) { // val就是拿到的 base64 }, error(err) { console.error(err) } })
我没有使用 domtoimage 只使用html2canvas了 目前没有出过问题 抽取了部分 参考地址:https://blog.csdn.net/Mcky_Love/article/details/106241259