Skip to content

Kyant0/Capsule

Repository files navigation

Capsule

Capsule is a Jetpack Compose library that creates G2 continuous rounded corner shapes.

Comparison of G2 continuous corner and G1 continuous corner

The black one is the G2 continuous corner. The red one is the normal G1 continuous corner.

Screenshot of the playground app

Installation

JitPack Release

// settings.gradle.kts in root project
dependencyResolutionManagement {
    repositories {
        maven("https://jitpack.io")
    }
}

// build.gradle.kts in module
implementation("com.github.Kyant0:Capsule:<version>")

Usages

Replace the RoundedCornerShape with G2RoundedCornerShape or CapsuleShape:

// create a basic rounded corner shape
G2RoundedCornerShape(16.dp)

// create a capsule shape
CapsuleShape

// create a rectangle shape
G2RectangleShape

Custom corner smoothness:

// default corner smoothness, which looks similar to the Apple's
val defaultCornerSmoothness = CornerSmoothness.Default

// custom corner smoothness
val cornerSmoothness = CornerSmoothness(
    circleFraction = 0.181f,
    extendedFraction = 0.75f
)

// create shapes with a custom corner smoothness
G2RoundedCornerShape(16.dp, cornerSmoothness = cornerSmoothness)
CapsuleShape(cornerSmoothness = cornerSmoothness)

Performance

Drawing cubic Bézier curves on Android performs poorly. However, the Capsule library uses a very efficient method to calculate the control points, achieving optimal theoretical performance.

When the shape area is large (almost fullscreen) and the corner radius is constantly changing, performance may decrease. Use animatedShape.copy(cornerSmoothness = CornerSmoothness.None) to temporarily disable corner smoothing during the animation.

How it works

Each corner consists of a part of circle (C) and two cubic Bézier curves (B) that connect the circle to the straight edges (L) of the rectangle.

The proportion of the circular section is defined by the circleFraction (f_c) and the extended length relative to the corner radius (R) is defined by the extendedFraction (f_e) in CornerSmoothness class.

Schematic

It uses mathematical calculations to determine the control points of the cubic Bézier curves to achieve G2 continuity.

Comparison with other implementations

Property Capsule androidx Compose Apple
Continuity G2 G1 (~G2) G1 ~G3
Curvature Non-monotonic Monotonic Discontinuous ~Monotonic
Curvature graph Capsule curvature graph androidx curvature graph - Apple curvature graph
Graph note green: B, blue: C red: B, blue: C - last green: C

androidx refers to the RoundedPolygon.Companion.rectangle in androidx.graphics.shapes package.

The implementation in Figma is similar to the androidx one.