androidx.compose.foundation.shape

Interfaces

CornerSize

Defines size of a corner in pixels.

Cmn
PolygonShapeScope

Receiver scope for the PolygonShape builder lambda.

Cmn

Classes

AbsoluteCutCornerShape

A shape describing the rectangle with cut corners.

Cmn
AbsoluteRoundedCornerShape

A shape describing the rectangle with rounded corners.

Cmn
CornerBasedShape

Base class for Shapes defined by four CornerSizes.

Cmn
CutCornerShape

A shape describing the rectangle with cut corners.

Cmn
GenericShape

Creates Shape defined by applying the provided builder on a Path.

Cmn
PolygonShape

Shape built from rounded polygon geometry.

Cmn
PolygonShapeGeometry

Geometry describing a polygon's vertices, center, and rounding.

Cmn
PolygonShapeGeometry.CornerRounding

Amount and quality of rounding around a polygon vertex.

Cmn
RoundedCornerShape

A shape describing the rectangle with rounded corners.

Cmn

Top-level functions summary

AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Cmn
AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Cmn
AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Cmn
AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Cmn
AbsoluteCutCornerShape
AbsoluteCutCornerShape(
    topLeft: Dp,
    topRight: Dp,
    bottomRight: Dp,
    bottomLeft: Dp
)

Creates AbsoluteCutCornerShape with sizes defined in Dp.

Cmn
AbsoluteCutCornerShape
AbsoluteCutCornerShape(
    topLeft: Float,
    topRight: Float,
    bottomRight: Float,
    bottomLeft: Float
)

Creates AbsoluteCutCornerShape with sizes defined in float.

Cmn
AbsoluteCutCornerShape
AbsoluteCutCornerShape(
    topLeftPercent: @IntRange(from = 0, to = 100) Int,
    topRightPercent: @IntRange(from = 0, to = 100) Int,
    bottomRightPercent: @IntRange(from = 0, to = 100) Int,
    bottomLeftPercent: @IntRange(from = 0, to = 100) Int
)

Creates AbsoluteCutCornerShape with sizes defined in percents of the shape's smaller side.

Cmn
AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Cmn
AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Cmn
AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Cmn
AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Cmn
AbsoluteRoundedCornerShape
AbsoluteRoundedCornerShape(
    topLeft: Dp,
    topRight: Dp,
    bottomRight: Dp,
    bottomLeft: Dp
)

Creates AbsoluteRoundedCornerShape with sizes defined in Dp.

Cmn
AbsoluteRoundedCornerShape
AbsoluteRoundedCornerShape(
    topLeft: Float,
    topRight: Float,
    bottomRight: Float,
    bottomLeft: Float
)

Creates AbsoluteRoundedCornerShape with sizes defined in pixels.

Cmn
AbsoluteRoundedCornerShape
AbsoluteRoundedCornerShape(
    topLeftPercent: @IntRange(from = 0, to = 100) Int,
    topRightPercent: @IntRange(from = 0, to = 100) Int,
    bottomRightPercent: @IntRange(from = 0, to = 100) Int,
    bottomLeftPercent: @IntRange(from = 0, to = 100) Int
)

Creates AbsoluteRoundedCornerShape with sizes defined in percents of the shape's smaller side.

Cmn
CornerSize
CornerSize(percent: @IntRange(from = 0, to = 100) Int)

Creates CornerSize with provided size.

Cmn
CornerSize
CornerSize(size: Dp)

Creates CornerSize with provided size.

Cmn
CornerSize

Creates CornerSize with provided size.

Cmn
CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Cmn
CutCornerShape
CutCornerShape(percent: Int)

Creates CutCornerShape with the same size applied for all four corners.

Cmn
CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Cmn
CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Cmn
CutCornerShape
CutCornerShape(topStart: Dp, topEnd: Dp, bottomEnd: Dp, bottomStart: Dp)

Creates CutCornerShape with sizes defined in Dp.

