0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Compose のバーアニメーションで左端がずれる問題を直した

0
Posted at

はじめに

Compose でバーが左端から右に伸びるアニメーションを実装しようとしたところ、左端がずれる問題に遭遇したので、原因と解決方法を記事に残します。

問題

graphicsLayer { scaleX = progress } を使うと、デフォルトのスケール点が中央なので両端から縮む動きになり、左端が右にずれてしまう。

 // 中央からスケールされて左端がずれる
  Box(                                                                                                                                                                                         
      modifier = Modifier                                                                                                                                                                    
          .width(totalWidth)
          .graphicsLayer { scaleX = progress }                                                                                                                                                 
  )

原因

Compose の graphicsLayer にも transformOrigin パラメータがあるが、Canvas
で複数バーを描画している場合は個別に効かせにくい。
(iOS の SwiftUI には scaleEffect(anchor: .leading)でスケール点を左端に指定できる。)

解決策

Modifier でスケールするのをやめ、Canvas の drawRect で幅だけを progress に応じて変化させる。x(左端座標)は固定、w(幅)だけアニメーションするように。

val animProgress = remember(key) { Animatable(0f) }
LaunchedEffect(key) { animProgress.animateTo(1f, tween(400)) }                                                                                                                               
val progress = animProgress.value                                                                                                                                                          

Canvas(modifier = Modifier.fillMaxSize()) {
    val x = size.width * bar.startFraction      // 左端は固定
    val w = size.width * bar.widthFraction * progress  // 横幅だけ伸ばす                                                                                                                       
    drawRect(
        color = barColor,                                                                                                                                                                    
        topLeft = Offset(x, 0f),                                                                                                                                                           
        size = Size(w.coerceAtLeast(0f), size.height),                                                                                                                                       
    )
} 

Modifier のスケール系は原点が中央になるので、左端固定で伸ばしたいときは Canvas で幅を直接計算するほうがシンプル。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?