基於 SVG ForeignObject 的網頁截圖組件

Simple-ForeignObject github.com/newbieYoung… 是基於 SVG ForeignObject 的網頁截圖組件,部分實現參考了 dom-to-image github.com/tsayen/dom-…javascript

聊到網頁截圖你們首先就會想到目前比較流行的兩個庫:css

html2canvas原理是先對頁面進行解析,而後根據解析的結果繪製到 Canvas 中;這種方式因爲只須要瀏覽器支持 Canvas 所以兼容性較好,能夠知足大部分場景的要求;html

可是因爲是解析再繪製的實現方式,解析過程當中的偏差、CSS 和 Canvas 的渲染差別以及瀏覽器的支持程度都會致使截圖的結果和網頁中實際看起來有一些差別;當你對截圖結果的類似度要求很高時 html2canvas 就有點差強人意了。java

在其官方網站上也說明了這一點:git

dom-to-image雖然說在 Github 上 star 數不少,可是因爲缺少維護以及做者的一些實現並不合理,致使其問題不少;github

耳聽爲虛,眼見爲實!如下將給出一些簡單的示例比較來進行說明。web

示例比較

示例一

.demo1 {
  font-size: 20px;
  color: #000;
  background-color: gray;
}
複製代碼
<p class="demo1">demo1</p>
複製代碼

截圖結果爲:npm

從結果中能夠很明顯的看出 dom-to-image 截圖模糊,html2canvas 截圖文字偏下,simple-foreignobject 的截圖和瀏覽器渲染的 DOM 元素幾乎如出一轍。canvas

示例二

.demo2 {
  font-size: 20px;
  color: #000;
  background-color: pink;
  margin-top: 10px;
}
複製代碼
<p class="demo2">demo2</p>
複製代碼

截圖結果爲:瀏覽器

示例二隻是在示例一的基礎上增長了 margin ,html2canvas 依舊是一樣的問題,可是 dom-to-image 除了模糊以外還出現了部分被裁切的問題,simple-foreignobject 正常。

示例三

.demo3 {
  font-size: 20px;
  color: #000;
  background-color: lightblue;
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
}
複製代碼
<p class="demo3">demo3</p>
複製代碼

截圖結果爲:

示例三採用絕對定位,dom-to-image 截圖空白,html2canvas 仍是老問題,simple-foreignobject 正常。

示例四

.demo4 {
  font-size: 20px;
  background-image: -webkit-linear-gradient(top, blue, red);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  font-weight: 700;
  border: 1px solid #000;
  font-family: TTTGB-Medium;
}
複製代碼
<p class="demo4">demo4</p>
複製代碼

截圖結果爲:

示例四是字體結合文字漸變,dom-to-image 文字消失且漸變色變成了背景,html2canvas 雖然文字沒有消失可是漸變色也變成了背景,simple-foreignobject 正常。

示例五

.demo5 {
  font-size: 20px;
  color: blue;
  background-color: lightgreen;
}

.demo5-3 {
  filter: grayscale(1);
}

.demo5-2 {
  transform: scale(0.885);
}

.demo5-1 {
  opacity: 0.5;
}
複製代碼
<div class="demo5-3">
  <div class="demo5-2">
    <div class="demo5-1">
      <p class="demo5">demo5</p>
    </div>
  </div>
</div>
複製代碼

截圖結果爲:

示例五使用了一些特殊的屬性,好比 opacity、transform、filter;這些屬性特殊的地方在於若是設置在父元素上雖然不會被子元素繼承可是卻會對子元素形成影響,所以這個例子主要是爲了測試當對子元素截圖時是否考慮了父元素上的這些特殊屬性的影響;從截圖結果來看 dom-to-image 和 html2canvas 均未考慮,可是 simple-foreignobject 正常。

上述全部示例的完整代碼在 newbieyoung.github.io/Simple-Fore…

兼容性

Simple-ForeignObject 的兼容性能夠簡單理解和 SVG ForeignObject 的兼容性同樣;

固然並不排除代碼中的其它特性的影響,若是有問題歡迎你們提到 issue 裏邊。

安裝和使用

npm install simple-foreignobjec
複製代碼
var simpleFO = new SimpleForeignObject({
  devicePixelRatio: window.devicePixelRatio,
  ready: function() {
    var $demo = document.querySelector('#demo')
    simpleFO.toCanvas($demo, function(canvas) {})
  }
})
複製代碼
參數 說明
devicePixelRatio 設備像素比,若是不設置那麼截圖會比較模糊
ready 準備就緒回調函數,截圖操做須要在此回調函數中執行
toCanvas 截圖函數,會把指定的 DOM 元素繪製到 Canvas 中
相關文章
相關標籤/搜索