Cmn
CutCornerShape
CutCornerShape(
    topStart: Float,
    topEnd: Float,
    bottomEnd: Float,
    bottomStart: Float
)

Creates CutCornerShape with sizes defined in float.

Cmn
CutCornerShape
CutCornerShape(
    topStartPercent: @IntRange(from = 0, to = 100) Int,
    topEndPercent: @IntRange(from = 0, to = 100) Int,
    bottomEndPercent: @IntRange(from = 0, to = 100) Int,
    bottomStartPercent: @IntRange(from = 0, to = 100) Int
)

Creates CutCornerShape with sizes defined in percents of the shape's smaller side.

Cmn
Shape
@RememberInComposition
MorphPolygonShape(
    start: PolygonShape,
    end: PolygonShape,
    progress: () -> Float
)

Creates a Shape that morphs between start and end as progress moves from 0f to 1f.

Cmn
PolygonShape

Creates a PolygonShape whose geometry is defined by builder at layout resolution time.

Cmn
PolygonShape

Creates a PolygonShape from geometry defined in an author-chosen coordinate space.

Cmn
RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Cmn
RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Cmn
RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Cmn
RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Cmn
RoundedCornerShape
RoundedCornerShape(topStart: Dp, topEnd: Dp, bottomEnd: Dp, bottomStart: Dp)

Creates RoundedCornerShape with sizes defined in Dp.

Cmn
RoundedCornerShape
RoundedCornerShape(
    topStart: Float,
    topEnd: Float,
    bottomEnd: Float,
    bottomStart: Float
)

Creates RoundedCornerShape with sizes defined in pixels.

Cmn
RoundedCornerShape
RoundedCornerShape(
    topStartPercent: @IntRange(from = 0, to = 100) Int,
    topEndPercent: @IntRange(from = 0, to = 100) Int,
    bottomEndPercent: @IntRange(from = 0, to = 100) Int,
    bottomStartPercent: @IntRange(from = 0, to = 100) Int
)

Creates RoundedCornerShape with sizes defined in percents of the shape's smaller side.

Cmn

Extension functions summary

PolygonShape
@RememberInComposition
PolygonShape.scaledToFit(
    contentScale: ContentScale,
    alignment: Alignment
)

Returns a new PolygonShape scaled and aligned into the layout bounds.

Cmn
PolygonShape

Converts a RoundedCornerShape to a PolygonShape.

Cmn
PolygonShape

Converts an AbsoluteRoundedCornerShape to a PolygonShape.

Cmn
PolygonShape

Converts a CutCornerShape to a PolygonShape.

Cmn
PolygonShape

Converts an AbsoluteCutCornerShape to a PolygonShape.

Cmn
PolygonShape
@RememberInComposition
PolygonShape.transformed(
    matrix: Matrix,
    contentScale: ContentScale?,
    alignment: Alignment
)

Returns a new PolygonShape with matrix applied to the underlying geometry.

Cmn
PolygonShape
@RememberInComposition
PolygonShape.transformed(
    rotation: Float,
    translation: Offset,
    contentScale: ContentScale?,
    alignment: Alignment
)

Returns a new PolygonShape with rotation and translation applied to the underlying geometry.

Cmn

Top-level properties summary

RoundedCornerShape

Circular Shape with all the corners sized as the 50 percent of the shape size.

Cmn
CornerSize

CornerSize always equals to zero.

Cmn

Top-level functions

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(corner: CornerSize): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Parameters
corner: CornerSize

CornerSize to apply.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(percent: Int): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Parameters
percent: Int

Size in percents to apply.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(size: Dp): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Parameters
size: Dp

Size in Dp to apply.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(size: Float): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with the same size applied for all four corners.

Parameters
size: Float

Size in pixels to apply.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(
    topLeft: Dp = 0.dp,
    topRight: Dp = 0.dp,
    bottomRight: Dp = 0.dp,
    bottomLeft: Dp = 0.dp
): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with sizes defined in Dp.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(
    topLeft: Float = 0.0f,
    topRight: Float = 0.0f,
    bottomRight: Float = 0.0f,
    bottomLeft: Float = 0.0f
): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with sizes defined in float.

