最近在作的微信 html5 項目有個需求:頁面包含 一張大的背景圖片 + 一個用戶的連接二維碼圖片 拼成一張圖片,讓用戶長按保存的時候,能夠把整個頁面都保存起來,而不是隻保存二維碼。php
1.先後端哪一個實現方法會更高效html
雖然圖片均可以從後臺獲取,可是一來須要 等待二維碼生成->添加到大圖上->轉換成一張圖片->傳輸,是一個同步過程,耗時比較久;二來看到網上的評價,後臺使用的庫生成的圖片偶爾會出錯,修改起來也麻煩。所以決定在前端完成。前端
2.使用 svg 仍是 canvasvue
考慮到移動端對 html5 新特性支持得比較好以及高分辨率屏幕,使用 svg 看起來很適合------若是沒看到前輩的踩坑文章的話,會是這樣的~~html5
根據 https://www.jianshu.com/p/458... 所說,步驟是 html-->svg-->canvas-->img ,問題出在使用跨域圖片的時候:canvas
也便是 iphone 系列都被拒之門外 ...後端
所以決定用 html2canvas 庫,完成 html-->canvas-->img 的轉變。如下是踩坑心得。跨域
圖片模糊微信
此爲想不到的坑,浪費了不少時間在代碼檢查上...app
問題: html2canvas 渲染背景圖片 background-image 會不清晰。
解決方法:使用 Img 標籤。
高分辨率下,文字模糊
此爲預料中的狀況,獲取了設備像素比 window.devicePixelRatio 百分比伸展 canvas 畫布便可......纔怪......
而後發現這是 0.5 版本須要作的操做,1.0 版本的默認參數 scale 已經設置好了,但仍是不太清晰。
最後從同事處獲得啓發,最終解決方法是!!
一概設爲 4 倍!即
html2canvas(ele, { sacle: 4 }).then((canvas) => {});
簡單粗暴...雖然圖片體積所以變大了...
IOS 下,機率性出現大圖繪製不出來的狀況
對於這個需求,本來的操做是在 img 標籤裏的 src 屬性寫上大圖連接,在 activated() 裏生成二維碼再建立新的 img 標籤附到大圖裏(用的 vue)。在 IOS 上,常常出現頁面上只有背景顏色和二維碼的圖片的狀況。
緣由: 大圖還未下載完畢即開始了繪製。
解決方法: 給 img 添加 onload 事件,下載完畢再調用繪製方法。
html 元素的隱藏
由於是要讓用戶長按保存整個頁面,因此用 html2canvas 將全部內容轉成圖片。而其並不能繪製隱藏的內容,所以須要先顯示頁面,在圖片生成後再隱藏。在 vue 裏就是 v-show 的值的變化過程。
問題: 頁面會有閃爍,再顯示圖片
解決方法: 組件直接設爲 v-show = false,html2canvas 添加參數 onclone ,生成一個複製的虛擬組件,設置爲顯示,便可獲取進行繪製,且虛擬組件不會顯示在頁面上。
html2canvas(ele, { onclone(doc) { let e = doc.querySelector('#wrapper'); e.style.display = 'block'; } }).then((canvas) => {});
圖片高度
問題: UI 只給了一張圖片,寬度能夠稍微拉伸,高度在全面屏下會不足以覆蓋整個屏幕,漏出白底;強制設置爲屏幕高度圖片會失真。
解決方法: 讓 UI 幫忙別把圖片底部設計得五光十色,只保留一種顏色。而後將頁面的背景顏色設爲同種顏色便可。
二維碼圖片的位置定位
問題: 如何讓二維碼圖片在不一樣屏幕下都定位到正確的位置。
解決方法: 設爲絕對定位,使用屏幕寬度做爲基準設置 left、top 值。
.qr { width: 32vw; position: absolute; left: 16vw; top: 97vw; }
圖片跨域等
其餘更多相似圖片跨域等問題能夠參考如下兩篇文章: