1. 程式人生 > >Html2canvas - 項目中遇到的那些坑點匯總(更新中...)

Html2canvas - 項目中遇到的那些坑點匯總(更新中...)

false type all pen sub string ogg cau func

水平居中的元素截圖後向左跑偏

  明明是水平居中的代碼,截圖出來的會偏左,結構是左圖片右文字,有時候是圖片自己跑到最左邊,有時候是整體偏左一點點
  這個問題也不是經常遇到,場景是父div元素text-align=center;內部兩個子元素設為display:inline-block的模式。然後畫圖就會出現左邊的div偏左靠或直接在左邊的情況。
  問題未解決,出現時也沒研究因為啥,等有時間的時候就不出現了。。。

靠背景圖露臉的dom們會有底線
  截圖時,如果有一個dom元素是用背景圖填充的,裏邊沒有任何結構,那麽截圖出來的底部會有一條和背景圖底部一致的一條線
  有時候靠拉伸dom元素的高度解決了,有時候又不行。

the operation is insecure
  canvas.toDataURL 報錯 the operation is insecure
  canvas.toDataURL(type, encoderOptions);語法
  配置如:canvas.toDataURL("image/png", 0.7);
  參數type指定圖片類型,如果指定的類型不被支持則以默認值image/png替代;
  encoderOptions(第二個參數)可以為image/jpeg或image/webp類型的圖片設置圖片質量,取值0-1,超出則以默認值0.92替代。


html2canvas在微信中base64碼為空


  在微信中或者可以說在移動端瀏覽器裏,canvas.toDataURL不成功。canvas.toDataURL(type) 得到空的 data:;
  折騰了半天。。。
  同事說如果base64碼的長度有個限制,忘了超過多少就不行了,後來我嘗試把放大四倍改成放大兩倍,問題竟然解決了!!
  不要笑話我放大了四倍,為了清晰哈哈哈。但是改成兩倍後和四倍比也沒差。反倒是挖了個坑自己填了半天!

不可見的元素截圖後是空白
  沒法截圖看不見的,比如opacity為0的東西,或者visibility為hidden的,更別說display:none了。都不行,
  截出來的一樣是白色的,可想而知,畢竟沒截上東西當然就是白色了。


  解決方法是讓canvas部分隱藏到後邊。最終選擇方案,層級設為-1,上一層的把他蓋住。

  前提是上一層要又一個可以設置的背景色,能把他蓋住不被世人看到

html2canvas結合微信裏的長按存圖功能
  先用html2canvas拿到一個html轉為canvas的base64碼,

  再在頁面建立一個img元素,src=base64碼,插入dom中,蓋在所有元素的最上方(或者需要用戶長按保存的地方),opacity設置為0。

  然後用戶就長按保存,存下來的就是事先準備好的覆蓋在那裏的那個不可見得透明圖。
  事實證明,圖片透明不可見覆蓋在頁面上邊,微信裏是可以存圖的。

  而很多市面上的h5,結果頁和最後存下來的圖不一樣的,估計都是這麽搞得,畢竟看不見代碼

html2canvas+jsbridge同時存兩張圖
  html2canvas和jsbridge的存圖功能協作時,會觸發同時存兩張圖的現象。

  第一次存圖很完美,如果不關掉頁面第二次存圖,就會存兩張,以後也會存兩張。只有第一次使用存圖是好的。
  就是jsbridge調了兩次,第二次自動調起的原因目前猜測是html2canvas引起的, 

  因為一層層定位,只有在html2canvas返回base64碼後會有問題。具體原因暫沒有找到。
  最後解決方法是:配合sessionStore,第一次截完圖後,將圖片地址存入sessionstore,

  之後判斷,sessionstore裏有base64碼就不用html2canvas生成碼了,直接取數據存圖,

html2canvas觸發時重新加載頁面的所有靜態資源(除js)
  css和img圖像,這一點是在和Wdatapicker組合使用時發現的問題。

  本來沒什麽,愛加載幾次加載幾次,但是datapicker的樣式是寫在iframe裏的,重新加載dom還把人家的樣式給丟了。這事兒就大了
  大歸大,問題根本原因沒解決,還是治標不治本的在每次觸發html2canvas截圖保存pdf的時候,重新給datapicker繪制樣式,就是這麽任性!

html2canvas 截圖跨域

  https://blog.csdn.net/yaosir1993/article/details/76474080

以下截取部分作者思想,主要是用於解決了本次問題的地方:
  useCORS:true 這個參數很重要,沒有配置的話,依舊是不能解決問題的;
  根據現有的解決方案大致有兩種:
  (1).在跨域的服務器上設置header設置為允許跨域請求。 在服務器上設置header設置允許跨域請求(采用nginx做靜態資源映射)
  (2).借助代理腳本獲得外域圖片的 base64 編碼後的字符串
  
  關於跨域和清晰度解決方案的講解地址:https://lengxing.github.io/
  設置header,實現跨域訪問http://blog.csdn.net/enter89/article/details/51205752

領導建議:

  域名反向代理,

  圖片允許跨域使用:Access-Control-Allow-Origin: *;

html2canvas+qrcode 截二維碼被白底遮擋

  html2canvas執行截圖-因為頁面中有一處是qrcode執行的地址轉二維碼,每次截圖後二維碼都截不下來,那一塊就是一個白塊
  後來把二維碼img的外部div結構背景色設置半透明,二維碼就截出來了,原來是div的背景色蓋住了img
  原理還是搞不明白,明明層級都設置了還不起作用,竟然被自己的爹給蓋住也是醉了。
  二維碼處之所以為白色是因為外部結構的白色背景給覆蓋了,最後是盛放二維碼img的外部div結構不設置背景色就解決了


