[HTML5] Canvasで描画する際に、要素同士が重なる部分のブレンドモードを指定する
こんにちは、@yoheiMuneです。
今日は、HTML5 Canvasのブレンドモードについてブログに書きたいと思います。
例えば、以下のコードの場合は、四角形の上に丸が描画されます。
上記の例では、丸と四角形が重なる部分は、後から描いた丸が描画されています。
この重なった部分の描画をどのようにするかを指定することができるのが、Canvasのブレンドモードです。
上記それぞれのブレンドモードで描画したサンプルは、以下となります。
ブレンドモードを利用することで、重なり部分の描画方法を決めることができます。
具体的には、以下のようにブレンドモードを指定します。
ポイントは、ContextのglobalCompositeOperationにブレンドモードを指定するところです。
上記の実装で、丸を描く際に、ブレンドモードを指定しています。
これを利用すれば、図形の切り抜きや、色の加算・減算ができて、表現の幅が広がりそうだなぁと思いました。
ただし、このブレンドモードは、ブラウザ毎に実装内容が間違っていたり、サポートしていないブレンドモードがあったりと、 使う際には注意が必要です。
当たり前ですが、サポート対象ブラウザ/端末でのテストは、必須です。
最後までご覧いただきましてありがとうございました。
今日は、HTML5 Canvasのブレンドモードについてブログに書きたいと思います。
Cnavasのブレンドモードとは
HTML5 Canvas上に、画像・図形・文字などを描画する際に、通常は重なり合う部分は後に描画した内容が描画されると思います。例えば、以下のコードの場合は、四角形の上に丸が描画されます。
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // 四角形を描画する。 ctx.fillStyle = '#cc00cc'; ctx.fillRect(canvas.width/4, canvas.height/4, canvas.width/2, canvas.height/2); ctx.fillStyle = '#cccc00'; ctx.beginPath(); // 丸を描画する。 ctx.arc(canvas.width*3/4, canvas.height*3/4, canvas.width/4, 0, Math.PI*2, true); ctx.fill();
上記の例では、丸と四角形が重なる部分は、後から描いた丸が描画されています。
この重なった部分の描画をどのようにするかを指定することができるのが、Canvasのブレンドモードです。
Canvasのブレンドモードの種類
W3Cのページによれば、ブレンドモードは以下の12種類があるようです。- source-over
- デフォルト値。現在描画している内容に上書きする形で新しい図形を描画する。
- source-in
- 既に描画された図形と、新規で描画する図形で重なる領域のみ描画される。それ以外はすべて透明となる。
- source-out
- 新しい図形のうち、既にCanvas上に描画されていない領域のみが描画される。
- source-atop
- 新しい図形は、既にCanvas上に存在する図形と重なる部分のみ描画される。
- destination-over
- 新しい図形は、既に存在するCanavs上の図形以外の部分のみ描画される。
- destination-in
- 既にCanvas上に存在する図形のうち、新しい図形と重なる部分のみが描画される。
- destination-out
- 新しく描画する図形の領域と重ならない部分のみ、既存の図形が残り、それ以外は透明となる。
- destination-atop
- 新規図形と既存図形が重なる部分のみ、既存図形が描画される。新しい図形はその逆で、既存図形と重ならない部分のみ描画される。
- lighter
- 新規図形と既存図形の領域が重なる部分は、色値を加算して描画する。
- darker
- 新規図形と既存図形で同じ場所を描画する場合には、色値の減算を行う。
- copy
- 新規図形のみ描画される。新規図形と既存図形が重なる部分は、新規図形のみ描画する。
- xor
- 新規図形/既存図形の両方のイメージの領域が描画される。重なった部分は描画されない。
上記それぞれのブレンドモードで描画したサンプルは、以下となります。
ブレンドモードを利用することで、重なり部分の描画方法を決めることができます。
具体的には、以下のようにブレンドモードを指定します。
// CanvasとContextの初期化を行う。 var canvas = document.getElementById(canvasId); var ctx = canvas.getContext('2d'); // 1つ目の図形を描画する。 // このときは、ブレンドモードはデフォルト値のまま。 ctx.fillStyle = '#cc00cc'; ctx.fillRect(canvas.width/4, canvas.height/4, canvas.width/2, canvas.height/2); // 2つ目の図形を描画する。 // ブレンドモードにsource-inを指定する。 // contextのsaveメソッドを使うのは、あとでブレンドモードを設定値前に復元するため。 ctx.save(); ctx.globalCompositeOperation = 'source-in'; ctx.fillStyle = '#cccc00'; ctx.beginPath(); ctx.arc(canvas.width*3/4, canvas.height*3/4, canvas.width/4, 0, Math.PI*2, true); ctx.fill(); // ブレンドモードの設定をもとに戻す。 ctx.restore(); // デフォルト値のブレンドモードで、文字を描画する。 ctx.font = "32px 'Hiragino Kaku Gothic Pro', sans-serif"; ctx.fillStyle = '#000000'; ctx.fillText(globalCompositeOperation, 5, 30);
ポイントは、ContextのglobalCompositeOperationにブレンドモードを指定するところです。
上記の実装で、丸を描く際に、ブレンドモードを指定しています。
最後に
Canvasは、上塗りが当たり前と思っていたので、このブレンドモードを知ったときには驚きでした。これを利用すれば、図形の切り抜きや、色の加算・減算ができて、表現の幅が広がりそうだなぁと思いました。
ただし、このブレンドモードは、ブラウザ毎に実装内容が間違っていたり、サポートしていないブレンドモードがあったりと、 使う際には注意が必要です。
当たり前ですが、サポート対象ブラウザ/端末でのテストは、必須です。
最後までご覧いただきましてありがとうございました。