Canvasは、HTML5 Canvas APIを通じてウェブブラウザで、ネイティブSDKを通じてモバイルプラットフォームで利用可能な、2次元グラフィックス描画のためのプログラム可能なキャンバスです。UIコンポーネントによる宣言的レイアウトとは異なり、Canvasは画像のすべての要素をピクセル単位で制御できます。MDN Web Docs(2025)によると、Canvasは画像エディタからゲームまで、グラフィックスを扱う最新のウェブアプリケーションの78%で使用されています。開発者は、高い描画パフォーマンスとデータ可視化の完全な制御が必要な場合にCanvasを選択します。
重要なポイント
Canvasは、プログラムが描画コンテキストを使用してピクセル単位で描画を行う画面上の長方形領域です。この概念は2004年にWHATWG仕様の一部としてHTML5ウェブ標準で生まれ、以来すべてのプラットフォームにおけるグラフィックスの基盤となっています。
Canvasと宣言的アプローチ(SVG、UIコンポーネント)の主な違いは、Canvasがシーンを保存しないことです。描画後、ピクセルは固定され、画像を変更するにはプログラムが必要な領域を消去して再描画する必要があります。これにより、アニメーションで最大のパフォーマンスとシーン保存のための最小限のメモリ消費を実現します。
Canvasは2種類のコンテキストをサポートしています:フラットグラフィックス用の2Dと、GPUハードウェアアクセラレーションによる3次元描画用のWebGL / WebGL2です。Statista(2025)によると、Canvas APIはブラウザゲームの89%とウェブエディタの67%で使用されています。
モバイル開発では、Canvasは各プラットフォームに適応されています:AndroidではCanvasクラス、iOSではCore GraphicsとMetal、.NET MAUIではMicrosoft.Maui.Graphicsを通じて。描画コンテキスト、座標系、変換スタックという単一の原則は、プラットフォームに関係なく変わりません。
キャンバスはピクセルで指定された固定サイズのビットマップマトリックスです。各ピクセルはRGBA値(赤、緑、青のチャンネルとアルファ透明度)を保存します。Canvasの座標系は左上隅から始まり、X軸は右方向、Y軸は下方向です。
キャンバスのサイズは、ピクセル単位の幅と高さの2つのパラメータで決まります。キャンバスのwidth属性とheight属性をCSSの寸法と区別することが重要です。CSSは表示領域をスケーリングできますが、内部解像度は属性で設定されたままです。これらのパラメータが一致しないと、画像がぼやけます。
Androidでは、Canvasのサイズは通常、それが作成されるViewまたはBitmapのサイズと一致します。onDraw()が呼び出されると、ビューのサイズに既に設定されたCanvasが渡されるため、開発者が手動で寸法を設定する必要はありません。
Canvasは描画コンテキストを通じて機能します。これは現在の状態(塗りつぶし色、線の太さ、変換、パス)を保存するオブジェクトです。すべての描画メソッドの呼び出しはこの状態に適用され、キャンバスのビットマップマトリックスを変更します。
描画プロセスはパイプラインに従います:領域をクリア→状態を設定→パスを構築→ストロークまたは塗りつぶし。アニメーション中、このサイクルは毎秒60回繰り返され、スムーズさを維持するために各ステップの最適化が必要です。
Canvasはイミディエイトモードレンダリングを使用し、各描画コマンドが即座に実行されます。リテインドモード(SVGやDOM)とは異なり、Canvasはオブジェクトのリストを保存しません。これによりメモリ消費は減りますが、インタラクティブ性は複雑になります。開発者は自身でヒットテストと再描画を実装する必要があります。
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
ctx.font = '16px sans-serif';
ctx.fillText('Hello Canvas', 10, 80);
上記の例では、2Dコンテキストを取得し、塗りつぶし色を設定し、長方形を描画し、フォントを設定してテキストを出力しています。すべての操作は、要素のwidth属性とheight属性で指定されたサイズのキャンバス上で実行されます。
Canvasの状態スタックを使用すると、描画パラメータを保存および復元できます。save()メソッドは現在の状態をスタックにプッシュし、restore()は前の状態を復元します。これは、他の要素に影響を与えずに要素のグループにシフトや回転を適用する必要があるカスケード変換に便利です。
Canvas APIは、プリミティブ、画像、テキストの描画とスタイル管理のための約40のメソッドを提供します。基本セットには、長方形、パス、円弧、テキストを扱うメソッドが含まれています。主要なメソッドグループを見てみましょう。
長方形はCanvasの最速のプリミティブです。fillRect(x, y, w, h)メソッドは塗りつぶされた長方形を描画し、strokeRect()は境界線のみを描画し、clearRect()は領域をクリアします。複雑な多角形にはPath2Dオブジェクトを使用し、フレーム間で再利用できます。
| メソッド | 説明 | パフォーマンス |
|---|---|---|
| fillRect | 塗りつぶし長方形 | 高 |
| strokeRect | 長方形の輪郭 | 高 |
| beginPath | 新しいパスの開始 | 中 |
| arc | 円弧または円 | 中 |
| quadraticCurveTo | 2次ベジェ曲線 | 低 |
drawImage()はCanvasにビットマップ画像を描画するための主要メソッドです。このメソッドは3つのパラメータセットを受け入れます:単純コピー、スケーリング、スケーリング付きクロッピングです。画像はHTMLImageElement、SVGImageElement、または別のCanvasから読み込めます。
モバイル開発では、drawImage()がAndroidではBitmap、iOSではUIImageと連携することが重要です。プラットフォームの実装は、画像とCanvasが同じGPUテクスチャメモリにある場合にハードウェアアクセラレーションを使用します。画像のカラープロファイルが一致しない場合、変換によるパフォーマンス低下が発生する可能性があります。
requestAnimationFrame()はCanvasアニメーションの標準メカニズムです。setIntervalとは異なり、このメソッドは描画を画面のリフレッシュレート(通常60 FPS)に同期させます。タブがバックグラウンドにある場合、ブラウザは呼び出しを停止してバッテリーを節約します。
Canvasアニメーションを最適化するには、再描画領域を最小限に抑えます:キャンバス全体をクリアする代わりに、変更された領域のみにclearRect()を使用します。要素を1つのレイヤーにグループ化し、静的部分をオフスクリーンCanvasにキャッシュすると、レンダリングパイプラインの負荷が軽減されます。
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#e74c3c';
ctx.beginPath();
ctx.arc(x, 60, 25, 0, Math.PI * 2);
ctx.fill();
x += 2;
requestAnimationFrame.bind(animate);
}
アニメーションループはキャンバスをクリアし、オブジェクトの位置を更新して再描画します。requestAnimationFrameはスムーズさとタブ非表示時の自動一時停止を保証し、デバイスリソースを節約します。
Canvasはモバイルプラットフォームで異なる方法で実装されていますが、プログラム可能なキャンバスという共通のアイデアに基づいています。Androidでは、Canvasクラスはグラフィックスシステムの一部であり、任意のViewのonDraw(Canvas)メソッドに渡されます。iOSでは、CGContextコンテキストを持つCore Graphicsが同等です。
Android CanvasはBitmapまたはSurfaceViewと連携して動作します。Bitmap経由でCanvasを作成するとメモリ内で描画が行われ、SurfaceView経由ではハードウェアアクセラレーションを使用して直接画面に描画されます。API 14+以降、CanvasはHWUI(描画コマンドをOpenGLまたはVulkanに変換するハードウェアアクセラレータ)を使用します。
Android Canvasの主要メソッドには、drawBitmap()、drawCircle()、drawLine()、drawPath()があります。すべてのメソッドは、スタイル(色、太さ、アンチエイリアシング効果)を制御するPaintオブジェクトを受け入れます。Google I/O(2024)によると、HWUI上のCanvasはソフトウェアレンダリングと比較して最大40%のパフォーマンス向上を示します。
class CustomView(context: Context) : View(context) {
private val paint = Paint().apply {
color = Color.RED
isAntiAlias = true
strokeWidth = 4f
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(100f, 100f, 50f, paint)
canvas.drawText("Canvas Android", 100f, 200f, paint)
}
}
Androidでは、CanvasはAPI 14+でデフォルトでハードウェアアクセラレーションを使用します。複雑なグラフィックスには、バックグラウンドスレッドでの描画用に別のレイヤーを割り当てるSurfaceViewまたはTextureViewを推奨します。これにより、集中的なアニメーション中のUIスレッドのブロッキングを防ぎます。
Core Graphicsは、ラスターグラフィックスとベクターグラフィックスのためのAppleのフレームワークで、Canvasに相当します。CGContextコンテキストは、線、曲線、グラデーション、影を描画するメソッドを提供します。SwiftUIでは、iOS 15で追加されたCanvas構造体を通じて利用可能です。
SwiftUI Canvasは、Core Graphics上のタイプセーフなラッパーであるGraphicsContextを使用します。開発者は、変換、レイヤー、シンボルをサポートするGraphicsContextを操作します。UIKitとは異なり、SwiftUI CanvasはRetinaディスプレイと動的タイプを自動的に処理します。
struct MyCanvasView: View {
var body: some View {
Canvas { context, size in
context.fill(
Path(ellipseIn: CGRect(x: 0, y: 0, width: 100, height: 100)),
with: .color(.red)
)
context.draw(
Text("Canvas iOS"),
at: CGPoint(x: 50, y: 150)
)
}
.frame(width: 300, height: 300)
}
}
SwiftUI Canvasは、宣言的構文と自動描画最適化が特徴です。フレームワーク自体が、状態が変更されたときにキャンバスのどの部分を再描画する必要があるかを判断します。GraphicsContextはdrawLayerメソッドを通じてレイヤーをサポートし、多層グラフィックスの作成を簡素化します。
Canvasのパフォーマンスは、再描画領域、描画呼び出しの数、操作の複雑さの3つの要因に依存します。各描画メソッド呼び出しはパイプラインを通過するコマンドです:CPUがコマンドを形成し、GPUがラスタライズを実行します。
最適化の主なルールは呼び出し回数を最小限に抑えることです。1000個の個別の点を描画する代わりに、1000セグメントのパスを使用します(1000回ではなく1回のstroke()呼び出し)。2つ目のルールは静的キャッシングです:変更されない要素をオフスクリーンCanvasに移動し、drawImage()でコピーします。
プロファイリングツール:ウェブ用のChrome DevTools Performance、Android用のGPU Inspector、iOS用のInstruments。Google Chrome Developers(2025)によると、Canvasのパフォーマンス問題の70%は過剰な再描画とレイヤーキャッシングの欠如が原因です。
| 問題 | 原因 | 解決策 |
|---|---|---|
| カクつくアニメーション | 毎フレームキャンバス全体をクリア | ダーティ領域とclearRectを使用 |
| 低FPS | 描画呼び出しが多すぎる | プリミティブをPath2Dに統合 |
| ぼやけ | CSSとサイズ属性の不一致 | width/heightとCSS寸法を同期 |
| メモリリーク | 削除なしのオフスクリーンCanvas | 未使用のキャンバスへの参照をクリア |
モバイルデバイスでは、バッテリー節約が重要です。過剰な描画はGPUに負荷をかけ、動作時間を短縮します。画面のリフレッシュレートに同期するには、AndroidではwillBePresented()メソッド、iOSではdisplayLinkを使用します。
現代のCanvasは単純な2D描画を超えています。CanvasContextに基づくWebGLは、ハードウェアアクセラレーションによる3次元グラフィックスの描画を可能にします。OffscreenCanvasは、UIスレッドをブロックせずに、負荷の高い描画をWeb Workersに移行します。
WebGLは、ブラウザからOpenGL ESへのアクセスを提供するCanvasコンテキストです。fillRect()の代わりに、開発者はGLSLでシェーダーを作成し、ジオメトリをバッファに読み込みます。Statista(2025)によると、92%のモバイルブラウザがWebGL 2.0をサポートしており、Canvasはウェブゲームと3Dビジュアライゼーションの基盤となっています。
WebGLのコンテナとしてのCanvasは、1つのアプリケーションで2Dと3Dグラフィックスを統合するのを簡素化します。例えば、3DシーンはWebGLで描画され、UIオーバーレイは同じキャンバスの2Dコンテキストで描画されます。混合描画には、Zオーダーの管理とフレームレートの同期が必要です。
OffscreenCanvasは、描画をバックグラウンドスレッドに移行するためのAPIです。通常のCanvasとは異なり、OffscreenCanvasはDOMに結びつかず、Web Workerで使用できます。これにより、FPSの低下なしにメインスレッドと並行して複雑なグラフィックス計算を実行できます。
Workerからメインスレッドへの完成フレームの転送は、transferControlToOffscreen()とcommit()を介して行われます。Chrome Platform Status(2025)によると、OffscreenCanvasはブラウザの87%でサポートされており、グラフィックエディタ、チャート、アニメーションなどの集中的な描画を必要とするアプリケーションに推奨されています。
よくある質問
Canvasはラスターモードで動作し、描画後にピクセルが固定されます。SVGはベクターオブジェクトを保存し、変更時に再描画します。Canvasは頻繁な再描画を伴うアニメーションに高速で、SVGはスケーリングを伴うインタラクティブな図に適しています。
2Dコンテキストは図表、エディタ、インターフェースに適しています。WebGLは3Dグラフィックスとシェーダーによる画像処理に必要です。単純な2Dアニメーションには、2Dコンテキストの方が開発が速く、十分なパフォーマンスを発揮します。
はい、Canvasはテキスト出力のためのfillText()とstrokeText()をサポートしています。カスタムフォントを扱うには、Font Loading APIを通じて読み込む必要があります。モバイルプラットフォームでは、Android CanvasはTypeface、iOSはUIFontを使用します。
部分再描画にはダーティ領域を使用し、静的な要素をオフスクリーンCanvasにキャッシュし、描画呼び出しの回数を減らします。Androidではマニフェストでハードウェアアクセラレーションを有効にします。iOSではOpenGLの代わりにMetalを使用します。
Canvasはvideo要素からdrawImage()で動画をキャプチャし、各フレームにフィルタを適用できます。本格的な編集には、WebGLと動画ストリームの低レベル処理のためのWebCodecsが使用されます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。