AbsoluteCutCornerShape

fun AbsoluteCutCornerShape(
    topLeftPercent: @IntRange(from = 0, to = 100) Int = 0,
    topRightPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomRightPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomLeftPercent: @IntRange(from = 0, to = 100) Int = 0
): AbsoluteCutCornerShape

Creates AbsoluteCutCornerShape with sizes defined in percents of the shape's smaller side.

Parameters
topLeftPercent: @IntRange(from = 0, to = 100) Int = 0

The top left corner clip size as a percentage of the smaller side, with a range of 0 - 100.

topRightPercent: @IntRange(from = 0, to = 100) Int = 0

The top right corner clip size as a percentage of the smaller side, with a range of 0 - 100.

bottomRightPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom right clip size radius as a percentage of the smaller side, with a range of 0 - 100.

bottomLeftPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom left clip size radius as a percentage of the smaller side, with a range of 0 - 100.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(corner: CornerSize): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Parameters
corner: CornerSize

CornerSize to apply.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(percent: Int): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Parameters
percent: Int

Size in percents to apply.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(size: Dp): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Parameters
size: Dp

Size in Dp to apply.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(size: Float): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with the same size applied for all four corners.

Parameters
size: Float

Size in pixels to apply.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(
    topLeft: Dp = 0.dp,
    topRight: Dp = 0.dp,
    bottomRight: Dp = 0.dp,
    bottomLeft: Dp = 0.dp
): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with sizes defined in Dp.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(
    topLeft: Float = 0.0f,
    topRight: Float = 0.0f,
    bottomRight: Float = 0.0f,
    bottomLeft: Float = 0.0f
): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with sizes defined in pixels.

AbsoluteRoundedCornerShape

fun AbsoluteRoundedCornerShape(
    topLeftPercent: @IntRange(from = 0, to = 100) Int = 0,
    topRightPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomRightPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomLeftPercent: @IntRange(from = 0, to = 100) Int = 0
): AbsoluteRoundedCornerShape

Creates AbsoluteRoundedCornerShape with sizes defined in percents of the shape's smaller side.

Parameters
topLeftPercent: @IntRange(from = 0, to = 100) Int = 0

The top left corner radius as a percentage of the smaller side, with a range of 0 - 100.

topRightPercent: @IntRange(from = 0, to = 100) Int = 0

The top right corner radius as a percentage of the smaller side, with a range of 0 - 100.

bottomRightPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom right corner radius as a percentage of the smaller side, with a range of 0 - 100.

bottomLeftPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom left corner radius as a percentage of the smaller side, with a range of 0 - 100.

CornerSize

fun CornerSize(percent: @IntRange(from = 0, to = 100) Int): CornerSize

Creates CornerSize with provided size.

Parameters
percent: @IntRange(from = 0, to = 100) Int

the corner size defined in percents of the shape's smaller side. Can't be negative or larger then 100 percents.

CornerSize

fun CornerSize(size: Dp): CornerSize

Creates CornerSize with provided size.

Parameters
size: Dp

the corner size defined in Dp.

CornerSize

fun CornerSize(size: Float): CornerSize

Creates CornerSize with provided size.

Parameters
size: Float

the corner size defined in pixels.

CutCornerShape

fun CutCornerShape(corner: CornerSize): CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Parameters
corner: CornerSize

CornerSize to apply.

CutCornerShape

fun CutCornerShape(percent: Int): CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Parameters
percent: Int

Size in percents to apply.

CutCornerShape

fun CutCornerShape(size: Dp): CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Parameters
size: Dp

Size in Dp to apply.

CutCornerShape

fun CutCornerShape(size: Float): CutCornerShape

Creates CutCornerShape with the same size applied for all four corners.

Parameters
size: Float

