LoginSignup
2
2

More than 3 years have passed since last update.

Canvas2Dについてさっくり復習してみた

Last updated at Posted at 2020-12-06

Canvas2Dについてさっくり復習してみた

概要

ryokio0129です。

JavaScript Advent Calendar 2020 6日目になります。
初参加です。よろしくお願いいたします。

canvasへの描画に関して、昨今色々なフレームワークやライブラリがあり、そちらを使うことが多いと思います。
かくいう私も、仕事では Phaser というHTML5ゲームフレームワークを使っていることが多いです。

そんな中、たまたま素のCanavs2Dを触らないといけない状況が発生したので、さっくり復習していきます!

Canvas2Dをさっくり復習するどん

Canvas2Dのコンテキスト取得

WebGLにしてもCanvas2Dにしても、HTMLCanvasElementからコンテキストを取得しないと描画できないです。
Canvas2Dに関してはCanvasRenderingContext2Dを取得します。

See the Pen Canvas2Dのコンテキストを取得 by ryokio (@ryokio) on CodePen.

矩形・テキストの描画

矩形の描画は context.fillRect(x, y, width, height)
テキストの描画は context.fillText(text, x, y)

さくっと描画できますが、現状だとどちらも黒で何がなんだかわからないですね……。

See the Pen 矩形・テキストの描画 by ryokio (@ryokio) on CodePen.

色を指定する

色……特に塗りつぶすための色を指定するのは context.fillStyle を使います。
context.fillStyle はCSSの指定そのまま使えるので、例えば context.fillStyle = rgba(255, 0, 0, 0.1) のようにすると、不透明度も反映することが可能です。

色は変わりましたが、これだとどちらも同じ色になってしまいます。
これだと困りますね……。

See the Pen 色を指定する by ryokio (@ryokio) on CodePen.

描画状況の保存・復元

context.save() で今の描画状況を保存します。
context.restore() で保存した状況を復元します。

これで矩形のみがrgba(255, 0, 0, 0.1)になりました。
また、

context.save();

  // この時点での描画を保存
  context.save();
  context.fillStyle = '#00FF00';
  context.restore();

context.restore();

のように入れ子も出来ますが、context.save()context.restore() が抜けると大変なことになりますので、ご注意を。
(今までで context.restore() の記載が抜けてることの方が多かったです)

See the Pen 描画状況の保存・復元 by ryokio (@ryokio) on CodePen.

様々な図形

円弧を描く場合は context.arc() を使えば描けます。
context.beginPath() でパスを使いたい宣言をします。その後に、context.arc() を使って描画します。

See the Pen 円弧を描く by ryokio (@ryokio) on CodePen.

また context.moveTo() でパスの始点を変更することができます。
それを使って、様々な図形を描くことが可能です。

画像の描画

画像の描画は context.drawImage() で行います。
ですが、画像はまず画像を読み込み終えていることが前提ですので、画像が読み込み終わっているかのチェックが必要になります。

See the Pen 画像の描画 by ryokio (@ryokio) on CodePen.

context.drawImage() は画像以外にも色々指定することができます。

変形

図形や画像などは変形することが可能です。

拡縮に関しては context.scale()
移動に関しては context.translate()
回転に関しては context.rotate()

複雑な変形を行う場合は context.transform() もしくは context.setTransform() で可能です。
context.transform() は現状のマトリクスからの変形。
context.setTransform() は現状のマトリクスを破棄して変形(上書き)です。
どちらにしても2Dの行列計算が必要です。調べれば出てくるとはいえ、私は苦手です……。

See the Pen 変形 by ryokio (@ryokio) on CodePen.

合成

直前の描画との合成をする際は、context.globalCompositeOperation を設定します。
私は黒の矩形を画像で抜いて、シルエット画像にする。ということが多いでしょうか。
(これによって、わざわざシルエット画像を用意してもらう必要がなくなる)

See the Pen 合成 by ryokio (@ryokio) on CodePen.

オフスクリーンレンダリング

合成 の際に少しやっていますが、新しいcanvas要素を作り、そこにひとまず描画を行い、
その結果を、実際のcanvasに描画して反映させています。
いわゆるオフスクリーンレンダリングです。

専用の OffscreeCanvas というものもあるようですが、当面はこの手法でやるしかないのかなと思っています。

OffscreenCanvas - Web APIs | MDN
https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas

終わりに

アドベントカレンダー初参加だ!
と思いつつも、仕事が忙しい(言い訳)ために、今急いで書いた次第であります。
だが、参加することに意義がある! ……と信じつつ。

根っこのCanvas2Dを触れようとしている方の一助になれば幸いです。
ありがとうございました。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2