KotlinLeaner
04/19/2023, 12:59 PMOleksandr Balan
04/19/2023, 2:15 PMfun Modifier.pulse(
color: Color = Color.Magenta,
count: Int = 3,
duration: Int = 5_000,
easing: Easing = LinearEasing,
): Modifier = composed {
val transition = rememberInfiniteTransition()
val progress = List(count) {
transition.animateFloat(
initialValue = 0f,
targetValue = 1f,
animationSpec = InfiniteRepeatableSpec(
animation = tween(
durationMillis = duration,
easing = easing
),
initialStartOffset = StartOffset(it * duration / count),
repeatMode = RepeatMode.Restart,
)
)
}
drawBehind {
val radius = min(size.width, size.height) / 2f
progress.forEach {
drawCircle(
color = color.copy(alpha = 1f - it.value),
radius = radius * it.value
)
}
}
}
Usage:
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.size(100.dp)
.pulse()
) {
Icon(
imageVector = Icons.Default.AccountCircle,
contentDescription = null,
)
}
}
KotlinLeaner
04/19/2023, 2:32 PM3000
or 3_000
?Oleksandr Balan
04/19/2023, 2:33 PMKotlinLeaner
04/19/2023, 2:34 PMKotlinLeaner
04/19/2023, 2:34 PMKotlinLeaner
04/19/2023, 2:35 PMStartOffset(it * duration / count)
?Oleksandr Balan
04/19/2023, 2:37 PMit
refers to the index of item in the list and this formula is used to delay each “circle”. For example when duration is 3s and there are 3 circles the first one will have delay of 0ms (0 * 3_000 / 3
), the second circle will start its animation after 1s (1 * 3_000 / 3
) and the last one will start after 2s (2 * 3_000 / 3
)KotlinLeaner
04/19/2023, 2:40 PMOleksandr Balan
04/19/2023, 3:39 PMOffset(x = size.width / 2, y = size.height / 2)
with simple center
, it is a property provided in DrawScope
KotlinLeaner
04/19/2023, 3:47 PM