1. 程式人生 > 實用技巧 >html2canvas.js——HTML轉Canvas工具

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方式,但是注意要對文字進行限流!

參考文章:https://juejin.im/entry/58b91491570c35006c4f7fdf