使用html2canvas.js
處理瀏覽器截屏時,發現當元素寬度超過某個閾值後會出現超出部分渲染異常現象。html
html2canvas截屏,實質是dom轉canvns,canvas轉圖片。
目標寬度20000+pxcanvas
option
添加foreignObjectRendering: true
,copyDom顯示正常,canvas寬高正常,但右側原異常元素缺失部分文本。option
指定width爲10000,copyDom顯示正常,canvas寬度10000,導出10000寬-圖正常。初步推斷canvas渲染有寬度上限,百度一番仍無定論瀏覽器
首先不是視圖外元素缺失的問題,試了不少都無結果。最後敲定折中方案就是根據寬度計算 拆分出圖。app
/** * @description html轉圖片導出 * @param ele * @param option * @param fileName * @param uuidKey */ export const handleHtml2Down = (ele, option, fileName, uuidKey) => { window.pageYOffset = 0; document.documentElement.scrollTop = 0 document.body.scrollTop = 0 const targetDom = document.querySelector(ele) const copyDom = targetDom.cloneNode(true) copyDom.style.width = targetDom.scrollWidth + 'px' copyDom.style.height = targetDom.scrollHeight + 'px' copyDom.style.position = 'absolute' copyDom.style.top = '0px' copyDom.style.zIndex = '-1' copyDom.style.backgroundColor = 'white' document.body.appendChild(copyDom) html2canvas(copyDom, { height: copyDom.scrollHeight, width: copyDom.scrollWidth, allowTaint: false, useCORS: true, ...option }).then((canvas => { copyDom.parentNode.removeChild(copyDom) canvas.style.width = parseFloat(canvas.style.width) * 0.8 + 'px' canvas.style.height = parseFloat(canvas.style.height) * 0.6 + 'px' let imgURL = canvas.toDataURL('image/png',1.0) const alink = document.createElement("a") alink.href = imgURL let theName = fileName || getUUID(uuidKey) alink.download = `${theName}.png` alink.click() })) }
/** * @description html轉圖片導出【寬度分頁】 * @param ele 目標dom元素 * @param option html2canvas函數執行參數 * @param fileName 導出圖片文件(可不傳) * @param uuidKey uuid前綴字符(可不傳) */ export const handleHtml2Down = async (ele, option, fileName, uuidKey) => { // reset this page scroll window.pageYOffset = 0; document.documentElement.scrollTop = 0 document.body.scrollTop = 0 // targetDom - target 2 img const targetDom = document.querySelector(ele) // copyDom - copy dom from targetDom const copyDom = targetDom.cloneNode(true) // copyWrapper - wrapper contain the copyDom , use for with-overflow const copyWrapper = document.createElement('div') // init the copyDom copyDom.style.width = targetDom.scrollWidth + 'px' copyDom.style.height = targetDom.scrollHeight + 'px' copyDom.style.transform = '' copyDom.style.margin = '0 0' // define the maxWidth:15000(px) const maxW = 15000 // define the val let urls = [], w = targetDom.scrollWidth,index=0 // init the copyWrapper copyWrapper.style.backgroundColor = 'white' copyWrapper.style.width = (w > maxW ? maxW : w) + 'px' copyWrapper.style.height = targetDom.scrollHeight + 'px' // fix the element copyWrapper.style.position = 'fixed' copyWrapper.style.top = '0px' // make sure the copyWrapper is invisible copyWrapper.style.zIndex = '-1' // use for pageControl copyWrapper.style.overflow = 'hidden' // execute dom append copyWrapper.appendChild(copyDom) document.body.appendChild(copyWrapper) // generate canvas from dom in Loop while (w > 0){ await html2canvas(copyWrapper, { height: copyWrapper.scrollHeight, width: (w > maxW ? maxW : w), foreignObjectRendering: true, allowTaint: false, useCORS: true, ...option }).then((canvas => { canvas.style.width = parseFloat(canvas.style.width) * 0.8 + 'px' canvas.style.height = parseFloat(canvas.style.height) * 0.6 + 'px' urls.push(canvas.toDataURL('image/png',1.0)) w = w - maxW index++ copyWrapper.style.width = w copyDom.style.marginLeft = `-${maxW * index}px` })) } // execute dom remove copyDom.parentNode.removeChild(copyDom) console.log(urls) // export urls & execute img download urls.forEach(url=>{ let alink = document.createElement("a") alink.href = url alink.download = `${fileName || getUUID(uuidKey)}.png` alink.click() }) } expory getUUID = (preffix)=> { return preffix + 'i-am-uuid-123'}
thanks 4 read & welcome 4 leaving a message.dom