Size in pixels to apply.

CutCornerShape

fun CutCornerShape(
    topStart: Dp = 0.dp,
    topEnd: Dp = 0.dp,
    bottomEnd: Dp = 0.dp,
    bottomStart: Dp = 0.dp
): CutCornerShape

Creates CutCornerShape with sizes defined in Dp.

CutCornerShape

fun CutCornerShape(
    topStart: Float = 0.0f,
    topEnd: Float = 0.0f,
    bottomEnd: Float = 0.0f,
    bottomStart: Float = 0.0f
): CutCornerShape

Creates CutCornerShape with sizes defined in float.

CutCornerShape

fun CutCornerShape(
    topStartPercent: @IntRange(from = 0, to = 100) Int = 0,
    topEndPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomEndPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomStartPercent: @IntRange(from = 0, to = 100) Int = 0
): CutCornerShape

Creates CutCornerShape with sizes defined in percents of the shape's smaller side.

Parameters
topStartPercent: @IntRange(from = 0, to = 100) Int = 0

The top start corner clip size as a percentage of the smaller side, with a range of 0 - 100.

topEndPercent: @IntRange(from = 0, to = 100) Int = 0

The top end corner clip size as a percentage of the smaller side, with a range of 0 - 100.

bottomEndPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom end clip size radius as a percentage of the smaller side, with a range of 0 - 100.

bottomStartPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom start clip size radius as a percentage of the smaller side, with a range of 0 - 100.

MorphPolygonShape

@RememberInComposition
fun MorphPolygonShape(
    start: PolygonShape,
    end: PolygonShape,
    progress: () -> Float
): Shape

Creates a Shape that morphs between start and end as progress moves from 0f to 1f.

Reads progress each time the outline is resolved. Values at or below 0f resolve to start; values at or above 1f resolve to end. Create a separate instance for each morphing element. Two shapes created with equal endpoints and the same progress instance compare equal.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.MorphPolygonShape
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// A badge that morphs between a rounded hexagon and a star as it is toggled. No remember
// keys are needed: the endpoints are constant and the current progress is read through the
// lambda each time the outline is resolved.
var selected by remember { mutableStateOf(false) }
val progress by animateFloatAsState(if (selected) 1f else 0f)
val shape = remember {
    MorphPolygonShape(
        start =
            PolygonShape { polygon(numVertices = 6, rounding = CornerRounding(percent = 20)) },
        end =
            PolygonShape.star(
                numPoints = 6,
                innerRadiusRatio = 0.6f,
                outerRounding = CornerRounding(percent = 20),
            ),
        progress = { progress },
    )
}
Box(
    Modifier.size(96.dp).clip(shape).background(Color(0xFF4CAF50)).clickable {
        selected = !selected
    }
)
Parameters
start: PolygonShape

starting shape of the morph

end: PolygonShape

ending shape of the morph

progress: () -> Float

returns the current morph progress

@RememberInComposition
fun PolygonShape(builder: PolygonShapeScope.() -> PolygonShapeGeometry): PolygonShape

Creates a PolygonShape whose geometry is defined by builder at layout resolution time.

builder runs in PolygonShapeScope on every resolution, with access to the resolved size, layout direction, and density; the PolygonShapeGeometry it returns is the shape's definition. Values the lambda reads are re-read on each resolution, and the outline rebuilds when the resulting geometry changes. Two shapes created with the same builder instance compare equal.

Use this overload when the geometry depends on the resolved size or density, such as vertices placed in pixels of the layout's coordinate space or rounding given in Dp. For a fixed geometry that scales uniformly into any container, use the PolygonShape overload taking a PolygonShapeGeometry.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// A diamond built from pixel coordinates derived from the resolved layout size, with an
// exact 8dp corner rounding.
val diamond = remember {
    PolygonShape {
        polygon(
            vertices =
                listOf(
                    Offset(size.width / 2f, 0f),
                    Offset(size.width, size.height / 2f),
                    Offset(size.width / 2f, size.height),
                    Offset(0f, size.height / 2f),
                ),
            rounding = CornerRounding(radius = 8.dp),
        )
    }
}
Box(Modifier.size(96.dp).clip(diamond).background(Color(0xFFFF5722)))
Parameters
builder: PolygonShapeScope.() -> PolygonShapeGeometry

