Skip to content

Instantly share code, notes, and snippets.

@Mikkareem
Created October 30, 2023 11:01
Show Gist options
  • Save Mikkareem/1731bc3e33583fdb9f01c6e363a75594 to your computer and use it in GitHub Desktop.
Save Mikkareem/1731bc3e33583fdb9f01c6e363a75594 to your computer and use it in GitHub Desktop.
Animated Go Button Without Rotation in Jetpack Compose
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
@Composable
private fun AnimatedGoButton(
modifier: Modifier = Modifier.size(24.dp),
strokeWidth: Dp = 3.dp,
color: Color = Color.Red,
onClick: () -> Unit = {}
) {
val canRotate = false
val animationProgress = remember { Animatable(0f) }
LaunchedEffect(key1 = Unit) {
animationProgress.animateTo(
targetValue = 1f,
animationSpec = tween(durationMillis = 1200)
)
}
Canvas(
modifier = modifier
.padding(strokeWidth)
.clickable(onClick = onClick)
) {
drawArc(
color = color,
startAngle = 0f,
sweepAngle = 359.99f * animationProgress.value,
useCenter = false,
style = Stroke(width = strokeWidth.toPx())
)
val path = Path().apply {
moveTo(size.width * .25f, center.y)
lineTo(size.width * .75f, center.y)
lineTo(size.width * .55f, size.height * .35f)
moveTo(size.width * .75f, center.y)
lineTo(size.width * .55f, size.height * .65f)
}
scale(
scale = animationProgress.value,
pivot = Offset(size.width * .25f, center.y)
) {
rotate(if(canRotate) 360f * animationProgress.value else 0f) {
drawPath(
path = path,
color = color.copy(alpha = animationProgress.value),
style = Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Round, join = StrokeJoin.Round)
)
}
}
}
}
@Preview
@Composable
fun AnimatedGoButtonPreview() {
var count by remember {
mutableIntStateOf(0)
}
LaunchedEffect(key1 = Unit) {
while (count < 100) {
count++
if(count % 2 == 0) {
delay(1000)
} else {
delay(3000)
}
}
}
Box(modifier = Modifier
.size(400.dp)
.background(Color.White)) {
if(count % 2 != 0) {
AnimatedGoButton(
modifier = Modifier.fillMaxSize()
)
}
}
}
@Mikkareem
Copy link
Author

AnimatedGoButtonWithoutRotation.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment