html2canvas.js——HTML轉Canvas工具
概述:
將HTML程式碼轉化成Canvas,進而生成圖片
使用場景:
動態生成海報的需求,html2canvas.js就是一款優秀的外掛,它可以輕鬆地幫你將HTML程式碼轉換成Canvas,進而生成可儲存分享的圖片
使用:
佈局
<div id="qianduanwz" ref='teamShare'> <img src="./images/qrcode.jpg" alt="" @load="qrcodeLoad"/>
<p>學習Web前端<br>關注前端微站</p> </div>
<style> #qianduanwz{ width: 900px; height: 383px; text-align: center; background: url("./images/bg.jpg") no-repeat center;} #qianduanwz img{ width: 200px; margin-top: 60px;} #qianduanwz p{ margin: 0; padding-top: 10px; font-size: 20px; color: #fff;} </style>
轉換Canvas並匯出圖片
async creatImage() { const el = this.$refs.teamShare const options = { type: 'dataURL', useCORS: true, // backgroundColor: '#00a560', } this.output = await this.$html2canvas(el, options) 將元素和配置項傳入 },
可能出現的問題及相應解決方案
① 圖片模糊問題
有時候我們會發現,匯出的圖片區域性有些圖片看起來沒有原圖那麼清晰,這其實是因為你使用背景圖片的原因。解決方法也很簡單,就是直接使用<img>
<img>
來替代)。
② 圖片不顯示問題
有時你可能莫名其妙地發現有些圖片並沒有出現在匯出的圖片中,這基本上就是因為圖片素材出現跨域,也就是說圖片所在的域名與你專案所在域名不一致。這個問題的解決方案就是html2canvas
使用時多加以下兩個配置項就好了。
allowTaint: true, useCORS: true
③ PNG圖片不透明問題
有時你可能用到透明的PNG圖片作為背景圖,可是結果最後生成的圖片卻並不透明,這是因為html2canvas
生成的canvas背景顏色預設為白色的緣故,所以匯出的圖片背景顏色當然也是白色。
解決方案也是新增一個配置項就好(事實上經實驗發現只要是非顏色型別的字串都可以)。
backgroundColor: "transparent"
④ 在iOS系統部分瀏覽器中,用<br>
標籤進行文字換行時,文字只顯示第一行的問題
這種現象並不是必現的,但確實存在這樣的問題,這時解決問題的方式也很簡單,就是不用<br>
標籤來換行,而是採用其他塊級標籤元素對需要進行換行的文字分別包裹即可。
例如:
想學習前端,<br>可關注微信公眾號:前端微站可寫成:
<ul> <li>想學習前端,</li> <li>可關注微信公眾號:前端微站</li> </ul>
重點總結
① 生成圖片的HTML儘量使用<img>而不使用背景圖 ② { allowTaint: true, useCORS: true }可解決跨域圖片不顯示問題 ③ { backgroundColor: "transparent" }可解決圖片不透明問題
html2canvas原理:
一種是利用foreignObject,一種是純canvas繪製
1.foreignObject到canvas
步驟:
1.把要截圖的dom克隆一份,過程中把getComputedStyle附上style
2.放到svg的foreignObject中
3.把svg序列化成img的src(SVG直接內聯):
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(new XMLSerializer().serializeToString(svg));
4.ctx.drawImage(img, ....)
2.純canvas
步驟:
1.把要截圖的dom克隆一份,過程中把getComputedStyle附上style
2.把克隆的dom轉成類似VirtualDom的物件
3.遞迴這個物件,根據父子關係、層疊關係來計算出一個renderQueue
4.每個renderQueue Item都是一個虛擬dom物件,根據之前getComputedStyle得到的style資訊,呼叫ctx的各種方法
總結:
效能:如果文字多,節點少,svg foreignObject的方式往往效能更高;文字少,節點多的時候,canvas反而效能更高
準確性:純canvas方式往往更準確的還原dom的表現;svg foreignObject在比較複雜的情況下會出現截圖不準確的問題
綜上所述,建議使用純canvas方式,但是注意要對文字進行限流!