lambda run in PolygonShapeScope returning the shape's geometry

@RememberInComposition
fun PolygonShape(geometry: PolygonShapeGeometry): PolygonShape

Creates a PolygonShape from geometry defined in an author-chosen coordinate space.

The geometry is uniformly scaled and centered to fit within the layout bounds at resolution time, preserving its aspect ratio.

Use this overload for a fixed shape definition, such as unit-space vertices, that scales into whatever bounds the shape is used in. To define geometry against the resolved size, layout direction, or density instead, use the PolygonShape overload taking a PolygonShapeScope builder.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// A kite authored in the unit square [0..1] with per-vertex rounding in the same coordinate
// space. The shape scales and centers into any container preserving its aspect ratio.
val kite = remember {
    PolygonShape(
        PolygonShapeGeometry(
            vertices =
                listOf(Offset(0.5f, 0f), Offset(1f, 0.4f), Offset(0.5f, 1f), Offset(0f, 0.4f)),
            perVertexRounding =
                listOf(
                    CornerRounding(0.1f),
                    CornerRounding(0.15f),
                    CornerRounding(0.05f),
                    CornerRounding(0.15f),
                ),
        )
    )
}

Box(Modifier.size(width = 120.dp, height = 84.dp).clip(kite).background(Color(0xFF673AB7)))
Parameters
geometry: PolygonShapeGeometry

polygon geometry to scale and center into the layout bounds

RoundedCornerShape

fun RoundedCornerShape(corner: CornerSize): RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Parameters
corner: CornerSize

CornerSize to apply.

RoundedCornerShape

fun RoundedCornerShape(percent: Int): RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Parameters
percent: Int

Size in percents to apply.

RoundedCornerShape

fun RoundedCornerShape(size: Dp): RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Parameters
size: Dp

Size in Dp to apply.

RoundedCornerShape

fun RoundedCornerShape(size: Float): RoundedCornerShape

Creates RoundedCornerShape with the same size applied for all four corners.

Parameters
size: Float

Size in pixels to apply.

RoundedCornerShape

fun RoundedCornerShape(
    topStart: Dp = 0.dp,
    topEnd: Dp = 0.dp,
    bottomEnd: Dp = 0.dp,
    bottomStart: Dp = 0.dp
): RoundedCornerShape

Creates RoundedCornerShape with sizes defined in Dp.

RoundedCornerShape

fun RoundedCornerShape(
    topStart: Float = 0.0f,
    topEnd: Float = 0.0f,
    bottomEnd: Float = 0.0f,
    bottomStart: Float = 0.0f
): RoundedCornerShape

Creates RoundedCornerShape with sizes defined in pixels.

RoundedCornerShape

fun RoundedCornerShape(
    topStartPercent: @IntRange(from = 0, to = 100) Int = 0,
    topEndPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomEndPercent: @IntRange(from = 0, to = 100) Int = 0,
    bottomStartPercent: @IntRange(from = 0, to = 100) Int = 0
): RoundedCornerShape

Creates RoundedCornerShape with sizes defined in percents of the shape's smaller side.

Parameters
topStartPercent: @IntRange(from = 0, to = 100) Int = 0

The top start corner radius as a percentage of the smaller side, with a range of 0 - 100.

topEndPercent: @IntRange(from = 0, to = 100) Int = 0

The top end corner radius as a percentage of the smaller side, with a range of 0 - 100.

bottomEndPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom end corner radius as a percentage of the smaller side, with a range of 0 - 100.

bottomStartPercent: @IntRange(from = 0, to = 100) Int = 0

