Skip to content

Instantly share code, notes, and snippets.

@IlyaGulya
Last active December 10, 2021 12:25
Show Gist options
  • Save IlyaGulya/92ed2d8deb1021b53c7b38f0784661bd to your computer and use it in GitHub Desktop.
Save IlyaGulya/92ed2d8deb1021b53c7b38f0784661bd to your computer and use it in GitHub Desktop.
Animated image example
@JvmInline
value class ImageId(val id: String)
@Preview
@Composable
fun Test() {
val images = emptyList<ImageId>()
var animatingImageId by remember {
mutableStateOf<ImageId?>(null)
}
val pendingAnimation = remember {
Animatable(0f)
}
val animationRequests = Channel<ImageId>(Channel.CONFLATED)
LaunchedEffect(animationRequests) {
for (request in animationRequests) {
animatingImageId = request
pendingAnimation.animateTo(1f)
}
}
val imagePositions = remember {
mutableStateMapOf<ImageId, Offset>()
}
var cartButtonPosition by remember {
mutableStateOf(Offset.Unspecified)
}
Box {
LazyColumn {
items(images, key = { it }) { imageId ->
Image(
modifier = Modifier
.size(56.dp)
.onGloballyPositioned { coordinates ->
imagePositions[imageId] = coordinates.positionInWindow()
}
.clickable {
animationRequests.trySend(imageId)
},
painter = painterResource(id = R.drawable.bg_rounded_grey_stroke_rect),
contentDescription = null,
)
}
}
Button(
modifier = Modifier
.onGloballyPositioned { coordinates ->
cartButtonPosition = coordinates.positionInWindow()
},
onClick = { /*navigate to cart*/ },
) {
Text("Корзина")
}
val animatingImage = animatingImageId
if (animatingImage != null) {
Image(
modifier = Modifier
.size(56.dp)
.absoluteOffset {
val imagePosition = imagePositions.getValue(animatingImage)
val difference = cartButtonPosition - imagePosition
val animatedDifference = difference * pendingAnimation.value
val animatedOffset = imagePosition + animatedDifference
animatedOffset.round()
},
painter = painterResource(id = R.drawable.bg_rounded_grey_stroke_rect),
contentDescription = null,
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment