html2canvas注意事項總結

html2canvas可以實現瀏覽器端直接對整個或部分頁面進行截屏,是目前較爲經常使用的截屏方案,其原理簡單來講就是先將需截屏的 DOM 部分轉化爲 canvas 畫布,再將 canvas 畫布轉化爲圖片。html2canvas 的使用很簡單,但在實際開發過程當中,需注意以下幾點:html

圖片跨域問題(截圖中會出現圖像缺失)

  • 解決方案:
  1. 在 html2canvas 配置項中配置 allowTaint: false

canvas 的 CanvasRenderingContext2D 屬於瀏覽器中的對象,若是曾經渲染過跨域資源,瀏覽器就認定 canvas 已經被污染(tainted)了。ios

  1. 在 html2canvas 配置項中配置 useCORS: true

重要的配置項,表示容許跨域資源共享,注意不能與 allowTaint 同時配置爲 true。web

  1. 在 img 標籤中添加 crossOrigin = "anonymous"

anonymous:若是使用這個值的話就會在請求中的 header 中的帶上 Origin 屬性,但請求不會帶上 cookie 和客戶端 ssl 證書等其餘的一些認證信息。canvas

  1. 圖片服務器配置 Access-Control-Allow-Origin: *

重要的配置項,是跨域問題的根本源泉,需後端配合。小程序

生成的截圖中文字間距變大

  • 解決方案:

使用 CSS 屬性 letter-spacing 進行調整。後端

能進行截圖,但截圖顯示不完整

  • 解決方案:

在截圖操做前先將 body 的 scrollTop 值設爲0(需提早確認所帶來的體驗差別)。跨域

生成的圖片模糊(截圖鋸齒化較爲嚴重)

  • 解決方案(原理:先將 canvas 容器擴大,再將合成的圖片進行縮放):
// 動態獲取設備的像素比,從而正確放大 canvas
    getPixelRatio(context) {
      let backingStore =
        context.backingStorePixelRatio ||
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
      return (window.devicePixelRatio || 1) / backingStore;
    },
    saveScreenshot() {
      console.log("執行截屏");
      let self = this,
        canvas = document.createElement("canvas"),
        width = document.getElementById("screenPart").clientWidth,
        height = document.getElementById("screenPart").clientHeight,
        context = canvas.getContext("2d"),
        scale = this.getPixelRatio(context),
        pageYOffset = window.pageYOffset;
      canvas.width = width * scale;
      canvas.height = height * scale;
      canvas.style.width = width + "px";
      canvas.style.height = height + "px";
      context.scale(scale, scale);
      self.loadImage = true;
      setTimeout(() => {
        html2canvas(document.getElementById("screenPart"), {
          logging: false,
          tainttest: true,
          background: null,
          useCORS: true,
          canvas: canvas,
          scale: scale,
          width: width,
          height: document.body.scrollHeight,
          windowWidth: document.body.scrollWidth,
          windowHeight: document.body.scrollHeight,
          onrendered: function(canvas) {
            let picUrl = canvas.toDataURL("image/jpeg");
            picUrl = picUrl.replace(/data:image\/jpeg/i, "data:image/png");
            // 存入 localStorge 以便後續取用
            window.localStorage.setItem("picUrl", picUrl);
          }
        });
      }, 500);
    }
複製代碼

渲染時出現白屏

  • 解決方案(原理:將 base64 轉成二進制流,資源會減少 1 到 1.5 倍):
function dataURLtoBlob (data_url) {
    let arr = data_url.split(',');
    let mime = arr[0].match(/:(.*?);/)[1];
    let bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    let blob = false;
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    try {
      blob = new Blob([u8arr], { type: mime });
    } catch (e) {}
    return blob;
  }
複製代碼

在小程序內嵌 H5 開發環境中,圖片資源過大時,某些機型(常見於 ios)會實行限流,在渲染時,微信可能會直接白屏或提示「該小程序繼續運行會影響微信的使用」,繼而強制退出該小程序。瀏覽器

JPEG的黑屏問題

  • 解決方案:縮減部分圖片元素的體積和尺寸大小。

設置 html2canvas 輸出格式爲 jpeg 時,會有必定概率致使生成的圖片包含大量的黑色塊。bash

html2canvas 暫不支持的 CSS 樣式屬性

These CSS properties are NOT currently supported
background-blend-mode
background-clip: text
box-decoration-break
repeating-linear-gradient()
font-variant-ligatures
mix-blend-mode
writing-mode
writing-mode
border-image
box-shadow
filter
zoom
相關文章
相關標籤/搜索