The bottom start corner radius as a percentage of the smaller side, with a range of 0 - 100.

Extension functions

PolygonShape.scaledToFit

@RememberInComposition
fun PolygonShape.scaledToFit(
    contentScale: ContentScale = ContentScale.Fit,
    alignment: Alignment = Alignment.Center
): PolygonShape

Returns a new PolygonShape scaled and aligned into the layout bounds.

contentScale selects the scaling policy and alignment positions the scaled geometry:

Measures the resolved geometry to place a shape accurately even when rounding pulls it inside its nominal bounds. Predefined shapes and scope factories are already bounded; scaling is useful after a transformed call or when applying non-default placement policies.

Leaves the receiver untouched and derives a new shape value.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.foundation.shape.scaledToFit
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp

// Inside a wide container the star keeps its aspect ratio and is centered; passing
// ContentScale.FillBounds instead would stretch it to fill the container.
val star = remember {
    PolygonShape.star(
            numPoints = 5,
            innerRadiusRatio = 0.5f,
            outerRounding = CornerRounding(percent = 30),
        )
        .scaledToFit(contentScale = ContentScale.Fit)
}
Box(Modifier.size(width = 160.dp, height = 64.dp).clip(star).background(Color(0xFF9C27B0)))
Parameters
contentScale: ContentScale = ContentScale.Fit

how to scale the resolved geometry into the layout bounds

alignment: Alignment = Alignment.Center

where to place the scaled geometry within the layout bounds

RoundedCornerShape.toPolygonShape

fun RoundedCornerShape.toPolygonShape(): PolygonShape

Converts a RoundedCornerShape to a PolygonShape.

Note: The resulting outline closely approximates the original shape, but is not pixel-identical because PolygonShape and RoundedCornerShape use different geometry and curve calculations. Avoid comparing them for 1:1 pixel equivalence.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.MorphPolygonShape
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.shape.toPolygonShape
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// Converting a corner-based shape to a PolygonShape lets it morph with any other polygon
// shape; here a rounded rectangle relaxes into a circle.
var expanded by remember { mutableStateOf(false) }
val progress by animateFloatAsState(if (expanded) 1f else 0f)
val shape = remember {
    MorphPolygonShape(
        start = RoundedCornerShape(12.dp).toPolygonShape(),
        end = PolygonShape.circle(),
        progress = { progress },
    )
}
Box(
    Modifier.size(96.dp).clip(shape).background(Color(0xFF03A9F4)).clickable {
        expanded = !expanded
    }
)

AbsoluteRoundedCornerShape.toPolygonShape

fun AbsoluteRoundedCornerShape.toPolygonShape(): PolygonShape

Converts an AbsoluteRoundedCornerShape to a PolygonShape.

Corners do not swap with the layout direction.

Note: The resulting outline closely approximates the original shape, but is not pixel-identical because PolygonShape and AbsoluteRoundedCornerShape use different geometry and curve calculations. Avoid comparing them for 1:1 pixel equivalence.

CutCornerShape.toPolygonShape

fun CutCornerShape.toPolygonShape(): PolygonShape

Converts a CutCornerShape to a PolygonShape.

Note: The resulting outline closely approximates the original shape, but is not pixel-identical because PolygonShape and CutCornerShape use different geometry and curve calculations. Avoid comparing them for 1:1 pixel equivalence.

AbsoluteCutCornerShape.toPolygonShape

fun AbsoluteCutCornerShape.toPolygonShape(): PolygonShape

Converts an AbsoluteCutCornerShape to a PolygonShape.

Corners do not swap with the layout direction.

Note: The resulting outline closely approximates the original shape, but is not pixel-identical because PolygonShape and AbsoluteCutCornerShape use different geometry and curve calculations. Avoid comparing them for 1:1 pixel equivalence.

PolygonShape.transformed

@RememberInComposition
fun PolygonShape.transformed(
    matrix: Matrix,
    contentScale: ContentScale? = null,
    alignment: Alignment = Alignment.Center
): PolygonShape

