Skip to content

Instantly share code, notes, and snippets.

@victory316
Last active November 7, 2023 06:22
Show Gist options
  • Save victory316/83a849b8f18831b242f262b9c9a76b81 to your computer and use it in GitHub Desktop.
Save victory316/83a849b8f18831b242f262b9c9a76b81 to your computer and use it in GitHub Desktop.
Jetpack compose animation on touch sample.
@Composable
fun BounceAnimationOnTouch(
touchedPoint: Offset,
contentSize: Dp,
content: @Composable BoxScope.(modifier: Modifier) -> Unit,
) {
val isVisible = remember { mutableStateOf(false) }
val animatable = remember { Animatable(0f) }
val duration = 500
val boxSize = contentSize + 20.dp
val density = LocalDensity.current
val (xDp, yDp) = with(density) {
(touchedPoint.x.toDp() - contentSize / 2) to (touchedPoint.y.toDp() - contentSize / 2)
}
LaunchedEffect(touchedPoint) {
isVisible.value = true
animatable.stop()
animatable.snapTo(0f)
animatable.animateTo(
targetValue = contentSize.value,
animationSpec = tween(durationMillis = duration, easing = EaseOutElastic),
)
isVisible.value = animatable.isRunning
}
Box(
Modifier
.offset(xDp, yDp)
.size(boxSize),
) {
content.invoke(
this,
Modifier
.align(Alignment.Center)
.size(if (isVisible.value) animatable.value.dp else 0.dp)
)
}
}
var touchedPoint by remember { mutableStateOf(Offset.Zero) }
@Composable
fun SampleFullscreenBox() {
Box(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
if (event.type == PointerEventType.Press) {
touchedPoint = event.changes.first().position
}
}
}
}
) {
// ...
BounceAnimationOnTouch(
touchedPoint = touchedPoint,
contentSize = 38.dp,
content = { modifier ->
Image(
painter = painterResource(id = R.drawable.img_heart),
contentDescription = null,
modifier = modifier,
colorFilter = ColorFilter.tint(color = SysColor.PrimaryDefault)
)
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment