I want to make an animated circle in Jetpack compose to be animated as in the GIF. I couldn’t do it the way I wanted. The code block is below.
- Colors and lighting effects are unimportant
<code> val transition = rememberInfiniteTransition()
val scale = transition.animateFloat(
initialValue = 1.9f,
targetValue = if(isAnimating) 2.05f else 1.9f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = FastOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
val deformFactor = transition.animateFloat(
initialValue = 0f,
targetValue = if(isAnimating) randomFloatInRange(0.1f, 0.2f) else 0f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = LinearOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
Canvas(modifier = Modifier
.fillMaxSize()) {
val center = Offset(size.width / 2, size.height / 2)
val radius = 100f * scale.value
val path = Path()
path.moveTo(center.x + radius * (1 - deformFactor.value), center.y)
for (angle in 0..360 step 10) {
val rad = Math.toRadians(angle.toDouble())
val x = center.x + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.cos(rad)
val y = center.y + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.sin(rad)
path.lineTo(x.toFloat(), y.toFloat())
}
path.close()
drawPath(path, color.value)
}
</code>
<code> val transition = rememberInfiniteTransition()
val scale = transition.animateFloat(
initialValue = 1.9f,
targetValue = if(isAnimating) 2.05f else 1.9f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = FastOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
val deformFactor = transition.animateFloat(
initialValue = 0f,
targetValue = if(isAnimating) randomFloatInRange(0.1f, 0.2f) else 0f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = LinearOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
Canvas(modifier = Modifier
.fillMaxSize()) {
val center = Offset(size.width / 2, size.height / 2)
val radius = 100f * scale.value
val path = Path()
path.moveTo(center.x + radius * (1 - deformFactor.value), center.y)
for (angle in 0..360 step 10) {
val rad = Math.toRadians(angle.toDouble())
val x = center.x + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.cos(rad)
val y = center.y + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.sin(rad)
path.lineTo(x.toFloat(), y.toFloat())
}
path.close()
drawPath(path, color.value)
}
</code>
val transition = rememberInfiniteTransition()
val scale = transition.animateFloat(
initialValue = 1.9f,
targetValue = if(isAnimating) 2.05f else 1.9f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = FastOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
val deformFactor = transition.animateFloat(
initialValue = 0f,
targetValue = if(isAnimating) randomFloatInRange(0.1f, 0.2f) else 0f,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 1000, easing = LinearOutSlowInEasing),
repeatMode = RepeatMode.Reverse
)
)
Canvas(modifier = Modifier
.fillMaxSize()) {
val center = Offset(size.width / 2, size.height / 2)
val radius = 100f * scale.value
val path = Path()
path.moveTo(center.x + radius * (1 - deformFactor.value), center.y)
for (angle in 0..360 step 10) {
val rad = Math.toRadians(angle.toDouble())
val x = center.x + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.cos(rad)
val y = center.y + radius * (1 + deformFactor.value * Math.sin(rad * 5)) * Math.sin(rad)
path.lineTo(x.toFloat(), y.toFloat())
}
path.close()
drawPath(path, color.value)
}
New contributor
Hahw Jdjd is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2