Returns a new PolygonShape with matrix applied to the underlying geometry.

Rotation, scale, and skew act around the resolved geometry's center, changing the shape's orientation and size in place; translation components move the shape as written.

When contentScale is non-null, the transformed geometry is scaled and aligned into the layout container bounds to prevent rotated corners from escaping the container. Pass contentScale = null (the default) to apply only the matrix transformation without scaling, or use scaledToFit to adjust scaling on an existing shape.

This function returns a new PolygonShape and should not be used for continuous animations. To animate rotation or scale on every frame, apply androidx.compose.ui.graphics.graphicsLayer instead to transform the rendered output without rebuilding geometry.

Leaves the receiver untouched and derives a new shape value holding a snapshot of matrix.

Parameters
matrix: Matrix

affine transformation to apply to the geometry

contentScale: ContentScale? = null

optional scaling policy applied after the transformation, or null to skip scaling

alignment: Alignment = Alignment.Center

where to place the scaled geometry within the layout bounds

Throws
IllegalArgumentException

if matrix has perspective components

PolygonShape.transformed

@RememberInComposition
fun PolygonShape.transformed(
    rotation: Float = 0.0f,
    translation: Offset = Offset.Zero,
    contentScale: ContentScale? = null,
    alignment: Alignment = Alignment.Center
): PolygonShape

Returns a new PolygonShape with rotation and translation applied to the underlying geometry.

rotation is applied clockwise in degrees around the geometry's center, and translation moves the shape by the specified horizontal and vertical offsets.

When contentScale is non-null, the transformed geometry is scaled and aligned into the layout container bounds to prevent rotated corners from escaping the container. Pass contentScale = null (the default) to apply only the transformation without scaling, or use scaledToFit to adjust scaling on an existing shape.

This function returns a new PolygonShape and should not be used for continuous animations. To animate rotation or translation on every frame, apply androidx.compose.ui.graphics.graphicsLayer instead to transform the rendered output without rebuilding geometry.

Leaves the receiver untouched and derives a new shape value.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.foundation.shape.transformed
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp

// A square polygon rotated 45 degrees around its center and scaled into the layout bounds in a
// single pass so the rotated diamond stays inscribed without clipping.
val diamond = remember {
    PolygonShape { polygon(numVertices = 4, rounding = CornerRounding(percent = 15)) }
        .transformed(rotation = 45f, contentScale = ContentScale.Fit)
}
Box(Modifier.size(96.dp).clip(diamond).background(Color(0xFFE91E63)))
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.PolygonShape
import androidx.compose.foundation.shape.PolygonShapeGeometry.Companion.CornerRounding
import androidx.compose.foundation.shape.transformed
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// Pre-creates the unrotated and rotated badge shape values. The runtime decision toggles
// between shape instances without rebuilding or recomputing geometry on state flips.
val badge = remember {
    PolygonShape.star(
        numPoints = 8,
        innerRadiusRatio = 0.75f,
        outerRounding = CornerRounding(percent = 40),
    )
}
val selectedBadge = remember(badge) { badge.transformed(rotation = 22.5f) }
var selected by remember { mutableStateOf(false) }
val shape = if (selected) selectedBadge else badge
Box(
    Modifier.size(96.dp).clip(shape).background(Color(0xFF00695C)).clickable {
        selected = !selected
    }
)
Parameters
rotation: Float = 0.0f

clockwise rotation in degrees, applied around the geometry center

translation: Offset = Offset.Zero

offset by which to move the shape

contentScale: ContentScale? = null

optional scaling policy applied after the transformation, or null to skip scaling

alignment: Alignment = Alignment.Center

where to place the scaled geometry within the layout bounds

Top-level properties

CircleShape

val CircleShapeRoundedCornerShape

Circular Shape with all the corners sized as the 50 percent of the shape size.

ZeroCornerSize

val ZeroCornerSizeCornerSize

CornerSize always equals to zero.