前端小夥伴經常會遇到頁面截圖或者把網頁中指定的區域(某個大div)的內容轉換成png的圖片。這個時候常常會用到html2canvas庫來實現,js真的很強大。
我最近也遇到了一個需求,需要把輸入的文字框裡面的文字轉換成帶有字型樣式的圖片。於是去研究了一下html2canvas。
html2canvas官網是:http://html2canvas.hertzen.com/,當前最新版本是1.0.0-rc.7。
安裝方式有三種,第1種是用npm進行安裝:
npm install --save html2canvas
第二種是用yarn,命令如下:
yarn add html2canvas
第三種是直接下載html2canvas.js或者壓縮版本html2canvas.min.js。然後直接script方式引入到需要使用這個js庫的html檔案中即可。
官網給的案例如下(usage), 首先是html部分,有一個div:
<div id="capture" style="padding: 10px; background: #f5da55">
<h4 style="color: #000; ">Hello world!</h4>
</div>
js部分如下:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
這段程式碼就是把id為capture的div傳給html2canvas,回撥中的canvas是被捕獲的div物件。
如果要把這個div轉換成圖片,則還需要增加如下程式碼:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas);
// 新增程式碼 返回圖片的URL,設定為png格式
var dataUrl = canvas.toDataURL("image/png")
});
上面程式碼中的dataUrl是一個base64編碼的圖片URL地址。
在我的需求中,我需要把這個圖片資源儲存到伺服器中,所以需要在後面發起一個ajax請求(或者post請求)到後端服務,後端介面需要接收這個dataURL,先base64解碼,然後再把解碼後的圖片內容寫入到png格式的檔案中。
大致程式碼如下:
public function saveCustomTextToImage(Request $request) {
$imageDataURL = $request->input('dataUrl');
$encodeImage = explode(",", $imageDataURL)[1];
// 解碼
$decodeImage = base64_decode($encodeImage);
$storePath = "./img/my-pic.png";
// 寫入檔案
file_put_contents($storePath, $decodeImage);
$resArray['success'] = true;
$resArray['url'] = "testme";
return response()->json($resArray);
}
如果是不想傳給後端處理,想直接跳轉瀏覽器下載,那麼之前的js部分的程式碼可以改為:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas);
// 新增程式碼 返回圖片的URL,設定為png格式
var dataUrl = canvas.toDataURL("image/png");
var downloadUrl = dataUrl.replace("image/png","image/octet-stream");//圖片地址
window.location.href = downloadUrl; // 跳轉下載
});
常規玩法說完了,下面說一下常見的坑。
第一個我遇到的就是版本造成的api呼叫的問題,從上面的js程式碼可以看出最新的html2canvas是基於Promise實現的,所以可以用".then"的方式進行鏈式呼叫。而老版本的html2canvas只能用傳統回撥方式來寫,我的同事就是用的0.4.1版本,所以他的寫法和我不一樣,如下所示:
html2canvas([document.getElementById('mydiv')], {
onrendered: function(canvas) {
document.body.appendChild(canvas);
var data = canvas.toDataURL('image/png');
// AJAX call to send `data` to server
}
});
第二個遇到的問題是沒有任何報錯的前提下,生成的圖片是空白的。國內的童鞋們對這個問題往往說是去設定初始化選項,就可以解決帶有滾動條的頁面擷取出空白的問題。眾所紛紜,還有人說要給被選中的div設定寬高才行。
然而我採用這種方法沒有解決問題,Google了很久發現國外的開發真正解決了這個問題。其實還是和版本有關,將最新的版本降會1.0.0rc.0版本就可以了。
希望官方早點解決這個問題,不然強制降版本也不是個事兒啊。