snapDOMを活用したDOMの画像変換

4分で読めます

概要

モバイルゲーム業界ではプレイヤーのステータス・ランキング・アチーブメントなどをSNSシェア用の画像として生成する機能が複数のタイトルで提供されており、それらを実現する方法としてsnapDOMの簡単な使い方と、ユーザーが簡単にシェアするためのAPIを紹介します。

snapDOMとは?

SnapDOMは、超高速、モジュール化、拡張性に優れた次世代のDOMキャプチャエンジンです。あらゆるDOMサブツリーを自己完結的な表現に変換し、SVG、PNG、JPG、WebP、Canvas、Blob、あるいはプラグインを介して任意のカスタムフォーマットにエクスポートできます。

DOMの画像変換ライブラリにはhtml2canvasやdom-to-imageが広く使われてきましたが、これらのライブラリには以下のような課題があります。

  • html2canvas:
    独自のCSSパーサーでCanvas描画を行うため、実際のブラウザレンダリングと異なる結果になることがある。
  • dom-to-image:
    現在でも使えるが、開発が停止状態で今後のメンテナンスや新機能追加が期待できない。

snapDOMは、活発にメンテナンスされており、最新のWeb技術に対応した新しいライブラリとして注目されています。

どんなところに使えるのか

snapDOMはクライアントでHTML要素を画像に変換するため、サーバーやAPIを使わずに低コストで画像生成機能を実装できます。

  • コードスニペットの画像化
  • ダッシュボードやレポートのエクスポート
  • SNS投稿用のコンテンツ作成
  • 資料やプレゼンテーション用の画像生成
  • デザインツールの出力機能

ユーザーの入力やファイルを読み込ませてカスタマイズした画像生成などにも活用できます。

snapDOMの導入と基本的な使い方

snapDOMはnpmパッケージとして提供されており、以下の手順で導入できます。使用方法も非常にシンプルです。

インストール

Bash
npm install @zumer/snapdom

基本的な実装方法

HTML要素を画像に変換する最もシンプルな方法です。対象の要素を取得し、snapdomに渡すだけで画像データが生成されます。
Reactの場合は、useRefで要素を参照する形で実装します。

TypeScript
import { snapdom } from '@zumer/snapdom';

// 要素を画像に変換
const element = document.getElementById('my-element');
const result = await snapdom(element, {
  scale: 2,
  embedFonts: true
});

// PNG形式で取得
const blob = await result.toBlob({ type: 'png' });

出力形式の使い分け

用途に応じて様々な画像形式で出力できます。PNG(透明背景)、JPEG(小サイズ)、WebP(高圧縮)、SVG(ベクター)、Canvas(加工用)から選択可能です。

TypeScript
// 形式を指定してBlob取得
const pngBlob = await result.toBlob({ type: 'png' });
const jpegBlob = await result.toBlob({ type: 'jpeg', quality: 0.9 });
const webpBlob = await result.toBlob({ type: 'webp', quality: 0.8 });

// その他の形式
const svgImage = await result.toSvg();
const canvas = await result.toCanvas();

公式サイトにいろいろな使用例が掲載されていますので、詳しくは公式サイトを確認してみてください。

ダウンロードと共有方法

生成した画像をユーザーが簡単にダウンロードしたり、SNSアプリなどに共有できるようにする方法を紹介します。

ダウンロード

生成した画像をファイルとしてダウンロードする基本的な方法です。 以下のコードでは、result.toBlob()で画像をBlob形式に変換し、URL.createObjectURL()でダウンロード用のURLを作成します。その後、動的に作成した<a>要素でダウンロードを実行し、最後にメモリリークを防ぐためURLを解放しています。

TypeScript
// シンプルなダウンロード
const blob = await result.toBlob({ type: 'png' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'image.png';
link.href = url;
link.click();
URL.revokeObjectURL(url);

Web Share API

Web Share APIを使用すると、モバイルデバイスで生成した画像を他のアプリに直接共有できます。

Web Share APIは比較的新しい機能で、主にモバイルデバイス(Android Chrome、iOS Safari)でサポートされています。デスクトップブラウザでの対応は限定的なため、navigator.sharenavigator.canShareでの事前チェックが重要です。

TypeScript
// モバイルでの共有
const blob = await result.toBlob({ type: 'png' });
const file = new File([blob], 'image.png', { type: 'image/png' });

if (navigator.share && navigator.canShare({ files: [file] })) {
  await navigator.share({
    files: [file],
    title: '画像を共有'
  });
}

この機能を使用することで、ユーザーはワンタップで以下のようなアプリに画像を直接送信できます。対応ブラウザでは、SNSアプリやメッセージアプリなどに画像を直接送信できます。

デモ

このサイトのPlaygroundにsnapDOMを使ったサンプルがあるので興味のある方は試してみてください。

snapDOM デモを試す

この記事は役に立ちましたか?

この記事をシェア

X
Facebook
はてな
utsusieのプロフィール画像

utsusie

UI Designer / Web Director