最近接到一個需求,需要在小程序中實現頁面截圖,我一開始的考慮是使用官方提供的擴展組件wxml-to-canvas,但是實際體驗下來效果很糟糕,首先它並不能截取實際的頁面,而是必須傳入wxml和wxss;然後他能支持的效果也很少,並不能滿足需求中稍微複雜的效果。最終我決定用web-view加載的網頁中使用html2canvas來實現功能。
實際代碼
網頁部分我用了vue,首先需要安裝html2canvas
npm install html2canvas
頁面中引入
import html2canvas from 'html2canvas';
需要截圖的dom節點上添加ref屬性
<div ref="page">
截圖代碼
...
document.body.scrollTop = 0;
// 將頁面滾動至頂部後再開始截圖,才能保證截圖的完整
html2canvas(this.$refs.page, {
allowTaint: false,
useCORS: true,
width: document.body.scrollWidth,
height: document.body.scrollHeight
// 實際體驗中發現最好設置寬高為頁面的寬高才能獲得完整的截圖
}).then(canvas => {
this.savedPic = canvas.toDataURL('images/png')
// 用於在頁面中展示的截圖完成的網址
...
// 以下代碼為模擬a標籤的點擊直接下載截圖
// 但是這部分代碼在移動端網頁和小程序中並不會生效
let a = document.createElement('a'),
blob = this.dataURLToBlob(canvas.toDataURL('images/png'));
a.setAttribute('href', URL.createObjectURL(blob));
a.setAttribute('download', 'pic.png');
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(blob);
document.body.removeChild(a);
});
...
兼容性
網頁畢竟不是原生小程序,還是會存在一些兼容性問題,比如網頁中不能使用小程序的wx.saveImageToPhotosAlbum直接保存生成好的截圖。移動端和微信中也不支持模擬a標籤的點擊來下載圖片,最終只能通過展示生成的截圖並提示用户長按圖片來實現保存圖片的功能,用户體驗會差點,但是考慮到截圖效果比wxml-to-canvas好太多了,還是可以接受的。
最後説一下html2canvas的支持度,目前實際用下來發現不支持的樣式為陰影和偽元素,其他基本上都支持。網頁中的圖片必須為本地圖片或者支持跨域的網絡圖片。用到圖片的地方建議直接使用img標籤,而不是背景圖片,img標籤展示的圖片清晰度遠遠高於背景圖片。