DrawScope

Known direct subclasses
CanvasDrawScope

Implementation of DrawScope that issues drawing commands into the specified canvas and bounds via CanvasDrawScope.draw

ContentDrawScope

Receiver scope for drawing content into a layout, where the content can be drawn between other canvas operations.


Creates a scoped drawing environment with the provided Canvas. This provides a declarative, stateless API to draw shapes and paths without requiring consumers to maintain underlying Canvas state information. DrawScope implementations are also provided sizing information and transformations are done relative to the local translation. That is left and top coordinates are always the origin and the right and bottom coordinates are always the specified width and height respectively. Drawing content is not clipped, so it is possible to draw outside of the specified bounds.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.unit.dp

// Sample showing how to use the DrawScope receiver scope to issue
// drawing commands
Canvas(Modifier.size(120.dp)) {
    drawRect(color = Color.Gray) // Draw grey background
    // Inset content by 10 pixels on the left/right sides and 12 by the
    // top/bottom
    inset(10.0f, 12.0f) {
        val quadrantSize = size / 2.0f

        // Draw a rectangle within the inset bounds
        drawRect(size = quadrantSize, color = Color.Red)

        rotate(45.0f) { drawRect(size = quadrantSize, color = Color.Blue) }
    }
}

Summary

Public companion properties

BlendMode

Default blending mode used for each drawing operation.

Cmn
FilterQuality

Default FilterQuality used for determining the filtering algorithm to apply when scaling ImageBitmap objects.

Cmn

Public functions

