html2canvas的踩坑之路

html2canvas的踩坑之路

前言

早有耳聞這個html2canvas比較坑,但無奈於產品需求的壓迫,必須實現html轉圖片的功能,自此走上了填坑之路,好在最後的效果還算使人滿意,這纔沒有誤了產品上線週期.css

html2canvas介紹

html2canvas的詳細介紹能夠點擊這裏查看,其實簡單來講就是經過canvasHTML生成的DOM節點繪製到畫布上,再能夠經過本身的需求轉換成圖片.因此官方文檔也說了,最後生成的效果不是100%相同的,這一點你們要有心理準備,不管怎樣,一點點小瑕疵是確定有的。html

兼容性

 

PS:微信瀏覽器使用也是沒有問題的哦

 

使用html2canvas

使用也是十分簡單,官網寫的很清楚戳這裏前端

踩坑過程

生成的圖片裏面爲何缺失微信頭像或其餘圖片?

其實涉及到的就是跨域問題,即使是canvas的畫布中對於圖片的域也是有要求的,那咱們應該怎麼解決呢?node

  1. html2canvas配置項中配置 allowTaint:true 或 useCORS:true(兩者不可共同使用)
  2. img標籤增長 crossOrigin='anonymous'
  3. 圖片服務器配置Access-Control-Allow-Origin 或使用代理

其中第三步是最重要的,不設置則前兩步設置了也無效。git

服務器須要配置Access-Control-Allow-Origin信息,如PHP添加響應頭信息,*通配符表示容許任意域名:github

header("Access-Control-Allow-Origin: *"); 

或者指定域名:web

header("Access-Control-Allow-Origin: www.zhangxinxu.com"); 

但若是不想麻煩後端的人員,那咱們前端怎麼跨域呢? 那就可使用代理插件,如: html2canvas-proxy-nodejs 或者是 superagent,我是使用superagent,貼一下示例代碼:canvas

const request = require('superagent') // 導入 const proxHost = 'https://thirdwx.qlogo.cn' // 指定跨域圖片的地址 app.use('/proxy', function (req, res, next) { let urlPath = req.url console.log('urlPath', urlPath) urlPath = decodeURI(urlPath) if (!urlPath) { console.log('urlPath is null') return next() } console.log('proxy-request: /proxy->' + `${proxHost}${urlPath}`) const reqStream = request.get(`${proxHost}${urlPath}`) reqStream.on('error', function (err) { console.log('error', err) }) console.log('------reqStream----') return reqStream.pipe(res) }) 

那麼最終我在頁面中的圖片的srchttps://thirdwx.qlogo.cn/xxx 要更改成/proxy/xxx 效果圖以下:後端

 

 

2.生成的圖片模糊不清且有鋸齒瑕疵怎麼辦?

大部分找到的結果都是使用設備像素比去操做,但實際使用起來,仍是會有鋸齒。 這個問題苦惱了我好久,而且找了好久的相關資料,總算是功夫不負有心人,讓我找到了解決方案,在github裏有大神已經提供瞭解決方案,能夠點擊這裏,大神在源碼的基礎上增長兩個配置項,scaledpi,推薦使用scale參數。跨域

源碼位置:https://github.com/eKoopmans/html2canvas/tree/develop/dist

let imgHeight = window.document.querySelector('.content').offsetHeight // 獲取DOM高度 let imgWidth = window.document.querySelector('.content').offsetWidth // 獲取DOM寬度 let scale = window.devicePixelRatio // 獲取設備像素比 html2canvas(window.document.querySelector('.content'), { useCORS: true, scale: scale, width: imgWidth, height: imgHeight }).then((canvas) => { window.document.querySelector('.content').remove() let elemImg = `<img src='${canvas.toDataURL('image/png')}' id='canvas-img' style='height: ${imgHeight}px;border-radius: 10px;width:${imgWidth}px'/>` window.document.querySelector('.container').innerHTML = elemImg }) 

最終生成出來的圖片,是清晰而且最接近DOM的圖片

3.生成的圖片中若包含二維碼,微信長按圖片偶現沒法識別?

 

這個問題主要出如今使用單頁面框架(如VUE)的頁面. 感謝  sundaypig提出的解決方案。 很簡單,就是不使用路由切換,使用 window.location.href直接跳轉刷新頁面

 

location.href="www.abc.com/share/xxx" 

PS:這個問題能夠解決全部頁面中偶現二維碼沒法識別的狀況

4.生成的圖片中文字間距較大?

這個暫時沒法完美解決,能夠嘗試用css屬性:letter-spacing來設置字間距

相關文章
相關標籤/搜索