R.Aokiをフォローする

【html2canvas】任意の要素を指定して画面キャプチャを行う

フロントエンド

はじめに

今回はhtml2canvasの紹介になります。
業務で扱う機会があったのですが使用感が良く、使用できる場面は割とあるのではないかと感じました。

使用技術

html2canvas

使用例

下記が実装例になります。
ボタン押下で指定したDOM以下の内容をDLしてくれるだけの簡単な実装です。

<html>
  <head>
    <meta charset="utf-8" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <script>
      const onClickDownload = () => {
        const target = document.getElementById("target");
        if (target) {
          html2canvas(target).then((canvas) => {
            const downloadLink = document.createElement("a");
            downloadLink.href = canvas.toDataURL("image/png");
            downloadLink.download = "target.png";
            downloadLink.click();
          });
        }
      };      
    </script>
    <style>
      .download {
        border: solid 2px;
        border-color: #009879;
        background-color: #ffffff;
      }
      .styled-table {
        border-collapse: collapse;
        margin: 10px 0;
        font-size: 0.9em;
        font-family: sans-serif;
        min-width: 400px;
        box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
      }
      .styled-table thead tr {
        background-color: #009879;
        color: #ffffff;
        text-align: left;
      }
      .styled-table th,
      .styled-table td {
          padding: 12px 15px;
      }
      .styled-table tbody tr {
          border-bottom: 1px solid #dddddd;
      }
      .styled-table tbody tr:nth-of-type(even) {
          background-color: #f3f3f3;
      }
    </style>
  </head>
  <body>
    <button onclick="onClickDownload()">Download</button>
    <table id="target">
      <thead>
        <tr>
          <th>名前</th><th>ポジション</th><th>学年</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>円堂守</td><td>GK</td><td>2年生</td>
        </tr>
        <tr>
          <td>豪炎寺修也</td><td>FW</td><td>2年生</td>
        </tr>
        <tr>
          <td>風丸一郎太</td><td>DF</td><td>2年生</td>
        </tr>
        <tr>
          <td>壁山塀吾郎</td><td>DF</td><td>1年生</td>
        </tr>
        <tr>
          <td>染岡竜吾</td><td>FW</td><td>2年生</td>
        </tr>
        <tr>
          <td>半田真一</td><td>MF</td><td>2年生</td>
        </tr>
        <tr>
          <td>栗松鉄平</td><td>DF</td><td>1年生</td>
        </tr>
        <tr>
          <td>松野空介</td><td>FW</td><td>2年生</td>
        </tr>
        <tr>
          <td>影野仁</td><td>DF</td><td>2年生</td>
        </tr>
        <tr>
          <td>少林寺歩</td><td>MF</td><td>1年生</td>
        </tr>
        <tr>
          <td>宍戸佐吉</td><td>MF</td><td>1年生</td>
        </tr>
        <tr>
          <td>目金欠流</td><td>FW</td><td>2年生</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

左が実際の画面をSSしたもの、右がDLを行ったものになります。

解説

実装方法

html2canvasはhtmlの要素をcanvasとして生成するJavascriptライブラリです。

// 基本形
html2canvas(element, options);

// 例
html2canvas(document.getElementById("target")).then((canvas) => {
    const downloadLink = document.createElement("a");
    downloadLink.href = canvas.toDataURL("image/png");
    downloadLink.download = "target.png";
    downloadLink.click();
});

第1引数であるelementには、出力したいDOMを設定し、 第2引数には、オプションを設定できます。
html2canvas関数はcanvas要素を返却するため、予め作成していたアンカー要素のhref属性に返却されたcanvas要素をデータURLに変換して設定します。
ファイル名を設定した後、アンカー要素をクリックすることで出力した画像をダウンロードしています。

今回の実装ではoptionを特に使用していませんが、使用すると以下のような形になります。

// 例
html2canvas(document.getElementById("target"), {
    proxy: "https://~~~",
    useCORS: true,
}).then((canvas) => {
    const downloadLink = document.createElement("a");
    downloadLink.href = canvas.toDataURL("image/png");
    downloadLink.download = "target.png";
    downloadLink.click();
});

使用できるオプション一覧はこちらです。

注意点

SSではない

こちら注意点として実際にSSを撮影しているわけではないという点があります。
先ほど説明しましたが、html2canvasではDOMやCSSを読み込み、その結果をcanvasに描画した結果を出力しています。
つまり、実際に画面に出力されている表示と一部異なるものが出力される可能性があります。実際、先ほどの画像を見比べていただけば若干のずれが確認できると思います。

CSSのサポートについて

公式ドキュメントにもありますが、サポートしているCSSとサポートしていないCSSがあります。
導入の際には、画面に表示されているものと出力したものとのズレが許容範囲かどうかをよく確認してください。

CORS制限

canvasに描画する要素に別オリジンから読み込んだ画像などが含まれていた場合、クロスオリジン制限に引っかかることがあります。
その場合、サーバー側でもAccess-Control-Allow-Originヘッダーを設定し、画像要素にcrossOrigin属性を設定する、html2canvasのオプションでproxyとuseCORSを設定するなどの対策が必要です。

おわりに

今回はhtml2canvasについてでした。

いくつか注意点はありますが、簡易な実装でwebページを出力できる点は非常に有用かと思いますので、機会があればぜひお試しください。
ここまでご覧いただきありがとうございました。

クレジット

https://html2canvas.hertzen.com/