Unit
drawArc(
    brush: Brush,
    startAngle: Float,
    sweepAngle: Float,
    useCenter: Boolean,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draw an arc scaled to fit inside the given rectangle.

Cmn
Unit
drawArc(
    color: Color,
    startAngle: Float,
    sweepAngle: Float,
    useCenter: Boolean,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draw an arc scaled to fit inside the given rectangle.

Cmn
Unit
drawCircle(
    brush: Brush,
    radius: Float,
    center: Offset,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a circle at the provided center coordinate and radius.

Cmn
Unit
drawCircle(
    color: Color,
    radius: Float,
    center: Offset,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a circle at the provided center coordinate and radius.

Cmn
Unit
drawImage(
    image: ImageBitmap,
    topLeft: Offset,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws the given ImageBitmap into the canvas with its top-left corner at the given Offset.

Cmn
open Unit
drawImage(
    image: ImageBitmap,
    srcOffset: IntOffset,
    srcSize: IntSize,
    dstOffset: IntOffset,
    dstSize: IntSize,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode,
    filterQuality: FilterQuality
)

Draws the subset of the given image described by the src argument into the canvas in the axis-aligned rectangle given by the dst argument.

Cmn
Unit
drawLine(
    brush: Brush,
    start: Offset,
    end: Offset,
    strokeWidth: Float,
    cap: StrokeCap,
    pathEffect: PathEffect?,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a line between the given points using the given paint.

Cmn
Unit
drawLine(
    color: Color,
    start: Offset,
    end: Offset,
    strokeWidth: Float,
    cap: StrokeCap,
    pathEffect: PathEffect?,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a line between the given points using the given paint.

Cmn
Unit
drawOval(
    brush: Brush,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws an oval with the given offset and size.

Cmn
Unit
drawOval(
    color: Color,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws an oval with the given offset and size.

Cmn
Unit
drawPath(
    path: Path,
    brush: Brush,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws the given Path with the given Color.

Cmn
Unit
drawPath(
    path: Path,
    color: Color,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws the given Path with the given Color.

Cmn
Unit
drawPoints(
    points: List<Offset>,
    pointMode: PointMode,
    brush: Brush,
    strokeWidth: Float,
    cap: StrokeCap,
    pathEffect: PathEffect?,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a sequence of points according to the given PointMode.

Cmn
Unit
drawPoints(
    points: List<Offset>,
    pointMode: PointMode,
    color: Color,
    strokeWidth: Float,
    cap: StrokeCap,
    pathEffect: PathEffect?,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a sequence of points according to the given PointMode.

Cmn
Unit
drawRect(
    brush: Brush,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a rectangle with the given offset and size.

Cmn
Unit
drawRect(
    color: Color,
    topLeft: Offset,
    size: Size,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a rectangle with the given offset and size.

Cmn
Unit
drawRoundRect(
    brush: Brush,
    topLeft: Offset,
    size: Size,
    cornerRadius: CornerRadius,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a rounded rectangle with the provided size, offset and radii for the x and y axis respectively.

Cmn
Unit
drawRoundRect(
    color: Color,
    topLeft: Offset,
    size: Size,
    cornerRadius: CornerRadius,
    style: DrawStyle,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws a rounded rectangle with the given Paint.

Cmn
open Unit
GraphicsLayer.record(size: IntSize, block: DrawScope.() -> Unit)

Record the corresponding drawing commands for this GraphicsLayer instance using the Density, LayoutDirection and IntSize from the provided DrawScope as defaults.

Cmn

Public properties

open Offset

Center of the current bounds of the drawing environment

Cmn
DrawContext

The current DrawContext that contains the dependencies needed to create the drawing environment

Cmn
LayoutDirection

The layout direction of the layout being drawn in.

Cmn
open Size

Provides the dimensions of the current drawing environment

Cmn

Extension functions

inline Unit
DrawScope.clipPath(path: Path, clipOp: ClipOp, block: DrawScope.() -> Unit)

Reduces the clip region to the intersection of the current clip and the given path.

Cmn
inline Unit
DrawScope.clipRect(
    left: Float,
    top: Float,
    right: Float,
    bottom: Float,
    clipOp: ClipOp,
    block: DrawScope.() -> Unit
)

Reduces the clip region to the intersection of the current clip and the given rectangle indicated by the given left, top, right and bottom bounds.

Cmn
inline Unit
DrawScope.draw(
    density: Density,
    layoutDirection: LayoutDirection,
    canvas: Canvas,
    size: Size,
    graphicsLayer: GraphicsLayer?,
    block: DrawScope.() -> Unit
)

Draws into the provided Canvas with the commands specified in the lambda with this DrawScope as a receiver

Cmn
inline Unit

Provides access to draw directly with the underlying Canvas.

Cmn
inline Unit
DrawScope.inset(inset: Float, block: DrawScope.() -> Unit)

Convenience method modifies the DrawScope bounds to inset both left, top, right and bottom bounds by inset.

Cmn
inline Unit
DrawScope.inset(horizontal: Float, vertical: Float, block: DrawScope.() -> Unit)

Convenience method modifies the DrawScope bounds to inset both left and right bounds by horizontal as well as the top and bottom by vertical.

Cmn
inline Unit
DrawScope.inset(
    left: Float,
    top: Float,
    right: Float,
    bottom: Float,
    block: DrawScope.() -> Unit
)

Simultaneously translate the DrawScope coordinate space by left and top as well as modify the dimensions of the current painting area.

Cmn
inline Unit
DrawScope.rotate(degrees: Float, pivot: Offset, block: DrawScope.() -> Unit)

Add a rotation (in degrees clockwise) to the current transform at the given pivot point.

Cmn
inline Unit
DrawScope.rotateRad(radians: Float, pivot: Offset, block: DrawScope.() -> Unit)

Add a rotation (in radians clockwise) to the current transform at the given pivot point.

Cmn
inline Unit
DrawScope.scale(scale: Float, pivot: Offset, block: DrawScope.() -> Unit)

Add an axis-aligned scale to the current transform, scaling both the horizontal direction and the vertical direction at the given pivot coordinate.

Cmn
inline Unit
DrawScope.scale(
    scaleX: Float,
    scaleY: Float,
    pivot: Offset,
    block: DrawScope.() -> Unit
)

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction at the given pivot coordinate.

Cmn
inline Unit
DrawScope.translate(left: Float, top: Float, block: DrawScope.() -> Unit)

Translate the coordinate space by the given delta in pixels in both the x and y coordinates respectively

Cmn
inline Unit
DrawScope.withTransform(transformBlock: DrawTransform.() -> Unit, drawBlock: DrawScope.() -> Unit)

Perform 1 or more transformations and execute drawing commands with the specified transformations applied.

Cmn
Unit

Draw the provided GraphicsLayer into the current DrawScope.

Cmn
Unit
DrawScope.drawOutline(
    outline: Outline,
    brush: Brush,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws the Outline on a DrawScope.

Cmn
Unit
DrawScope.drawOutline(
    outline: Outline,
    color: Color,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float,
    style: DrawStyle,
    colorFilter: ColorFilter?,
    blendMode: BlendMode
)

Draws the Outline on a DrawScope.

Cmn
Unit
DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    brush: Brush,
    topLeft: Offset,
    alpha: Float,
    shadow: Shadow?,
    textDecoration: TextDecoration?,
    drawStyle: DrawStyle?,
    blendMode: BlendMode
)

Draw an existing text layout as produced by TextMeasurer.

Cmn
Unit
DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    color: Color,
    topLeft: Offset,
    alpha: Float,
    shadow: Shadow?,
    textDecoration: TextDecoration?,
    drawStyle: DrawStyle?,
    blendMode: BlendMode
)

Draw an existing text layout as produced by TextMeasurer.

Cmn
Unit
DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: String,
    topLeft: Offset,
    style: TextStyle,
    overflow: TextOverflow,
    softWrap: Boolean,
    maxLines: Int,
    size: Size,
    blendMode: BlendMode
)

Draw text using a TextMeasurer.

Cmn
Unit
DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: AnnotatedString,
    topLeft: Offset,
    style: TextStyle,
    overflow: TextOverflow,
    softWrap: Boolean,
    maxLines: Int,
    placeholders: List<AnnotatedString.Range<Placeholder>>,
    size: Size,
    blendMode: BlendMode
)

Draw styled text using a TextMeasurer.

Cmn

Inherited functions

From androidx.compose.ui.unit.Density
open Int

Convert Dp to Int by rounding

Cmn
open Int

Convert Sp to Int by rounding

Cmn
open Dp

Convert an Int pixel value to Dp.

Cmn
open Dp

Convert a Float pixel value to a Dp

Cmn
open DpSize

Convert a Size to a DpSize.

Cmn
open Float

Convert Dp to pixels.

Cmn
open Float

Convert Sp to pixels.

Cmn
open Rect

Convert a DpRect to a Rect.

Cmn
open Size

Convert a DpSize to a Size.

Cmn
open TextUnit

Convert an Int pixel value to Sp.

Cmn
open TextUnit

Convert a Float pixel value to a Sp

Cmn
From androidx.compose.ui.unit.FontScaling
open Dp

Convert Sp to Dp.

Cmn
open TextUnit

Convert Dp to Sp.

Cmn

Inherited properties

From androidx.compose.ui.unit.Density
Float

The logical density of the display.

Cmn
From androidx.compose.ui.unit.FontScaling
Float

Current user preference for the scaling factor for fonts.

Cmn

Public companion properties

DefaultBlendMode

val DefaultBlendModeBlendMode

Default blending mode used for each drawing operation. This ensures that content is drawn on top of the pixels in the destination

DefaultFilterQuality

val DefaultFilterQualityFilterQuality

Default FilterQuality used for determining the filtering algorithm to apply when scaling ImageBitmap objects. Maps to the default behavior of bilinear filtering

Public functions

drawArc

fun drawArc(
    brush: Brush,
    startAngle: Float,
    sweepAngle: Float,
    useCenter: Boolean,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draw an arc scaled to fit inside the given rectangle. It starts from startAngle degrees around the oval up to startAngle + sweepAngle degrees around the oval, with zero degrees being the point on the right hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval. If useCenter is true, the arc is closed back to the center, forming a circle sector. Otherwise, the arc is not closed, forming a circle segment.

Parameters
brush: Brush

Color or fill to be applied to the arc

startAngle: Float

Starting angle in degrees. 0 represents 3 o'clock

sweepAngle: Float

Size of the arc in degrees that is drawn clockwise relative to startAngle

useCenter: Boolean

Flag indicating if the arc is to close the center of the bounds

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the arc to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the arc from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the arc is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the arc when it is drawn

drawArc

fun drawArc(
    color: Color,
    startAngle: Float,
    sweepAngle: Float,
    useCenter: Boolean,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draw an arc scaled to fit inside the given rectangle. It starts from startAngle degrees around the oval up to startAngle + sweepAngle degrees around the oval, with zero degrees being the point on the right hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval. If useCenter is true, the arc is closed back to the center, forming a circle sector. Otherwise, the arc is not closed, forming a circle segment.

Parameters
color: Color

Color to be applied to the arc

startAngle: Float

Starting angle in degrees. 0 represents 3 o'clock

sweepAngle: Float

Size of the arc in degrees that is drawn clockwise relative to startAngle

useCenter: Boolean

Flag indicating if the arc is to close the center of the bounds

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the arc to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the arc from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the arc is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the arc when it is drawn

drawCircle

fun drawCircle(
    brush: Brush,
    radius: Float = size.minDimension / 2.0f,
    center: Offset = this.center,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a circle at the provided center coordinate and radius. If no center point is provided the center of the bounds is used.

Parameters
brush: Brush

The color or fill to be applied to the circle

radius: Float = size.minDimension / 2.0f

The radius of the circle

center: Offset = this.center

The center coordinate where the circle is to be drawn

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the circle from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the circle is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the brush

drawCircle

fun drawCircle(
    color: Color,
    radius: Float = size.minDimension / 2.0f,
    center: Offset = this.center,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a circle at the provided center coordinate and radius. If no center point is provided the center of the bounds is used.

Parameters
color: Color

The color or fill to be applied to the circle

radius: Float = size.minDimension / 2.0f

The radius of the circle

center: Offset = this.center

The center coordinate where the circle is to be drawn

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the circle from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the circle is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the brush

drawImage

fun drawImage(
    image: ImageBitmap,
    topLeft: Offset = Offset.Zero,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws the given ImageBitmap into the canvas with its top-left corner at the given Offset. The image is composited into the canvas using the given Paint.

Parameters
image: ImageBitmap

The ImageBitmap to draw

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to image from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Specifies whether the image is to be drawn filled in or as a rectangular stroke

colorFilter: ColorFilter? = null

ColorFilter to apply to the image when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to apply to destination

drawImage

open fun drawImage(
    image: ImageBitmap,
    srcOffset: IntOffset = IntOffset.Zero,
    srcSize: IntSize = IntSize(image.width, image.height),
    dstOffset: IntOffset = IntOffset.Zero,
    dstSize: IntSize = srcSize,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode,
    filterQuality: FilterQuality = DefaultFilterQuality
): Unit

Draws the subset of the given image described by the src argument into the canvas in the axis-aligned rectangle given by the dst argument.

If no src rect is provided, the entire image is scaled into the corresponding destination bounds

Parameters
image: ImageBitmap

The source image to draw

srcOffset: IntOffset = IntOffset.Zero

Optional offset representing the top left offset of the source image to draw, this defaults to the origin of image

srcSize: IntSize = IntSize(image.width, image.height)

Optional dimensions of the source image to draw relative to srcOffset, this defaults the width and height of image

dstOffset: IntOffset = IntOffset.Zero

Optional offset representing the top left offset of the destination to draw the given image, this defaults to the origin of the current translation tarting top left offset in the destination to draw the image

dstSize: IntSize = srcSize

Optional dimensions of the destination to draw, this defaults to srcSize

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to image from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Specifies whether the image is to be drawn filled in or as a rectangular stroke

colorFilter: ColorFilter? = null

ColorFilter to apply to the image when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to apply to destination

filterQuality: FilterQuality = DefaultFilterQuality

Sampling algorithm applied to the image when it is scaled and drawn into the destination. The default is FilterQuality.Low which scales using a bilinear sampling algorithm

drawLine

fun drawLine(
    brush: Brush,
    start: Offset,
    end: Offset,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = Stroke.DefaultCap,
    pathEffect: PathEffect? = null,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a line between the given points using the given paint. The line is stroked.

Parameters
brush: Brush

the color or fill to be applied to the line

start: Offset

first point of the line to be drawn

end: Offset

second point of the line to be drawn

strokeWidth: Float = Stroke.HairlineWidth

stroke width to apply to the line

cap: StrokeCap = Stroke.DefaultCap

treatment applied to the ends of the line segment

pathEffect: PathEffect? = null

optional effect or pattern to apply to the line

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

opacity to be applied to the brush from 0.0f to 1.0f representing fully transparent to fully opaque respectively

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

the blending algorithm to apply to the brush

drawLine

fun drawLine(
    color: Color,
    start: Offset,
    end: Offset,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = Stroke.DefaultCap,
    pathEffect: PathEffect? = null,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a line between the given points using the given paint. The line is stroked.

Parameters
color: Color

the color to be applied to the line

start: Offset

first point of the line to be drawn

end: Offset

second point of the line to be drawn

strokeWidth: Float = Stroke.HairlineWidth

The stroke width to apply to the line

cap: StrokeCap = Stroke.DefaultCap

treatment applied to the ends of the line segment

pathEffect: PathEffect? = null

optional effect or pattern to apply to the line

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

opacity to be applied to the color from 0.0f to 1.0f representing fully transparent to fully opaque respectively

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

the blending algorithm to apply to the color

drawOval

fun drawOval(
    brush: Brush,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws an oval with the given offset and size. If no offset from the top left is provided, it is drawn starting from the origin of the current translation. If no size is provided, the size of the current environment is used.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.unit.dp

Canvas(Modifier.size(120.dp)) {
    drawOval(
        brush = Brush.linearGradient(listOf(Color.Red, Color.Blue)),
        topLeft = Offset(10f, 10f),
        size = Size(size.width - 20f, size.height - 20f)
    )
}
Parameters
brush: Brush

Color or fill to be applied to the oval

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the oval from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the oval is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the brush

drawOval

fun drawOval(
    color: Color,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws an oval with the given offset and size. If no offset from the top left is provided, it is drawn starting from the origin of the current translation. If no size is provided, the size of the current environment is used.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.unit.dp

Canvas(Modifier.size(120.dp)) {
    drawOval(
        color = Color.Cyan,
        topLeft = Offset(10f, 10f),
        size = Size(size.width - 20f, size.height - 20f)
    )
}
Parameters
color: Color

Color to be applied to the oval

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the oval from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the oval is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the brush

drawPath

fun drawPath(
    path: Path,
    brush: Brush,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws the given Path with the given Color. Whether this shape is filled or stroked (or both) is controlled by DrawStyle. If the path is filled, then subpaths within it are implicitly closed (see Path.close).

Parameters
path: Path

Path to draw

brush: Brush

Brush to be applied to the path

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the path from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the path is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the path when it is drawn

drawPath

fun drawPath(
    path: Path,
    color: Color,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws the given Path with the given Color. Whether this shape is filled or stroked (or both) is controlled by DrawStyle. If the path is filled, then subpaths within it are implicitly closed (see Path.close).

Parameters
path: Path

Path to draw

color: Color

Color to be applied to the path

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the path from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the path is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the path when it is drawn

drawPoints

fun drawPoints(
    points: List<Offset>,
    pointMode: PointMode,
    brush: Brush,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = StrokeCap.Butt,
    pathEffect: PathEffect? = null,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a sequence of points according to the given PointMode.

The points argument is interpreted as offsets from the origin.

Parameters
points: List<Offset>

List of points to draw with the specified PointMode

pointMode: PointMode

PointMode used to indicate how the points are to be drawn

brush: Brush

Brush to be applied to the points

strokeWidth: Float = Stroke.HairlineWidth

The stroke width to apply to the line

cap: StrokeCap = StrokeCap.Butt

Treatment applied to the ends of the line segment

pathEffect: PathEffect? = null

optional effect or pattern to apply to the points

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the path from 0.0f to 1.0f representing fully transparent to fully opaque respectively.

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the path when it is drawn

drawPoints

fun drawPoints(
    points: List<Offset>,
    pointMode: PointMode,
    color: Color,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = StrokeCap.Butt,
    pathEffect: PathEffect? = null,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a sequence of points according to the given PointMode.

The points argument is interpreted as offsets from the origin.

Parameters
points: List<Offset>

List of points to draw with the specified PointMode

pointMode: PointMode

PointMode used to indicate how the points are to be drawn

color: Color

Color to be applied to the points

strokeWidth: Float = Stroke.HairlineWidth

The stroke width to apply to the line

cap: StrokeCap = StrokeCap.Butt

Treatment applied to the ends of the line segment

pathEffect: PathEffect? = null

optional effect or pattern to apply to the point

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the path from 0.0f to 1.0f representing fully transparent to fully opaque respectively

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the path when it is drawn

drawRect

fun drawRect(
    brush: Brush,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a rectangle with the given offset and size. If no offset from the top left is provided, it is drawn starting from the origin of the current translation. If no size is provided, the size of the current environment is used.

Parameters
brush: Brush

The color or fill to be applied to the rectangle

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the brush from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the rectangle is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to apply to destination

drawRect

fun drawRect(
    color: Color,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a rectangle with the given offset and size. If no offset from the top left is provided, it is drawn starting from the origin of the current translation. If no size is provided, the size of the current environment is used.

Parameters
color: Color

The color to be applied to the rectangle

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to the color from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Whether or not the rectangle is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the color source pixels

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to apply to destination

drawRoundRect

fun drawRoundRect(
    brush: Brush,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    cornerRadius: CornerRadius = CornerRadius.Zero,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a rounded rectangle with the provided size, offset and radii for the x and y axis respectively. This rectangle is drawn with the provided Brush parameter and is filled or stroked based on the given DrawStyle

Parameters
brush: Brush

The color or fill to be applied to the rounded rectangle

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

cornerRadius: CornerRadius = CornerRadius.Zero

Corner radius of the rounded rectangle, negative radii values are clamped to 0

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to rounded rectangle from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Specifies whether the rounded rectangle is stroked or filled in

colorFilter: ColorFilter? = null

ColorFilter to apply to the brush when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the brush

drawRoundRect

fun drawRoundRect(
    color: Color,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    cornerRadius: CornerRadius = CornerRadius.Zero,
    style: DrawStyle = Fill,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
): Unit

Draws a rounded rectangle with the given Paint. Whether the rectangle is filled or stroked (or both) is controlled by Paint.style.

Parameters
color: Color

The color to be applied to the rounded rectangle

topLeft: Offset = Offset.Zero

Offset from the local origin of 0, 0 relative to the current translation

size: Size = this.size.offsetSize(topLeft)

Dimensions of the rectangle to draw

cornerRadius: CornerRadius = CornerRadius.Zero

Corner radius of the rounded rectangle, negative radii values are clamped to 0

style: DrawStyle = Fill

Specifies whether the rounded rectangle is stroked or filled in

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to rounded rectangle from 0.0f to 1.0f representing fully transparent to fully opaque respectively

colorFilter: ColorFilter? = null

ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DefaultBlendMode

Blending algorithm to be applied to the color

open fun GraphicsLayer.record(
    size: IntSize = this@DrawScope.size.toIntSize(),
    block: DrawScope.() -> Unit
): Unit

Record the corresponding drawing commands for this GraphicsLayer instance using the Density, LayoutDirection and IntSize from the provided DrawScope as defaults. This will retarget the underlying canvas of the provided DrawScope to draw within the layer itself and reset it to the original canvas on the conclusion of this method call.

Public properties

center

open val centerOffset

Center of the current bounds of the drawing environment

drawContext

val drawContextDrawContext

The current DrawContext that contains the dependencies needed to create the drawing environment

layoutDirection

val layoutDirectionLayoutDirection

The layout direction of the layout being drawn in.

size

open val sizeSize

Provides the dimensions of the current drawing environment

Extension functions

inline fun DrawScope.clipPath(
    path: Path,
    clipOp: ClipOp = ClipOp.Intersect,
    block: DrawScope.() -> Unit
): Unit

Reduces the clip region to the intersection of the current clip and the given path. This method provides a callback to issue drawing commands within the region defined by the clipped path. After this method is invoked, this clip is no longer applied.

Parameters
path: Path

Shape to clip drawing content within

clipOp: ClipOp = ClipOp.Intersect

Clipping operation to conduct on the given bounds, defaults to ClipOp.Intersect

block: DrawScope.() -> Unit

Lambda callback with this CanvasScope as a receiver scope to issue drawing commands within the provided clip

inline fun DrawScope.clipRect(
    left: Float = 0.0f,
    top: Float = 0.0f,
    right: Float = size.width,
    bottom: Float = size.height,
    clipOp: ClipOp = ClipOp.Intersect,
    block: DrawScope.() -> Unit
): Unit

Reduces the clip region to the intersection of the current clip and the given rectangle indicated by the given left, top, right and bottom bounds. This provides a callback to issue drawing commands within the clipped region. After this method is invoked, this clip is no longer applied.

Use ClipOp.Difference to subtract the provided rectangle from the current clip.

Parameters
left: Float = 0.0f

Left bound of the rectangle to clip

top: Float = 0.0f

Top bound of the rectangle to clip

right: Float = size.width

Right bound of the rectangle to clip

bottom: Float = size.height

Bottom bound of the rectangle to clip

clipOp: ClipOp = ClipOp.Intersect

Clipping operation to conduct on the given bounds, defaults to ClipOp.Intersect

block: DrawScope.() -> Unit

Lambda callback with this CanvasScope as a receiver scope to issue drawing commands within the provided clip

inline fun DrawScope.draw(
    density: Density,
    layoutDirection: LayoutDirection,
    canvas: Canvas,
    size: Size,
    graphicsLayer: GraphicsLayer? = null,
    block: DrawScope.() -> Unit
): Unit

Draws into the provided Canvas with the commands specified in the lambda with this DrawScope as a receiver

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.unit.dp

Box(
    modifier =
        Modifier.size(120.dp).drawWithCache {
            // Example that shows how to redirect rendering to an Android Picture and then
            // draw the picture into the original destination
            // Note:
            // Canvas#drawPicture is supported with hardware acceleration on Android API 23+
            // Check
            // https://developer.android.com/topic/performance/hardware-accel#drawing-support
            // for details of which drawing operations are supported with hardware acceleration
            val picture = android.graphics.Picture()
            val width = this.size.width.toInt()
            val height = this.size.height.toInt()
            onDrawWithContent {
                val pictureCanvas =
                    androidx.compose.ui.graphics.Canvas(picture.beginRecording(width, height))
                draw(this, this.layoutDirection, pictureCanvas, this.size) {
                    this@onDrawWithContent.drawContent()
                }
                picture.endRecording()

                drawIntoCanvas { canvas -> canvas.nativeCanvas.drawPicture(picture) }
            }
        }
)
Parameters
density: Density

Density used to assist in conversions of density independent pixels to raw pixels to draw

layoutDirection: LayoutDirection

LayoutDirection of the layout being drawn in.

canvas: Canvas

target canvas to render into

size: Size

bounds relative to the current canvas translation in which the DrawScope should draw within

graphicsLayer: GraphicsLayer? = null

Current GraphicsLayer we are drawing into. Might be null if the canvas is not provided by a GraphicsLayer, for example in the case of a software-accelerated drawing

block: DrawScope.() -> Unit

lambda that is called to issue drawing commands on this DrawScope

drawIntoCanvas

inline fun DrawScope.drawIntoCanvas(block: (Canvas) -> Unit): Unit

Provides access to draw directly with the underlying Canvas. This is helpful for situations to re-use alternative drawing logic in combination with DrawScope

Parameters
block: (Canvas) -> Unit

Lambda callback to issue drawing commands on the provided Canvas

inline fun DrawScope.inset(inset: Float, block: DrawScope.() -> Unit): Unit

Convenience method modifies the DrawScope bounds to inset both left, top, right and bottom bounds by inset. After this method is invoked, the coordinate space is returned to the state before this inset was applied.

Parameters
inset: Float

number of pixels to inset left, top, right, and bottom bounds.

block: DrawScope.() -> Unit

lambda that is called to issue additional drawing commands within the modified coordinate space

inline fun DrawScope.inset(
    horizontal: Float = 0.0f,
    vertical: Float = 0.0f,
    block: DrawScope.() -> Unit
): Unit

Convenience method modifies the DrawScope bounds to inset both left and right bounds by horizontal as well as the top and bottom by vertical. After this method is invoked, the coordinate space is returned to the state before this inset was applied.

Parameters
horizontal: Float = 0.0f

number of pixels to inset both left and right bounds. Zero by default

vertical: Float = 0.0f

Optional number of pixels to inset both top and bottom bounds. Zero by default

block: DrawScope.() -> Unit

lambda that is called to issue additional drawing commands within the modified coordinate space

inline fun DrawScope.inset(
    left: Float,
    top: Float,
    right: Float,
    bottom: Float,
    block: DrawScope.() -> Unit
): Unit

Simultaneously translate the DrawScope coordinate space by left and top as well as modify the dimensions of the current painting area. This provides a callback to issue more drawing instructions within the modified coordinate space. This method modifies the width of the DrawScope to be equivalent to width - (left + right) as well as height to height - (top + bottom). After this method is invoked, the coordinate space is returned to the state before the inset was applied.

Parameters
left: Float

number of pixels to inset the left drawing bound

top: Float

number of pixels to inset the top drawing bound

right: Float

number of pixels to inset the right drawing bound

bottom: Float

number of pixels to inset the bottom drawing bound

block: DrawScope.() -> Unit

lambda that is called to issue drawing commands within the inset coordinate space

inline fun DrawScope.rotate(degrees: Float, pivot: Offset = center, block: DrawScope.() -> Unit): Unit

Add a rotation (in degrees clockwise) to the current transform at the given pivot point. The pivot coordinate remains unchanged by the rotation transformation. After the provided lambda is invoked, the rotation transformation is undone.

Parameters
degrees: Float

to rotate clockwise

pivot: Offset = center

The coordinate for the pivot point, defaults to the center of the coordinate space

block: DrawScope.() -> Unit

lambda that is called to issue drawing commands within the rotated coordinate space

inline fun DrawScope.rotateRad(radians: Float, pivot: Offset = center, block: DrawScope.() -> Unit): Unit

Add a rotation (in radians clockwise) to the current transform at the given pivot point. The pivot coordinate remains unchanged by the rotation transformation

Parameters
radians: Float

to rotate clockwise

pivot: Offset = center

The coordinate for the pivot point, defaults to the center of the coordinate space

block: DrawScope.() -> Unit

lambda that is called to issue drawing commands within the rotated coordinate space

inline fun DrawScope.scale(scale: Float, pivot: Offset = center, block: DrawScope.() -> Unit): Unit

Add an axis-aligned scale to the current transform, scaling both the horizontal direction and the vertical direction at the given pivot coordinate. The pivot coordinate remains unchanged by the scale transformation. After this method is invoked, the coordinate space is returned to the state before the scale was applied.

Parameters
scale: Float

The amount to scale uniformly in both directions

pivot: Offset = center

The coordinate for the pivot point, defaults to the center of the coordinate space

block: DrawScope.() -> Unit

lambda used to issue drawing commands within the scaled coordinate space

inline fun DrawScope.scale(
    scaleX: Float,
    scaleY: Float,
    pivot: Offset = center,
    block: DrawScope.() -> Unit
): Unit

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction at the given pivot coordinate. The pivot coordinate remains unchanged by the scale transformation. After this method is invoked, the coordinate space is returned to the state before the scale was applied.

Parameters
scaleX: Float

The amount to scale in X

scaleY: Float

The amount to scale in Y

pivot: Offset = center

The coordinate for the pivot point, defaults to the center of the coordinate space

block: DrawScope.() -> Unit

lambda used to issue drawing commands within the scaled coordinate space

inline fun DrawScope.translate(left: Float = 0.0f, top: Float = 0.0f, block: DrawScope.() -> Unit): Unit

Translate the coordinate space by the given delta in pixels in both the x and y coordinates respectively

Parameters
left: Float = 0.0f

Pixels to translate the coordinate space in the x-axis

top: Float = 0.0f

Pixels to translate the coordinate space in the y-axis

block: DrawScope.() -> Unit

lambda that is called to issue drawing commands within the translated coordinate space

withTransform

inline fun DrawScope.withTransform(transformBlock: DrawTransform.() -> Unit, drawBlock: DrawScope.() -> Unit): Unit

Perform 1 or more transformations and execute drawing commands with the specified transformations applied. After this call is complete, the transformation before this call was made is restored

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.draw
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.unit.dp

Canvas(Modifier.size(120.dp)) { // CanvasScope
    inset(20.0f) {
        // Use withTransform to batch multiple transformations for 1 or more drawing calls
        // that are to be drawn.
        // This is more efficient than issuing nested translation, rotation and scaling
        // calls as the internal state is saved once before and after instead of multiple
        // times between each transformation if done individually
        withTransform({
            translate(10.0f, 12.0f)
            rotate(45.0f, center)
            scale(2.0f, 0.5f)
        }) {
            drawRect(Color.Cyan)
            drawCircle(Color.Blue)
        }
        drawRect(Color.Red, alpha = 0.25f)
    }
}
Parameters
transformBlock: DrawTransform.() -> Unit

Callback invoked to issue transformations to be made before the drawing operations are issued

drawBlock: DrawScope.() -> Unit

Callback invoked to issue drawing operations after the transformations are applied

fun DrawScope.drawLayer(graphicsLayer: GraphicsLayer): Unit

Draw the provided GraphicsLayer into the current DrawScope. The GraphicsLayer provided must have GraphicsLayer.record invoked on it otherwise no visual output will be seen in the rendered result.

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.layer.drawLayer
import androidx.compose.ui.unit.IntOffset

// Build the layer with the density, layout direction and size from the DrawScope
// and position the top left to be 20 pixels from the left and 30 pixels from the top.
// This will the bounds of the layer with a red rectangle
layer.apply {
    record { drawRect(Color.Red) }
    this.topLeft = IntOffset(20, 30)
}

// Draw the layer into the provided DrawScope
drawLayer(layer)
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.layer.drawLayer
import androidx.compose.ui.unit.IntSize

// Create a 200 x 200 pixel layer that has a red rectangle drawn in the lower right
// corner.
layer.apply {
    record(size = IntSize(200, 200)) {
        drawRect(Color.Red, topLeft = Offset(size.width / 2f, size.height / 2f))
    }
    // Scale the layer by 1.5x in both the x and y axis relative to the bottom
    // right corner
    scaleX = 1.5f
    scaleY = 1.5f
    pivotOffset = Offset(this.size.width.toFloat(), this.size.height.toFloat())
}

// Draw the layer into the provided DrawScope
drawLayer(layer)
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.layer.drawLayer

// Create a layer with the same configuration as the destination DrawScope
// and draw a red rectangle in the layer
layer.apply {
    record { drawRect(Color.Red) }
    // Apply a ColorFilter that will tint the contents of the layer to blue
    // when it is drawn into the destination DrawScope
    colorFilter = ColorFilter.tint(Color.Blue)
}

drawLayer(layer)
import androidx.compose.ui.graphics.BlurEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.layer.drawLayer

// Create a layer sized to the destination draw scope that is comprised
// of an inset red rectangle
layer.apply {
    record { inset(20f, 20f) { drawRect(Color.Red) } }
    // Configure a blur to the contents of the layer that is applied
    // when drawn to the destination DrawScope
    renderEffect = BlurEffect(20f, 20f, TileMode.Decal)
}

drawLayer(layer)
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.graphics.layer.drawLayer

// Create a layer sized to the destination draw scope that is comprised
// of an inset red rectangle
layer.apply {
    record { inset(20f, 20f) { drawRect(Color.Red) } }
    // Renders the content of the layer with 50% alpha when it is drawn
    // into the destination
    alpha = 0.5f
}

drawLayer(layer)
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.layer.drawLayer

layer.apply {
    record { drawRect(Color.Yellow) }
    // Rotates the yellow rect 45f clockwise relative to the x axis
    rotationX = 45f
}

drawLayer(layer)
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.layer.drawLayer

layer.apply {
    record { drawRect(Color.Yellow) }
    // Rotates the yellow rect 45f clockwise relative to the y axis
    rotationY = 45f
    cameraDistance = 5.0f
}

drawLayer(layer)

drawOutline

fun DrawScope.drawOutline(
    outline: Outline,
    brush: Brush,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draws the Outline on a DrawScope.

Parameters
outline: Outline

the outline to draw.

brush: Brush

Brush applied to the outline when it is drawn

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to outline from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Specifies whether the outline is stroked or filled in

colorFilter: ColorFilter? = null

: ColorFilter to apply to the Brush when drawn into the destination

blendMode: BlendMode = DrawScope.DefaultBlendMode

: Blending algorithm to be applied to the outline

drawOutline

fun DrawScope.drawOutline(
    outline: Outline,
    color: Color,
    alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draws the Outline on a DrawScope.

Parameters
outline: Outline

the outline to draw.

color: Color

Color applied to the outline when it is drawn

alpha: @FloatRange(from = 0.0, to = 1.0) Float = 1.0f

Opacity to be applied to outline from 0.0f to 1.0f representing fully transparent to fully opaque respectively

style: DrawStyle = Fill

Specifies whether the outline is stroked or filled in

colorFilter: ColorFilter? = null

: ColorFilter to apply to the color when drawn into the destination

blendMode: BlendMode = DrawScope.DefaultBlendMode

: Blending algorithm to be applied to the outline

drawText

fun DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    brush: Brush,
    topLeft: Offset = Offset.Zero,
    alpha: Float = Float.NaN,
    shadow: Shadow? = null,
    textDecoration: TextDecoration? = null,
    drawStyle: DrawStyle? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draw an existing text layout as produced by TextMeasurer.

This draw function cannot relayout when async font loading resolves. If using async fonts or other dynamic text layout, you are responsible for invalidating layout on changes.

Parameters
textLayoutResult: TextLayoutResult

Text Layout to be drawn

brush: Brush

The brush to use when drawing the text.

topLeft: Offset = Offset.Zero

Offsets the text from top left point of the current coordinate system.

alpha: Float = Float.NaN

Opacity to be applied to brush from 0.0f to 1.0f representing fully transparent to fully opaque respectively.

shadow: Shadow? = null

The shadow effect applied on the text.

textDecoration: TextDecoration? = null

The decorations to paint on the text (e.g., an underline).

drawStyle: DrawStyle? = null

Whether or not the text is stroked or filled in.

blendMode: BlendMode = DrawScope.DefaultBlendMode

Blending algorithm to be applied to the text

drawText

fun DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    color: Color = Color.Unspecified,
    topLeft: Offset = Offset.Zero,
    alpha: Float = Float.NaN,
    shadow: Shadow? = null,
    textDecoration: TextDecoration? = null,
    drawStyle: DrawStyle? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draw an existing text layout as produced by TextMeasurer.

This draw function cannot relayout when async font loading resolves. If using async fonts or other dynamic text layout, you are responsible for invalidating layout on changes.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.sp

val textMeasurer = rememberTextMeasurer()
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }

Canvas(
    Modifier.fillMaxSize().layout { measurable, constraints ->
        val placeable = measurable.measure(constraints)
        // TextLayout can be done any time prior to its use in draw, including in a
        // background thread.
        // In this sample, text layout is measured in layout modifier. This way the layout
        // call can be restarted when async font loading completes due to the fact that
        // `.measure` call is executed in `.layout`.
        textLayoutResult =
            textMeasurer.measure(text = "Hello, World!", style = TextStyle(fontSize = 24.sp))
        layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
    }
) {
    // This happens during draw phase.
    textLayoutResult?.let { drawText(it) }
}
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.LocalTextStyle
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints

// We can disable implicit caching since we will cache in DrawWithCache
val textMeasurer = rememberTextMeasurer(cacheSize = 0)
// Apply the current text style from theme, otherwise TextStyle.Default will be used.
val materialTextStyle = LocalTextStyle.current

// Animate color repeatedly
val infiniteTransition = rememberInfiniteTransition()
val color by
    infiniteTransition.animateColor(
        initialValue = Color.Red,
        targetValue = Color.Blue,
        animationSpec = infiniteRepeatable(tween(1000))
    )

Box(
    Modifier.fillMaxSize().drawWithCache {
        // Text layout will be measured just once until the size of the drawing area or
        // materialTextStyle changes.
        val textLayoutResult =
            textMeasurer.measure(
                text = "Hello, World!",
                style = materialTextStyle,
                constraints =
                    Constraints.fixed(
                        width = (size.width / 2).roundToInt(),
                        height = (size.height / 2).roundToInt()
                    ),
                overflow = TextOverflow.Ellipsis
            )
        // color changes will only invalidate draw phase
        onDrawWithContent {
            drawContent()
            drawText(
                textLayoutResult,
                color = color,
                topLeft =
                    Offset(
                        (size.width - textLayoutResult.size.width) / 2,
                        (size.height - textLayoutResult.size.height) / 2,
                    )
            )
        }
    }
)
Parameters
textLayoutResult: TextLayoutResult

Text Layout to be drawn

color: Color = Color.Unspecified

Text color to use

topLeft: Offset = Offset.Zero

Offsets the text from top left point of the current coordinate system.

alpha: Float = Float.NaN

opacity to be applied to the color from 0.0f to 1.0f representing fully transparent to fully opaque respectively

shadow: Shadow? = null

The shadow effect applied on the text.

textDecoration: TextDecoration? = null

The decorations to paint on the text (e.g., an underline).

drawStyle: DrawStyle? = null

Whether or not the text is stroked or filled in.

blendMode: BlendMode = DrawScope.DefaultBlendMode

Blending algorithm to be applied to the text

drawText

fun DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: String,
    topLeft: Offset = Offset.Zero,
    style: TextStyle = TextStyle.Default,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    size: Size = Size.Unspecified,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draw text using a TextMeasurer.

This draw function supports only one text style, and async font loading.

TextMeasurer carries an internal cache to optimize text layout measurement for repeated calls in draw phase. If layout affecting attributes like font size, font weight, overflow, softWrap, etc. are changed in consecutive calls to this method, TextMeasurer and its internal cache that holds layout results may not offer any benefits. Check out TextMeasurer and drawText overloads that take TextLayoutResult to learn more about text layout and draw phase optimizations.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer

val textMeasurer = rememberTextMeasurer()

Canvas(Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello, World!") }
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.sp

val textMeasurer = rememberTextMeasurer()

Canvas(Modifier.fillMaxSize()) {
    drawText(
        textMeasurer = textMeasurer,
        text = "Hello, World!",
        style =
            TextStyle(
                fontSize = 24.sp,
                fontWeight = FontWeight.Bold,
                textDecoration = TextDecoration.Underline
            )
    )
}
Parameters
textMeasurer: TextMeasurer

Measures and lays out the text

text: String

Text to be drawn

topLeft: Offset = Offset.Zero

Offsets the text from top left point of the current coordinate system.

style: TextStyle = TextStyle.Default

the TextStyle to be applied to the text

overflow: TextOverflow = TextOverflow.Clip

How visual overflow should be handled.

softWrap: Boolean = true

Whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If softWrap is false, overflow and TextAlign may have unexpected effects.

maxLines: Int = Int.MAX_VALUE

An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to overflow and softWrap. If it is not null, then it must be greater than zero.

size: Size = Size.Unspecified

how wide and tall the text should be. If left Size.Unspecified as its default value, text will be forced to fit inside the total drawing area from where it's placed. If size is specified, Size.width will define the width of the text. Size.height helps defining the number of lines that fit if softWrap is enabled and overflow is TextOverflow.Ellipsis. Otherwise, Size.height either defines where the text is clipped (TextOverflow.Clip) or becomes no-op.

blendMode: BlendMode = DrawScope.DefaultBlendMode

Blending algorithm to be applied to the text

drawText

fun DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: AnnotatedString,
    topLeft: Offset = Offset.Zero,
    style: TextStyle = TextStyle.Default,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    placeholders: List<AnnotatedString.Range<Placeholder>> = listOf(),
    size: Size = Size.Unspecified,
    blendMode: BlendMode = DrawScope.DefaultBlendMode
): Unit

Draw styled text using a TextMeasurer.

This draw function supports multi-styling and async font loading.

TextMeasurer carries an internal cache to optimize text layout measurement for repeated calls in draw phase. If layout affecting attributes like font size, font weight, overflow, softWrap, etc. are changed in consecutive calls to this method, TextMeasurer and its internal cache that holds layout results may not offer any benefits. Check out TextMeasurer and drawText overloads that take TextLayoutResult to learn more about text layout and draw phase optimizations.

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle

val textMeasurer = rememberTextMeasurer()

Canvas(Modifier.fillMaxSize()) {
    drawText(
        textMeasurer = textMeasurer,
        text =
            buildAnnotatedString {
                withStyle(ParagraphStyle(textAlign = TextAlign.Start)) { append("Hello") }
                withStyle(ParagraphStyle(textAlign = TextAlign.End)) { append("World") }
            }
    )
}
Parameters
textMeasurer: TextMeasurer

Measures and lays out the text

text: AnnotatedString

Text to be drawn

topLeft: Offset = Offset.Zero

Offsets the text from top left point of the current coordinate system.

style: TextStyle = TextStyle.Default

the TextStyle to be applied to the text

overflow: TextOverflow = TextOverflow.Clip

How visual overflow should be handled.

softWrap: Boolean = true

Whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If softWrap is false, overflow and TextAlign may have unexpected effects.

maxLines: Int = Int.MAX_VALUE

An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to overflow and softWrap. If it is not null, then it must be greater than zero.

placeholders: List<AnnotatedString.Range<Placeholder>> = listOf()

a list of Placeholders that specify ranges of text which will be skipped during layout and replaced with Placeholder. It's required that the range of each Placeholder doesn't cross paragraph boundary, otherwise IllegalArgumentException is thrown.

size: Size = Size.Unspecified

how wide and tall the text should be. If left Size.Unspecified as its default value, text will be forced to fit inside the total drawing area from where it's placed. If size is specified, Size.width will define the width of the text. Size.height helps defining the number of lines that fit if softWrap is enabled and overflow is TextOverflow.Ellipsis. Otherwise, Size.height either defines where the text is clipped (TextOverflow.Clip) or becomes no-op.

blendMode: BlendMode = DrawScope.DefaultBlendMode

Blending algorithm to be applied to the text