JS中實現網頁截圖

前端頁面中可使用JS將整個網頁或一部分區域截取成圖片並導出。html

今天剛作了一次這個功能,和你們分享一下經驗。前端

使用html2canvas將dom轉換成canvas

網頁截圖的第一步,就是將dom轉換圖片。目前比較好用的處理方式是先將dom轉換成canvas,再從canvas中導出圖片。git

可使用html2canvas這個庫來實現dom轉換成canvas。github

https://github.com/niklasvh/h...canvas

示例代碼:瀏覽器

html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas)
});

將canvas導出成圖片

canvas展現的時候,自己就有保存爲圖片的功能。app

若是須要的話,也能夠在JS中手動操控。dom

canvas 有兩個API能夠用來導出圖片,分別是 toDataURL 和 toBlobasync

https://developer.mozilla.org...this

https://developer.mozilla.org...

toDataURL能夠把canvas導出成圖片的data url,toBlob 則是轉換成Blob對象,Blob對象能夠保存成文件。

若是要在新窗口中展現圖片等,使用toDataURL導出的 data url就能夠了,而要直接導出成文件的話,使用toBlob更好一些。

調用 canvas.toBlob(),如今咱們有了一個Blob對象,下一步是保存Blob到文件中。

保存Blob爲文件

Canvas.toBlob 的文檔 https://developer.mozilla.org... 中有提到如何保存Blob到文件,不過使用起來略爲複雜。我推薦使用 filesaver 來解決這個問題。參見 https://github.com/eligrey/Fi...

Filesaver 支持保存 canvas 到文件,代碼以下:

import { saveAs } from 'file-saver/FileSaver';
canvas.toBlob(function(blob) {
    saveAs(blob, "pretty image.png");
});

調用 saveAs 以後,瀏覽器就會執行下載的動做。根據瀏覽器的設置,可能會直接下載,或彈出保存對話框。

至此,對網頁中的一部分進行截圖並保存成文件就完成了。

圖片調優

導出的圖片基本上會保持原有的樣式,只有一小部分不支持。參見 https://html2canvas.hertzen.c...

可是若是截取的範圍比較大,那麼導出的圖片有可能會出現模糊的狀況。有多是文字模糊,也有多是圖片模糊等。這個時候就須要對圖片進行調優

圖片調優指的是在 html 導出至 canvas的這個階段調優,調優方法是修改 html2canvas的參數。

html2canvas(element, options);

調優主要有兩個方向:

  1. 對於高分屏,好比Retina,有可能會須要調高 scale 參數。它的默認值是 window.devicePixelRatio,通常是1,我修改爲了1.2,感受效果會好一點
  2. 若是截圖範圍比較大,可能會出現文字模糊的狀況。這個時候能夠用 windowWidth 和 windowHeight 指定渲染時用的窗口寬度和高度。將寬度調小能夠下降模糊程度。

還有一些其它選項,參見 https://html2canvas.hertzen.c...

最後,附上參考代碼:

import { saveAs } from 'file-saver/FileSaver'
import html2canvas from 'html2canvas'
 
 
handleDownloadCapture = async () => {
  const reportDom = document.querySelector('.report-container')
  const actualWidth = reportDom.offsetWidth || 1000
  const actualHeight = reportDom.offsetHeight || 2000
  const factor = 0.6
  const canvas = await html2canvas(reportDom, {scale: 1.2, windowWidth: actualWidth * factor, windowHeight: actualHeight * factor})
  const filename = this.getExportFilename()
  canvas.toBlob(blob => saveAs(blob, filename))
}
相關文章
相關標籤/搜索