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)
        }
    })

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM