Badges
Badgesanimated

Verified draw

A verified badge whose ring and checkmark draw themselves stroke by stroke.

Verified

Installation

caveui components are copy-paste Jetpack Compose built entirely on Material 3 — there's no caveui dependency to add. Make sure Material 3 is on your classpath (it ships with the Compose BOM), then copy the Usage snippet below into your project.

kotlin
// build.gradle.kts (module)
dependencies {
    implementation(platform("androidx.compose:compose-bom:2025.06.00"))
    implementation("androidx.compose.material3:material3")
}

Usage

kotlin
var done by remember { mutableStateOf(false) }
LaunchedEffect(Unit) { done = true }
val p by animateFloatAsState(
    targetValue = if (done) 1f else 0f,
    animationSpec = tween(800, easing = EaseOutCubic),
    label = "draw",
)
val sky = Color(0xFF0EA5E9)
Row(
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.spacedBy(6.dp),
) {
    Canvas(Modifier.size(18.dp)) {
        val s = Stroke(2.dp.toPx(), cap = StrokeCap.Round, join = StrokeJoin.Round)
        drawArc(
            color = sky,
            startAngle = -90f,
            sweepAngle = 360f * (p / 0.6f).coerceIn(0f, 1f),
            useCenter = false,
            style = s,
        )
        val tick = Path().apply {
            moveTo(size.width * 0.28f, size.height * 0.52f)
            lineTo(size.width * 0.44f, size.height * 0.68f)
            lineTo(size.width * 0.74f, size.height * 0.34f)
        }
        val m = PathMeasure().apply { setPath(tick, false) }
        val tp = ((p - 0.4f) / 0.6f).coerceIn(0f, 1f)
        drawPath(
            Path().also { m.getSegment(0f, m.length * tp, it, true) },
            color = sky,
            style = s,
        )
    }
    Text("Verified", color = sky, fontWeight = FontWeight.SemiBold, fontSize = 13.sp)
}