前段時間,產品和運營整了個非常變態的需求,要求將一個活動頁面輸出為圖片,然后用戶進行分享
開始以為是用戶自己手動截圖分享,沒想到后來不是,細思極恐,感嘆需求之變態。
從網上找了N個方案,最后確定使用 html2canvas 基本可實現(http://html2canvas.hertzen.com/),下面開始踩坑。
html2canvas 的原理在於利用封裝的js將html的顯示輸出轉化為canvas,根據頁面的復雜度,可能會遇到一些問題。
截圖模糊
解決原理就是講canvas畫布的width和height放大兩倍
后來了解canvas的時候,其寫法不同於css的寬高設置,因為css里的只是展示畫布顯示的大小,不像canvas是真正的圖畫分辨率的大小
1 /*圖片跨域及截圖模糊處理*/ 2 let shareContent = domObj,//需要截圖的包裹的(原生的)DOM 對象 3 width = shareContent.clientWidth,//shareContent.offsetWidth; //獲取dom 寬度 4 height = shareContent.clientHeight,//shareContent.offsetHeight; //獲取dom 高度 5 canvas = document.createElement("canvas"), //創建一個canvas節點 6 scale = 2; //定義任意放大倍數 支持小數 7 canvas.width = width * scale; //定義canvas 寬度 * 縮放 8 canvas.height = height * scale; //定義canvas高度 *縮放 9 canvas.style.width = shareContent.clientWidth * scale + "px"; 10 canvas.style.height = shareContent.clientHeight * scale + "px"; 11 canvas.getContext("2d").scale(scale, scale); //獲取context,設置scale 12 let opts = { 13 scale: scale, // 添加的scale 參數 14 canvas: canvas, //自定義 canvas 15 logging: false, //日志開關,便於查看html2canvas的內部執行流程 16 width: width, //dom 原始寬度 17 height: height, 18 useCORS: true // 【重要】開啟跨域配置 19 }; 20 html2canvas(shareContent,opts).then()
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:;
引發這個問題的操作可能有2中,1、canvas被污染,2、生成圖片過大,base64碼有長度限制
不可見的元素截圖后是空白
沒法截圖看不見的,比如opacity為0的東西,或者visibility為hidden的,更別說display:none了。
解決方法是讓canvas部分隱藏到后邊。最終選擇方案,層級設為-1,上一層的把他蓋住。前提是上一層要又一個可以設置的背景色,能把他蓋住不被世人看到
html2canvas結合微信里的長按存圖功能
先用html2canvas拿到一個html轉為canvas的base64碼,
再在頁面建立一個img元素,src=base64碼,插入dom中,蓋在所有元素的最上方(或者需要用戶長按保存的地方),opacity設置為0。
然后用戶就長按保存,存下來的就是事先准備好的覆蓋在那里的那個不可見得透明圖。
事實證明,圖片透明不可見覆蓋在頁面上邊,微信里是可以存圖的。
html2canvas 截圖跨域
圖片跨域時報錯現象
這個時候你要去看圖片的header頭有沒有這個:
看圖片本身是否允許跨域訪問:
上邊這個是一個允許的圖片。下邊這個不允許,就截取不到。
主要是用於解決了本次問題的地方:useCORS:true 這個參數很重要,沒有配置的話,依舊是不能解決問題的;
根據現有的解決方案大致有兩種:
(1).在跨域的服務器上設置header設置為允許跨域請求。 在服務器上設置header設置允許跨域請求
(2).借助代理腳本獲得外域圖片的 base64 編碼后的字符串,本文未采用。
作者:舊舊的 <393210556@qq.com> 解決問題的方式,就是解決它一次