html2canvas截圖時,背景音樂在IOS11下會重復播放
解決方法見博文:https://blog.csdn.net/lerayZhang/article/details/79207468

技術分享圖片
1 import html2canvas from ‘html2canvas/dist/html2canvas.min‘;
2 export { html2canvas };
html2canvas 技術分享圖片
 1 /*
 2  * @Author: guojufeng@ 
 3  * @Date: 2017-12-25 15:18:12
 4  * html2image模塊
 5  * @param {object=} parameter 參數配置
 6  * @param {string} parameter.targetEleId: 目標元素id--要截屏的區域
 7  * @param {string} parameter.imgType: 要保留下來的圖片格式:png|jpg|bmp|gif
 8  * @param {Boolean} toDown: 是否執行下載功能,不執行則返回圖片base64地址
 9 */
10 import { html2canvas } from ‘./html2canvas‘;
11 //解決ios11下,重復加載背景音樂的bug
12 const iosMusic = (idName)=>{  
13   let agent = navigator.userAgent.toLowerCase(),//判斷手機系統  
14       version;  
15   // console.log(agent);  
16   if(agent.indexOf("like mac os x") > 0){  
17       //ios  
18       let regStr_saf = /os [\d._]*/gi,  
19           verinfo = agent.match(regStr_saf) ;  
20       version = (verinfo+"").replace(/[^0-9|_.]/ig,"").replace(/_/ig,".");//獲取具體的系統版本號  
21       let typeNum = version.split(".")[0];//獲取系統版本號的第一位數字  
22       // console.log(version);
23       // console.log(typeNum);
24       if(typeNum >= 11){  
25         $(idName).removeAttr("autoplay");  
26       }  
27   }  
28 }
29 export let html2img = (parameter,toDown = true)=> {
30   const promise = new Promise((resolve,reject)=>{
31     if(parameter.imgType == ‘png‘ || parameter.imgType == ‘jpg‘ || parameter.imgType == ‘bmp‘ || parameter.imgType == ‘gif‘){
32       let type = parameter.imgType;
33       /**
34       * 獲取mimeType
35       * @param  {String} type the old mime-type
36       * @return the new mime-type
37       */
38       const _fixType = function(type) {
39           type = type.toLowerCase().replace(/jpg/i, ‘jpeg‘);
40           let r = type.match(/png|jpeg|bmp|gif/)[0];
41           return ‘image/‘ + r;
42       };
43       /*圖片跨域及截圖模糊處理*/
44       let shareContent = parameter.targetEleId,//需要截圖的包裹的(原生的)DOM 對象
45           width = shareContent.clientWidth,//shareContent.offsetWidth; //獲取dom 寬度
46           height = shareContent.clientHeight,//shareContent.offsetHeight; //獲取dom 高度
47           canvas = document.createElement("canvas"), //創建一個canvas節點
48           scale = 2; //定義任意放大倍數 支持小數
49       canvas.width = width * scale; //定義canvas 寬度 * 縮放
50       canvas.height = height * scale; //定義canvas高度 *縮放
51       canvas.style.width = shareContent.clientWidth * scale + "px";
52       canvas.style.height = shareContent.clientHeight * scale + "px";
53       canvas.getContext("2d").scale(scale, scale); //獲取context,設置scale 
54       let opts = {
55           scale: scale, // 添加的scale 參數
56           canvas: canvas, //自定義 canvas
57           logging: false, //日誌開關,便於查看html2canvas的內部執行流程
58           width: width, //dom 原始寬度
59           height: height,
60           useCORS: true // 【重要】開啟跨域配置
61       };
62       /* html2canvas截圖時,背景音樂重復播放問題。 */
63       iosMusic(parameter.musicId);
64       /* html2canvas 截圖 */
65       html2canvas(shareContent,opts).then(function(canvas) {
66         let imgData = canvas.toDataURL(‘image/png‘);
67         // console.log(canvas.toDataURL(‘image/png‘).substring(0,20));
68         // console.log(canvas.toDataURL(‘image/png‘).length);
69         // let save_link = document.createElementNS(‘http://www.w3.org/1999/xhtml‘, ‘a‘);
70         // save_link.href = imgData.replace(_fixType(type),‘image/octet-stream‘);
71         if(toDown){
72           let link_title = parameter.titleStr ? parameter.titleStr + ‘_‘ : ‘easypass_‘;
73           save_link.download = link_title + (new Date()).getTime() + ‘.‘ + type;
74           let event = document.createEvent(‘MouseEvents‘);
75           event.initMouseEvent(‘click‘, true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
76           save_link.dispatchEvent(event);
77         }else{
78           resolve(imgData);
79         }
80       }); 
81     }else{
82       reject(new Error(‘parameter.imgType 類型錯誤,應該是字符串,且只有四種類型值。‘));
83     }
84   });
85   return promise;
86 }
html2img

具體配置根據自己需要進行調整。

最後調用:

 1 html2img({
 2     targetEleId: oCanvas,
 3     imgType: ‘png‘,
 4     titleStr: ‘測測你是哪種汽車人‘,
 5     musicId: ‘#musicAudio‘
 6   },false)
 7   .then((imgUrl)=>{
 8     let oImg = document.createElement(‘img‘);
 9     oImg.id = ‘oImg‘;
10     oImg.className = ‘o-img‘;
11     oImg.src= imgUrl;
12     document.body.appendChild(oImg);
13   });

2018-06-25 17:54:43 (持續更新中...)

Html2canvas - 項目中遇到的那些坑點匯總(更新中...)