html2canvas 截图不完整 图片缺失问题

核心是在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: 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

posted @ 2021-06-15 11:15  啾啾啾啾一口  阅读(5390)  评论(1编辑  收藏  举报