使用 HTML 實現截圖-html2canvas使用記錄
前言
最近專案需求總是有HTML頁面生成圖片功能,所以就想記錄一下自己在過程中遇到的問題,並加深印象,日後如果忘了也可以回顧。我們專案使用的是html2canvas外掛,還有其他外掛,例如dom-to-image、rasterizehtml,可以根據需求使用。
html2canvas使用問題彙總
專案中引入的是0.5.0-beta4版本的cdn連結,直接呼叫方法html2canvas(dom,options);第一個引數是你要繪製的dom物件,第二個引數是一些繪製的配置引數,個別引數我嘗試了也沒搞清楚具體什麼作用可以自行看html2canvas文件,對於我用到的直接上程式碼:
// 生成圖片 function generateImg() { var shareContent = document.body;// 需要繪製的部分的 (原生)dom 物件 ,注意容器的寬度不要使用百分比,使用固定寬度,避免縮放問題 var width = shareContent.offsetWidth; // 獲取(原生)dom 寬度 var height = shareContent.offsetHeight; var offsetTop = shareContent.offsetTop; //元素距離頂部的偏移量 // var rect = shareContent.getBoundingClientRect(); var canvas = document.createElement('canvas'); //建立canvas 物件 var context = canvas.getContext('2d'); var scaleBy = 3; //畫素密度 (也可以採用自定義縮放比例) canvas.width = width * scaleBy; //這裡 由於繪製的dom 為固定寬度,居中,所以沒有偏移 canvas.height = (height + offsetTop) * scaleBy; // 注意高度問題,由於頂部有個距離所以要加上頂部的距離,解決影像高度偏移問題 canvas.height = height * scaleBy; // context.translate(0, -offsetTop); // 畫布偏移 context.scale(scaleBy, scaleBy); html2canvas(shareContent, { logging: true, // 是否列印日誌,預設false taintTest: true, //檢測每張圖片都已經載入完成 scale: scaleBy, // 新增的scale 引數 canvas: canvas, //自定義 canvas width: width, //dom 原始寬度 height: height, //dom 原始高度 useCORS: true, //允許跨域 onrendered: function(canvas) { // 頁面繪製成功後的回撥 var url = canvas.toDataURL("image/png"); // 生成圖片後的操作 } }); }
圖片模糊解決
- 由於畫素比(DPR = 裝置畫素/CSS畫素)的問題,電腦上截圖看著還行,到手機上就會非常模糊。繪製圖片時可以根據畫素比把圖片放大,使用時在定義圖片的寬度,也可以自定義縮放比。縮放比也不是越大越好,太大了也可能會出問題。計算畫素比的程式碼:
function getPixelRatio(context){ var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return (window.devicePixelRatio || 1) / backingStore; }
- 繪圖時儘量不要使用背景圖片,直接使用img這樣會更清晰
圖片跨域問題
有次頁面中使用了微信頭像,設定了
useCORS: true
不能顯示頭像,設定
allowTaint:true
直接報錯不能使用toDataURL可能無法匯出受汙染的畫布;最後只有找百度了
- 修改Nginx配置檔案,由於我們專案其他地方也用到了,所以不便修改,可以修改的參考:
location ^~ /wechat_image/ { add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always; proxy_pass }
- 把圖片轉換成base64格式並設定CrossOrigin="anonymous",嘗試後有快取的情況下還是不能正常生成圖片,需要在後面拼接一個隨機引數解決快取問題,Android可以了,但ios上還是不行。
-
後來發現直接在微信頭像的img標籤上設定CrossOrigin="anonymous"即
<img class="user-img" th:src="${wxUser.headImgUrl}" alt="" crossOrigin="anonymous" />
,微信頭像的請求頭來就有access-control-allow-origin: *,Android和ios上都可以了,如果你之前嘗試過其他方法,可能需要清下快取,不然Android會誤導你不能正常顯示。 - 最近又發現一個html2canvas的options裡配置proxy為跨域的url。
生成圖片替換頁面時閃現問題
前面幾次生成圖片,都沒有出現這個問題,最近一次出現了替換時頁面一閃,以為是不是圖片太大了,我將兩個活動的圖片儲存對比並不是,具體我還是沒搞清楚,不過透過先在dom中寫一個空的img標籤然後生成的src替換給img,判斷圖片載入完成後再將繪製的dom隱藏掉解決了這個問題。
css樣式超出顯示省略號消失
html2canvas不支援css樣式生成省略號,百度找到了解決方法,透過js判斷超過父盒子高度時用省略號替換
$(".info_text_box").each(function () { var divH = $(this).height(); var $p = $("p", $(this)).eq(0); while ($p.outerHeight() > divH) { $p.html($p.html().replace(/(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/, "...")); }; });
引入web字型時字型還沒有顯示就生成圖片
window.onload=function(){}
是等頁面資源載入完畢再執行,但是在ios中並不支援,後來發現當字型大小大於300px時不同字型的寬度差別很大,就透過定時器判斷字型大小來判斷字型是否載入成功,但最總因為字型檔案載入太慢,就放棄了使用特殊字型
// 透過判斷字型內容寬度判斷字型載入完成 function fn_fontWatch(fontFamily, cb) { function fn_gen_span_with_font(font) { var span=document.createElement('span'); span.style.cssText = "display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:" + font; span.innerHTML = 'BESbswy'; document.body.append(span); return span; }; var span_default = fn_gen_span_with_font('serif'); var span_default_width = span_default.offsetWidth; document.body.removeChild(span_default); var span_font = fn_gen_span_with_font(fontFamily + ',serif'); var fn_check_loop = function() { if(span_default_width !== span_font.offsetWidth){ document.body.removeChild(span_font); cb(); } else { window.setTimeout(fn_check_loop,500); } }; fn_check_loop(); };
其他問題
- 一次活動需要判斷進入頁面次序,html2canvas是透過遍歷dom繪製圖片的,當生成圖片時除了js都會重新執行一次,導致類似重新整理頁面記錄次序,最後次序透過ajax請求獲取解決了問題;
-
html2canvas只會擷取頁面中可見的內容,設定了
display: none
、visibility:hidden
的元素是擷取不到的 - 生成圖片時文字有些許變化,比如安卓的數字1就變化特別明顯,而且文字的位置有點下移,原因我沒找到,影響不大,目前我也沒解決;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2649899/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Vue專案中使用html2canvas生成頁面截圖VueHTMLCanvas
- html2canvas實現瀏覽器截圖的原理(包含原始碼分析的通用方法)HTMLCanvas瀏覽器原始碼
- uni-app 中使用 html2canvas 生成圖片APPHTMLCanvas
- gmssl實踐截圖記錄
- html2canvas-實現頁面截圖HTMLCanvas
- 記錄--前端如何截圖前端
- jspdf + html2canvas 實現html轉pdf (提高解析度版本)JSHTMLCanvas
- html2canvas 如何生成高清圖片HTMLCanvas
- 直播軟體原始碼,在vue中使用html2canvas在前端生成圖片原始碼VueHTMLCanvas前端
- 使用html2canvas將頁面轉成圖,用canvas2image下載HTMLCanvas
- 使用 HTML5 Canvas 實現使用者自定義裁剪圖片HTMLCanvas
- html2canvas生成圖片顯示不全HTMLCanvas
- 在vue專案中基於html2canvas實現網頁儲存為圖片VueHTMLCanvas網頁
- html2canvas擷取圖片並下載HTMLCanvas
- js實現視訊截圖,視訊批量截圖,canvas實現JSCanvas
- Python網頁截圖/螢幕截圖/截長圖如何實現?Python網頁
- html2canvas:將html的dom變成圖片,並儲存HTMLCanvas
- vue 前端實現pdf下載.npm install html2canvas jspdf --saveVue前端NPMHTMLCanvasJS
- Linux上使用Ksnip截圖Linux
- 前端使用html5、ffmpeg實現錄屏攝像等功能前端HTML
- canvas實現截圖功能Canvas
- Layman 使用ffmpeg-php擴充套件庫實現視訊截圖(預設圖)PHP套件
- html背景圖的使用HTML
- 掌握Snagit 2023:輕鬆實現螢幕錄製與截圖Git
- Zwibbler—前端Canvas繪圖工具使用記錄前端Canvas繪圖
- 使用 HTML5 Canvas 實現圓形圖片裁剪並上傳HTMLCanvas
- 使用chromedriver抓取網頁截圖Chrome網頁
- java使用phantomjs進行截圖JavaJS
- Selenium IDE 如何實現截圖IDE
- 原生JS實現影片截圖JS
- C#實現截圖功能C#
- selenium實現螢幕截圖
- Android長截圖的實現Android
- Html2canvas——圖片空白的幾種排查解決方案HTMLCanvas
- 使用 HTML5 Canvas 實現簽名功能HTMLCanvas
- 使用Python 實現 PDF 到 HTML 的轉換PythonHTML
- Paged.js能使用HTML實現精美PDFJSHTML
- html2canvas的踩坑之路HTMLCanvas