参照图和效果图
网上搜的参照图:
最终效果图:
代码实现
@Composable
fun RadarSearchAnimation(
modifier: Modifier = Modifier.fillMaxSize(),
color: Color = Color.Green,
strokeWidth: Float = 10f,
) {
//循环动画
val trans = rememberInfiniteTransition()
val point by trans.animateFloat(
initialValue = 0f,
targetValue = 1.0f,
animationSpec = infiniteRepeatable(
tween(5000, 0, LinearEasing),
repeatMode = RepeatMode.Restart,
)
)
Canvas(modifier = modifier) {
val realSize = min(size.width, size.height)
//三个圆圈
drawCircle(color, realSize / 6, style = Stroke(strokeWidth))
drawCircle(color, realSize * 2 / 6, style = Stroke(strokeWidth))
drawCircle(color, realSize / 2, style = Stroke(strokeWidth))
//十字坐标系
drawLine(
color,
Offset(size.width / 2, (size.height - realSize) / 2),
Offset(size.width / 2, (size.height + realSize) / 2),
strokeWidth = strokeWidth
)
drawLine(
color,
Offset((size.width - realSize) / 2, size.height / 2),
Offset((size.width + realSize) / 2, size.height / 2),
strokeWidth = strokeWidth
)
//扫描视图
drawCircle(
Brush.sweepGradient(
point - 0.05f to Color.Transparent,
point to Color.Green,
point + 0.01f to Color.Transparent
),
realSize / 2,
)
}
}
改进优化
上面这么实现扫描动画会发现,在转完一圈与下一圈交接的地方会有一点不太自然,虽然几乎看不太出来,但是为了追求完美,可以用算法去修复,,也可以换一种更简单的方式来解决这个问题
把扫描动画改为单独旋转:
@Composable
fun RadarSearchAnimation(
modifier: Modifier = Modifier.fillMaxSize(),
color: Color = Color.Green,
strokeWidth: Float = 10f,
) {
//循环动画
val trans = rememberInfiniteTransition()
val rote by trans.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(
tween(5000, 0, LinearEasing),
repeatMode = RepeatMode.Restart,
)
)
Box {
Canvas(modifier = modifier) {
val realSize = min(size.width, size.height)
//三个圆圈
drawCircle(color, realSize / 6, style = Stroke(strokeWidth))
drawCircle(color, realSize * 2 / 6, style = Stroke(strokeWidth))
drawCircle(color, realSize / 2, style = Stroke(strokeWidth))
//十字坐标系
drawLine(
color,
Offset(size.width / 2, (size.height - realSize) / 2),
Offset(size.width / 2, (size.height + realSize) / 2),
strokeWidth = strokeWidth
)
drawLine(
color,
Offset((size.width - realSize) / 2, size.height / 2),
Offset((size.width + realSize) / 2, size.height / 2),
strokeWidth = strokeWidth
)
}
Canvas(modifier = modifier.rotate(rote)) {
val realSize = min(size.width, size.height)
//扫描视图
drawCircle(
Brush.sweepGradient(
0f to Color.Transparent,
0.05f to Color.Green,
0.051f to Color.Transparent
),
realSize / 2,
)
}
}
}
OK,最终效果完美了