使用 ShakeTransition
自定义动画实现震动效果。
示例代码如下:
@Composable
fun ShakeTransition(targetValue: Dp, onAnimationFinish: () -> Unit, content: @Composable () -> Unit) {
val shakeAnim = rememberInfiniteTransition()
val offsetX by shakeAnim.animateValue(
initialValue = 0.dp,
targetValue = targetValue,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 100,
easing = LinearEasing
),
repeatMode = RepeatMode.Reverse
)
)
LaunchedEffect(offsetX) {
if (offsetX == targetValue) {
onAnimationFinish()
}
}
content(offsetX = offsetX)
}
@Composable
fun ShakeAnimation(modifier: Modifier = Modifier, onAnimationFinish: () -> Unit) {
Box(
modifier = modifier
.graphicsLayer {
shakeAnimation(offsetX)
}
) {
// add your content here
}
}
private fun GraphicsLayerScope.shakeAnimation(offsetX: Dp) {
val angle = offsetX.value * 10
val radians = Math.toRadians(angle)
val translationX = offsetX.value * 5
val translationY = sin(radians) * 20
val rotationZ = if (offsetX > 0.dp) angle else -angle
this.translationX = translationX.toPx()
this.translationY = translationY.toPx()
this.rotationZ = rotationZ
}
使用方式如下:
ShakeTransition(
targetValue = 10.dp,
onAnimationFinish = { /* onAnimationFinish callback */ }
) { offsetX ->
ShakeAnimation(modifier = Modifier.offset(x = offsetX)) {
// add your content here
}
}