Animate scrolling a wide image horizontally that goes out of screen in compose

Viewed 112

I am trying to implement a scrolling image that is much wider then device's screen. See example:

example

Right now I implemented it using Row with horizontalScroll modifier, and calling scrollState.animateScrollTo

I do not like this implementation since I need this animation to go back and forth if the image reaches it's end, and scrolling it using animateScrollTo results in ugly code (need to call it in a loop to reverse when it's do) and it's not completely smooth for some reason.

        while (true) {
            animationPositions.forEach {
                if ((scrollState.maxValue * it).toInt() != scrollState.value) {
                    scrollState.animateScrollTo(
                        (scrollState.maxValue * it).toInt(),
                        animationSpec = tween(
                            cycleDurationMillis / animationPositions.size,
                            easing = LinearEasing
                        )
                    )
                }
            }
        }

Is there a way to do this in cleaner way? I was thinking about simple offset/translationX usage, but the image is clipped on the sides because of parent container (e.g. if I just put in a column and try to move it with offset).

Is there a way to not clip the image if it's too large to fit?

Thanks

1 Answers

// Min and Max possible states
val minima = ...
val maxima = ...

val value by rememberInfiniteTransition().animateInt(
  initialValue = minima,
  targetValue = maxima,
  animationSpec = infiniteRepeatable(
    animation = tween(
                  cycleDurationMillis / animationPositions.size,
                  easing = LinearEasing
      )
    ),
    repeatMode = RepeatMode.Restart
)

scrollState.scrollTo(value) // Do not use animateScrollState here, that's already taken care of
Related