はじめに
「このページをそのまま画像として保存したい」「レポート画面をPDFに出力したい」——Webアプリを作っていると、こうした要望に何度も出会います。しかしブラウザには標準で「画面をキャプチャするAPI」は用意されていません。サーバー側でHeadless Chromeを立てて撮影する方法もありますが、インフラのコストや構成が重くなりがちです。
そこで役立つのが html2canvas です。クライアント側のJavaScriptだけで、DOM要素を画像化できるライブラリとして長年使われ続けています。この記事では、html2canvasの特徴から具体的な実装方法までをご紹介します。
とはいえ、読むより触った方が早いと思います。テキストや背景色を変えたカード要素をその場でキャプチャできるサンプルを用意したので、先に挙動を見たい方はこちらからどうぞ。
html2canvasとは
html2canvasは「Screenshots with JavaScript」を掲げるライブラリで、指定したDOM要素をブラウザ上で解析し、<canvas> 要素として描画してくれます。面白いのは、実際に画面をキャプチャしているわけではないという点です。DOMツリーと適用されているCSSスタイルを1つずつ読み取り、その情報をもとにCanvas上へ再構築しているのです。そのため「本物のスクリーンショット」とは少し性質が異なりますが、サーバーを使わずにブラウザだけで画像化が完結する手軽さから、幅広いプロジェクトで採用されています。
主な特徴
- サーバー不要 - すべての処理がクライアント側で完結するため、バックエンドの構築が不要です
- Promiseベースの非同期API -
html2canvas(element)は Promise を返すため、thenやasync/awaitで扱えます - 主要ブラウザに対応 - Chrome、Firefox、Safari、Edgeなど、モダンブラウザで動作します
- 柔軟なオプション - 背景色の指定、スケール変更、対象範囲の限定など、細かな調整が可能です
インストール
npmまたはyarnでインストールできます。
npm install html2canvas
yarn add html2canvas
CDN経由で読み込むことも可能です。
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
html2canvasのサンプルを動かす
下のフォームは、テキストと背景色を自由に変えられるカード要素を html2canvas() でキャプチャし、生成された <canvas> をそのままページに追加するサンプルです。テキスト入力欄を書き換えたり、カラーピッカーで背景色を選び直したりしてから「キャプチャする」ボタンを押すと、そのときの見た目がそのまま画像化されます。
サンプルの中心部分だけを抜き出すと、次のようになります。html2canvas(target, options) はPromiseを返すので、await で <canvas> を受け取ってそのまま画面に追加できます。
import html2canvas from "html2canvas";
const target = document.querySelector("#card");
const resultBox = document.querySelector("#result");
async function capture() {
const canvas = await html2canvas(target, {
backgroundColor: null, // 透過を維持
scale: 2, // 高解像度で出力
});
resultBox.appendChild(canvas);
}
document.querySelector("#capture-btn").addEventListener("click", capture);
実際に動かせるものが下です。値を書き換えるとその場で結果が変わります。
テキスト入力欄に文字を打つと input イベントでカードの文言がリアルタイムに書き換わり、カラーピッカーで背景色を変えると即座に反映されます。「キャプチャする」ボタンを押した瞬間の見た目を html2canvas() がDOMとCSSから解析し直し、scale: 2 オプション付きで高解像度の <canvas> として書き出す様子を確認できます。backgroundColor: null を "#ffffff" に変えると、透過ではなく白背景でキャプチャされる違いも試せます。
基本的な使い方
最もシンプルな例は、document.body をそのまま画像化するケースです。
import html2canvas from "html2canvas";
html2canvas(document.body).then((canvas) => {
document.body.appendChild(canvas);
});
特定の要素だけを対象にしたい場合は、その要素をそのまま渡します。
const target = document.querySelector("#capture-area");
html2canvas(target).then((canvas) => {
const imageData = canvas.toDataURL("image/png");
console.log(imageData); // Base64形式の画像データ
});
async/await を使うと、より読みやすく書けます。
async function captureElement(selector) {
const target = document.querySelector(selector);
if (!target) return null;
const canvas = await html2canvas(target, {
backgroundColor: "#ffffff",
scale: window.devicePixelRatio,
});
return canvas.toDataURL("image/png");
}
実践的なユースケース
1. 画面の一部をPNGとしてダウンロードする
ユーザーが編集した内容をそのまま画像として保存したい場合に便利です。
async function downloadAsImage(selector, fileName) {
const target = document.querySelector(selector);
if (!target) return;
const canvas = await html2canvas(target, { backgroundColor: "#ffffff" });
const link = document.createElement("a");
link.download = `${fileName}.png`;
link.href = canvas.toDataURL("image/png");
link.click();
}
// 使用例
downloadAsImage("#report-card", "monthly-report");
downloadAsImage() は html2canvas() で取得した canvas を toDataURL("image/png") でBase64画像に変換し、<a download> のクリックでファイル保存をトリガーするhtml2canvasの典型的な使い方です。実際に動かして確認してみましょう。入力欄のテキストを書き換えてから「PNGとしてダウンロード」ボタンを押すと、そのときの見た目がキャプチャされ、下にプレビュー画像が表示されます(ブラウザの設定によっては実際のダウンロードも走ります)。
backgroundColor: "#ffffff" を null に書き換えると、背景が透過されたPNGとして書き出されるようになります。report-input に入力した文言がそのままキャプチャ結果に反映される様子から、html2canvas() が呼び出された瞬間のDOMを解析していることが分かります。
2. PDF生成ライブラリと組み合わせる
jsPDF などと組み合わせれば、画面をそのままPDFレポートとして出力できます。
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
async function exportToPdf(selector) {
const target = document.querySelector(selector);
const canvas = await html2canvas(target, { scale: 2 });
const imgData = canvas.toDataURL("image/png");
const pdf = new jsPDF({ orientation: "portrait", unit: "px" });
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight);
pdf.save("document.pdf");
}
html2canvas() で得た canvas を toDataURL() で画像データに変換し、pdf.addImage() でPDFのページに貼り付けるという2ステップの流れです。下のサンプルでは jsPDF の output("bloburl") を使って、生成したPDFをその場でプレビューできるようにしています。
「PDFを生成」ボタンを押すと、html2canvas がキャプチャした見積書がそのままPDFのiframeプレビューに変わります。入力欄の文言を変えてから再生成すると、PDFの中身もその場で書き換わることが確認できます。orientation: "portrait" を "landscape" にすれば、横向きのPDFとして出力する挙動も試せます。
3. SNSシェア用のOGP画像を動的に生成する
診断結果やスコア表示など、動的なコンテンツを画像化してシェアボタンに紐づけるユースケースもよく見られます。
async function generateShareImage(selector) {
const target = document.querySelector(selector);
const canvas = await html2canvas(target, {
backgroundColor: null, // 透過を維持
scale: 2, // 高解像度で出力
});
return canvas.toDataURL("image/png");
}
使用時の注意点
便利な一方で、いくつか押さえておきたい制限もあります。
- 外部画像はCORSの制約を受けます - クロスオリジンの画像を含む要素をキャプチャする場合、プロキシ設定や
useCORSオプションが必要になることがあります - すべてのCSSプロパティに対応しているわけではありません -
filterや一部の新しいレイアウト機能など、再現できないスタイルも存在します - あくまで「再構築」である点 - DOM情報から描き直しているため、実際の見た目と完全に一致しない場合があります。重要な用途では出力結果を必ず目視確認することをおすすめします
まとめ
html2canvasは、サーバーを使わずにブラウザだけでDOM要素を画像化できる、手軽さが魅力のライブラリです。「本物のキャプチャ」ではなく「DOM情報からの再構築」という仕組みを理解しておけば、レイアウトが崩れた際の原因調査もスムーズになります。
画面のダウンロード機能やPDFレポート出力、SNSシェア画像の生成など、活用の幅は意外と広いので、ぜひ手元のプロジェクトで試してみてください。
