この記事はレコチョク Advent Calendar 2022の14日目の記事となります。
はじめに
はじめまして、秦基博さんと日向坂46さんに日々癒しと元気をいただいている休井です。
株式会社レコチョクでAndroidの開発をしています。
最近はJetpack Composeを使用してUI作成をすることが多いのですが、何となく難しそうで触れてこなかったCanvas APIについて、実際に使ってみながらご紹介したいと思います。
Canvas APIについて
Androidでは、Jetpack ComposeというUIツールキットが提供されており、宣言的にUIを作成することができます。
CanvasはそのJetpack Composeに含まれるAPIで、画面内の位置(座標)を用いてレイアウトの設定を行うことができるので、かなり自由度高くカスタムレイアウトを作成することができます。
基本的な使い方
- 線を引く
drawLine()を使用します。
startとendで線の開始と終了を指定して線を引くことができます。@Composable fun DrawLine() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height drawLine( color = Color.Black, start = Offset.Zero, end = Offset(width, height), strokeWidth = 5F ) } }
四角形を描く
drawRect()を使用します。
topLeftで描画位置を決め、sizeで大きさを指定して四角形を描くことができます。@Composable fun DrawRect() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height drawRect( color = Color.Black, topLeft = Offset(width / 3, height / 3), size = Size(width / 3, height / 3) ) } } 角丸の四角形にしたい場合は、
drawRoundRect()を使いcornerRadiusに丸の半径を設定します。@Composable fun DrawRoundRect() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height drawRoundRect( color = Color.Black, topLeft = Offset(width / 3, height / 3), size = Size(width / 3, height / 3), cornerRadius = CornerRadius(x = 100F, y = 100F) ) } }
円を描く
drawCircle()を使用します。centerで描画位置を決め、radiusで半径を設定して円を描くことができます。@Composable fun DrawCircle() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height drawCircle( color = Color.Black, radius = 400F, center = Offset(width / 2, height / 2) ) } } また、楕円を描きたい場合は、
drawOval()を使用します。
topLeftで描画位置を決め、sizeで大きさを設定して楕円を描くことができます。@Composable fun DrawOval() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height drawOval( color = Color.Black, topLeft = Offset(width / 4, height / 3), size = Size(width = width / 2, height = height / 5) ) } }
弧を描く
drawArc()を使用します。
startAngleで開始位置(0Fが3時の方向)を決め、sweepAngleで弧の角度を設定して弧を描くことができます。
また、useCenterをtrueにすると、扇型に描画することができます。@Composable fun DrawArc() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width drawArc( color = Color.Black, startAngle = 0F, sweepAngle = 90F, useCenter = true, size = Size(width = width / 2, height = width / 2) ) drawArc( color = Color.Black, startAngle = 0F, sweepAngle = 90F, useCenter = false, size = Size(width = width / 2, height = width / 2), style = Stroke(width = 5F), topLeft = Offset(0F, width / 2) ) } }
点を描く
drawPoints()を使用します。
pointsで描きたい点の位置をリストで指定して点を描くことができます。
また、pointModeで描き方、capで点の形を設定できます。@Composable fun DrawPoints() { Canvas( modifier = Modifier .fillMaxSize() ) { val height = size.height drawPoints( points = listOf( Offset(300F, height / 2), Offset(500F, height / 2), Offset(700F, height / 2), Offset(900F, height / 2), Offset(1100F, height / 2), ), pointMode = PointMode.Points, color = Color.Black, strokeWidth = 50F, cap = StrokeCap.Square ) } }
パスを決めて描く
drawPath()を使用します。
pathを作成しdrawPath()に渡すことで、作成したpathに色を付けることができます。@Composable fun DrawPath() { Canvas( modifier = Modifier .fillMaxSize() ) { val width = size.width val height = size.height val path = Path() path.moveTo(width / 2, height / 3) // pathの開始位置 path.lineTo(width / 2, height / 2) // 開始位置→(width / 2, height / 2) path.lineTo(width, height / 3) // (width / 2, height / 2)→(width, height / 3) drawPath( path = path, color = Color.Black ) } }
使ってみた
Canvasでできることと使い方の基本について確認できたので、単純なアナログ時計のレイアウトを描いてみました。
chiaki.kyui