最近在做活動頁榜晦,有個(gè) H5 頁面生成海報(bào)圖片的功能冠蒋,本來想著用后端做,但需要把前端代碼傳到后端乾胶,后端在解析生成圖片抖剿,返回前端,但這么雖然可以识窿,但太麻煩了斩郎,并且耗時(shí),雖然感覺減輕了前端的工作量喻频,但后端工作量很大缩宜。讓后就去網(wǎng)上搜了一下 DOM 轉(zhuǎn) png,嘗試找一找有沒有這樣的庫甥温,就找到了 html2canvas 這個(gè)庫锻煌。
記錄一下用法,以及遇到的坑及解決方式:
- 下載 npm i html2canvas 或 yarn add html2canvas
- 生成圖片
productionImage() {
// 手動創(chuàng)建一個(gè) canvas 標(biāo)簽
const canvas = document.createElement("canvas")
// 獲取父標(biāo)簽姻蚓,意思是這個(gè)標(biāo)簽內(nèi)的 DOM 元素生成圖片
let canvasBox = this.$refs.imageWrapper
// 獲取父級的寬高
const width = parseInt(window.getComputedStyle(canvasBox).width)
const height = parseInt(window.getComputedStyle(canvasBox).height)
// 寬高 * 2 并放大 2 倍 是為了防止圖片模糊
canvas.width = width * 2
canvas.height = height * 2
canvas.style.width = width + 'px'
canvas.style.height = height + 'px'
const context = canvas.getContext("2d");
context.scale(2, 2);
const options = {
backgroundColor: null,
canvas: canvas,
useCORS: true
}
html2canvas(canvasBox, options).then((canvas) => {
// toDataURL 圖片格式轉(zhuǎn)成 base64
let dataURL = canvas.toDataURL("image/png")
this.downloadImage(dataURL)
})
},
downloadImage(url) {
// 創(chuàng)建一個(gè) img 標(biāo)簽炼幔,把圖片插入到 DOM 中
// 這里使用 img 是因?yàn)樵诳蛻舳酥校荒苤苯酉螺d史简,要調(diào)用原生的方法
const parents = this.$refs.selfReport
const createImg = document.createElement('img')
const insertEle = this.$refs.insetElement
parents.insertBefore(createImg,parents.childNodes[0])
createImg.setAttribute('src', url)
// 如果是在網(wǎng)頁中可以直接創(chuàng)建一個(gè) a 標(biāo)簽直接下載
let a = document.createElement('a')
a.href = url
a.download = '文件名'
a.click()
},
說一下遇到的問題
圖片的跨域乃秀,如果生成的 DOM 元素中有包含圖片,域名跟本地訪問域名不一致的話圆兵,會出現(xiàn)跨域跺讯。
添加 useCORS: true , 但我發(fā)現(xiàn)還可能會有跨域問題,還有兩種解決方式是: 直接后端返回的圖片轉(zhuǎn)成 base64 或者 把圖片放到統(tǒng)一域名下畫出來的圖片有白色的邊框
解決方式: 設(shè)置 backgroundColor: null 就可以了
把 H5 頁面生成二維碼殉农,可以看我的另一個(gè)小文章 鏈接
其實(shí)很多場景下都是二維碼+圖片的方式刀脏,二者的順序是先生成二維碼,放到 DOM 中超凳,在利用 html2canvas 把 DOM 生成圖片愈污。
最近發(fā)現(xiàn)一個(gè)小問題
我在網(wǎng)頁中使用 html2canvas 時(shí)耀态,即使使用的二倍圖,將 canvas 放大兩倍或者三倍之后暂雹,出現(xiàn)在效果還是模糊的一倍圖首装,最后發(fā)現(xiàn)它好像和電腦屏幕的分辨率有關(guān)系,在自己 Mac 上和在擴(kuò)展屏幕上生成的圖片清晰度差了很多杭跪,解決方式:
就是在options 中寫死 scale 的倍數(shù)仙逻。