🙂
Jetpack Compose の Canvas でアニメーションするグラフをつくる
Jetpack ComposeでのCanvasを使った簡単なアニメーションするグラフを作ったメモです。
まだまだ勉強中なのでもっとスマートな書き方あったら教えて下さい👍
Jetpack ComposeでCanvasを利用する
Canvas(modifier = Modifier.fillMaxSize()){
drawRect(..)
drawArc(..)
}
Canvas
Composableファンクションが用意されているので他のComposableファンクションと同様に利用します。
第2引数にはDrawScope
が公開している描画エリアのサイズや描画用メソッドを描きたい図形に合わせて呼び出します。
棒グラフを描画してみる
ここから本題です。まずはCanvasで棒グラフを描画してみます。
drawRect()
を利用して棒グラフを描画します。このときグラフにアニメーションを付けたときに画面下から上にグラフが伸びるようにするためにsize
のy軸にマイナス値を指定し、画面上方向に描画されるようにしています(他に良い方法があるかも)。
@Composable
fun drawGraphSample(){
val sampleValues = listOf(300f, 500f, 700f)
Canvas(modifier = Modifier.fillMaxSize().padding(start = 32.dp, bottom = 32.dp)){
drawRect(
topLeft = Offset(0f, size.height),
color = Color.Red,
size = Size(200f, -sampleValues[0]),
)
drawRect(
topLeft = Offset(250f, size.height),
color = Color.Red,
size = Size(200f, -sampleValues[1]),
)
drawRect(
topLeft = Offset(500f, size.height),
color = Color.Red,
size = Size(200f, -sampleValues[2]),
)
}
}
棒グラフに簡単なアニメーションをつけてみる
下記のように値が0から1まで変化するanimateFloatAsState
用意し、棒グラフのy軸の描画に利用することでグラフの高さが0%から100%までアニメーションさせることができます。
公式ドキュメント
@Composable
fun drawGraphSample(){
val animationFlag = remember { mutableStateOf(false)}
val animateHeight by animateFloatAsState(if (animationFlag.value) 1f else 0f)
val sampleValues = listOf(300f, 500f, 700f)
Canvas(modifier = Modifier.fillMaxSize()){
animationFlag.value = true
drawRect(
topLeft = Offset(0f, size.height),
color = Color.Red,
size = Size(200f, animateHeight * -sampleValues[0]),
)
drawRect(
topLeft = Offset(250f, size.height),
color = Color.Red,
size = Size(200f, animateHeight * -sampleValues[1]),
)
drawRect(
topLeft = Offset(500f, size.height),
color = Color.Red,
size = Size(200f, animateHeight * -sampleValues[2]),
)
}
}
また、animationSpec
を指定することでアニメーションの仕様を変えることもできます。
val animateHeight by animateFloatAsState(
targetValue = if (animationFlag.value) 1f else 0f,
animationSpec = tween(durationMillis = 500, easing = FastOutSlowInEasing)
)
終わりに
Canvasも他のComposableファンクション同様にanimate*AsState
を利用することで簡単にアニメーションさせることができました。
他にもグラフの色や幅も同様にアニメーションさせることもできるので今後試していきたいです。
Discussion