最近、Android開発でJetpack ComposeでCanvasを使う機会があったので、今まで難しそうでなかなか手を出してこなかった、Canvasを勉強してみることにしました。
Canvasの基本的な考え方
普段僕たちがみている画面は、ピクセルによって構成されています。キャンバスでは、このピクセルが色で満たされることで、その代わりに画面に画像が表示されるというものになっています。
Canvasでは、最初x = 0, y = 0
からスタートします。つまり、画面の左上の部分ですね。そこから、xにどのくらい動くのか?yにどのくらい動くのかを記述することで、さまざまなグラフィックを再現できます。
まずは簡単な三角形を表現してみます。
Canvas(
modifier = Modifier
.width(150.dp)
.height(150.dp)
.padding(16.dp)
) {
val path = Path()
path.moveTo(size.width.toFloat(), 0F)
path.lineTo(size.width.toFloat(), size.height.toFloat())
path.lineTo(0F, size.height.toFloat())
drawPath(
path = path,
brush = SolidColor(Color.LightGray)
)
}
こんな感じで、三角形が表現できました。
ここでのコードが何をやっているのかというと、まず先ほども述べたようにCanvasでは、(x=0、y=0)からスタートします。
そこで、まずはpath.moveTo(size.width.toFloat(), 0F)
でxに300dp
分移動して、そこからpath.lineTo(size.width.toFloat(), size.height.toFloat())
で直角にyへ150dp
移動しています。そこからまた、x=0のポジションから150dp
分ポイントをずらすことで、三角形の3点を定義しています。
そこから、drawPath
を用いて、3点の中身に色をつけているという流れになっています。
さらにここから、この三角形の半分のを別の色で塗りつぶそうとするとこんな感じのコードになります。
Canvas(modifier = Modifier
.width(300.dp)
.height(150.dp)
.padding(16.dp)
) {
val path = Path()
path.moveTo(size.width.toFloat(), 0f)
path.lineTo(size.width.toFloat(), size.height.toFloat())
path.lineTo(0f, size.height.toFloat())
clipPath(
path = path,
clipOp = ClipOp.Intersect
) {
drawPath(
path = path,
brush = SolidColor(Color.LightGray)
)
drawRect(
SolidColor(Color.Green),
size = Size(
0.5f * size.width,
size.height.toFloat()
)
)
}
}
ここでは、clipPath
メソッドを使用しています。
このメソッドを使用することで、path
の中身だけ色を塗りつぶすことができるようになります。
もし、clipPath
を使用しないと、こんな感じの見た目になります。
最後に
今回はCanvasを使用して簡単なカスタムグラフィックを作成してみました。
次からは、これにアニメーションをつけてさまざまなグラフィックを再現してみたいと思います。
参考