キャンバス ドリブンの背景画像

Eric Bidelman 氏

プログラムによる背景画像のアニメーション

背景画像をアニメーション化する主な方法は、次の 2 つです。

  1. CSS スプライトを使用して JS で background-position を更新します。
  2. .toDataURL() によるハッキング

1 つ目の方法は、画像を事前に用意している場合は便利ですが、<canvas> などでソースをプログラムで生成する必要がある場合はどうすればよいでしょうか。1 の解決策は、キャンバスで .toDataURL() を使用し、生成された URL に背景を設定することです。

while(1) {
    var url = canvas.toDataURL('image/jpeg');
    el.style.background = 'url(' + url + ')';
}

これには 2 つの問題があります。

  1. data: URL の場合、生成される画像のサイズに最大で 33% のオーバーヘッドが生じます。
  2. 大量の DOM の接触(el.style)。

どちらの方法も非効率的であり、常に滑らかで滑らかな 60 fps のウェブアプリには受け入れられません。

2D キャンバスを背景として使用する

背景デモとしてのキャンバス
デモ

WebKit が何年も前から提供してきた非標準の API があり、キャンバスを背景のソースとして使用できます。残念ながら、この機能の仕様は公開されていません

まず、背面の URL を指定する代わりに、次のようにします。

.bg {
    background: url(bg.png) no-repeat 50% 50%;
}

-webkit-canvas() を使用して、キャンバス コンテキストへの文字列識別子を参照します。

.canvas-bg {
    background: -webkit-canvas(animation) no-repeat 50% 50%;
}

次に、特別なバージョンの .getContext() を使用して 2D コンテキストを作成する必要があります。

var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);

Dave Hyatt からのその他の情報:

アニメーション

デモで示されているように、requestAnimationFrame() を再利用してアニメーションを動作させることができます。一度接続すると、CSS とキャンバス要素の関連付けが維持されるため、とても便利です。DOM を手直しする必要はありません。

Chrome のデモがアニメーションで表示されない場合

Chrome の現在の Stable チャンネル(バージョン 23)には crbug.com/161699 があり、requestAnimationFrame() アニメーションで背景が正しく更新されません。この問題は Chrome 25(現在は Canary 版)で修正されています。デモも現在の Safari で問題なく動作するはずです。

パフォーマンス上のメリット

こちらがキャンバスです。ハードウェア アクセラレーションによるアニメーションが、完全に機能するようになりました(少なくともこの機能に対応しているブラウザでは)。繰り返しになりますが、JS から DOM を除去する必要はありません

背景として webgl を使用する

少々お待ちください。これは、webgl を使用して CSS 背景を強化できるということでしょうか?無理もありません。WebGL は、キャンバスの 3D コンテキストにすぎません。「2d」ではなく「experimental-webgl」に切り替えるだけで、完了です。

var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);

頂点シェーダーとフラグメント シェーダーを使用して背景を描画した div を含む概念実証を以下に示します。デモ

その他のアプローチ

Mozilla はかなり以前から -moz-element()MDN)を使用していました。これは CSS Image Values andReplaced Content Module Level 4 仕様の一部であり、動画、キャンバス、DOM コンテンツなど、任意の HTML から生成された画像を作成することができます。しかし、DOM のスナップショット イメージへの完全アクセス権があることにはセキュリティ上の懸念があります。他のブラウザでこの機能を利用していないのは、このことが主な理由です。