Compose中Canvas绘制

Canvas绘制点

Compose中Canvas绘制_第1张图片

 

/**
 * Canvas绘制点
 */
@Composable
fun DrawPointsTest() {
    val points = arrayListOf(
        Offset(100f, 100f),
        Offset(300f, 300f),
        Offset(500f, 500f),
        Offset(700f, 700f),
        Offset(900f, 900f)
    )

    Canvas(modifier = Modifier.size(360.dp)) {
        drawPoints(
            points = points,
            //类型 PointMode.Points:点 PointMode.Lines:线 PointMode.Polygon:多边形
            pointMode = PointMode.Points,
            //颜色
            color = Color.Blue,
            //颜色渐变
//            brush = Brush.linearGradient(
//                0.0f to Color.Red,
//                0.5f to Color.Green,
//                1.0f to Color.Blue
//            ),
            //宽度
            strokeWidth = 30f,
            //Butt表示线段末端轮廓的起始点和结束点带有平缓的边缘,没有延伸;
            //Round表示线段末端以半圆开始和结束的轮廓;
            //Square表示线段末端将每个轮廓延伸笔触宽度的一半。
            cap = StrokeCap.Round
        )
    }
}

Canvas组件下用drawPoints绘制点;points属性添加点坐标;pointMode设置类型:PointMode.Points坐标为点。

PointMode.Lines两坐标点形成线段,不够两坐标最后一个坐标点自动省略不显示。

Compose中Canvas绘制_第2张图片

PointMode.Polygon多边形,多坐标点连线,和drawPath绘制路径类似。

Compose中Canvas绘制_第3张图片

 color属性设置坐标点的颜色。

brush属性设置坐标点或线的渐变。

Compose中Canvas绘制_第4张图片

strokeWidth属性设置坐标点或线的宽度。

cap设置坐标点或线末端是否为圆角。不设置默认为方形坐标点,设置后为圆形坐标点 。不设置实际是这样的点或线。

Compose中Canvas绘制_第5张图片

 

Compose中Canvas绘制_第6张图片

Canvas绘制线

Compose中Canvas绘制_第7张图片

 

/**
 * Canvas绘制线
 */
@Composable
fun DrawLineTest() {
    val start = Offset(100f, 100f)
    val end = Offset(900f, 900f)

    Canvas(modifier = Modifier.size(360.dp)) {
        drawLine(
            //线的颜色
            color = Color.Red,
            //起始点
            start = start,
            //末尾点
            end = end,
            //线宽
            strokeWidth = 30f,
            //线末端圆角
            cap = StrokeCap.Round
        )
    }
}

绘制线用drawLine,start和end起始点坐标点属性有差别外其他属性和绘制点属性基本一致。

Canvas绘制矩形

Compose中Canvas绘制_第8张图片

/**
 * Canvas绘制矩形(实心)
 */
@Composable
fun DrawRectTest() {
    val topLeft = Offset(100f, 100f)
    Canvas(modifier = Modifier.size(360.dp)) {
        drawRect(
            color = Color.Red,
            topLeft = topLeft,
            size = Size(400f, 600f)
        )
    }
}

 Compose中Canvas绘制_第9张图片

 

/**
 * Canvas绘制矩形(空心)
 */
@Composable
fun DrawRectStrokTest() {
    val topLeft = Offset(100f, 100f)
    val rectSize = Size(400f, 600f)
    Canvas(modifier = Modifier.size(360.dp)) {
        drawRect(
            color = Color.Red,
            topLeft = topLeft,
            size = rectSize,
            //Stroke设置空心
            style = Stroke(
                //边框宽度
                width = 30f,
                //用来设置直线和曲线段在描边路径上连接的处理方式
                //StrokeJoin.Miter:尖角 StrokeJoin.Bevel:斜切角 StrokeJoin.Round:圆角
                join = StrokeJoin.Round
            )
        )
    }
}

topLeft属性设置居上居左边距,size属性设置矩形大小。

style属性设置矩形样式,Stroke设置为空心矩形,Stroken内width属性设置矩形线的宽度,join属性设置边框角的形状。

join设置为StrokeJoin.Bevel时矩形边框是这样的斜切角:

Compose中Canvas绘制_第10张图片

不设置或设置为StrokeJoin.Miter为直角。

Compose中Canvas绘制_第11张图片

Canvas绘制圆角矩形 

Compose中Canvas绘制_第12张图片

/**
 * Canvas绘制圆角矩形
 */
@Composable
fun DrawRoundRectTest() {
    val topLeft = Offset(100f, 100f)
    val rectSize = Size(400f, 600f)
    Canvas(modifier = Modifier.size(360.dp)) {
        drawRoundRect(
            color = Color.Red,
            topLeft = topLeft,
            size = rectSize,
            //圆角设置
            cornerRadius = CornerRadius(100f),
            //Stroke设置空心
            style = Stroke(
                //边框宽度
                width = 30f,
                //用来设置直线和曲线段在描边路径上连接的处理方式
                //StrokeJoin.Miter:尖角 StrokeJoin.Bevel:斜切角 StrokeJoin.Round:圆角
                join = StrokeJoin.Round
            )
        )
    }
}

 绘制圆角矩形用drawRoundRect,当矩形宽高一样时,并且圆角角度设置足够大时,矩形就会变成圆形,设置圆角用cornerRadius属性。实心不设置style属性就行。

Canvas绘制圆

Compose中Canvas绘制_第13张图片

 

/**
 * Canvas绘制圆
 */
@Composable
fun DrawCircleTest() {
    Canvas(modifier = Modifier.size(360.dp)) {
        drawCircle(
            color = Color.Blue,
            //居中
            center = center,
            //圆的半径
            radius = 300f,
            //空心设置
            style = Stroke(
                width = 30f
            )
        )
    }
}

drawRoundRect虽然可以绘制圆,但是需要设置矩形宽高一致时并且圆角足够大时才变成圆形。直接用drawCircle可以直接设置圆,只需要通过radius属性设置圆的半径就行了。

Canvas绘制椭圆

Compose中Canvas绘制_第14张图片

/**
 * Canvas绘制椭圆
 */
@Composable
fun DrawOvalTest() {
    val topLeft = Offset(100f, 100f)
    val ovalSize = Size(600f, 800f)
    Canvas(modifier = Modifier.size(360.dp)) {
        drawOval(
            color = Color.Blue,
            //起始位置
            topLeft = topLeft,
            //大小设置
            size = ovalSize,
            //空心设置
            style = Stroke(
                width = 30f
            )
        )
    }
}

 绘制椭圆用drawOval,当椭圆宽高相同时椭圆也会变成圆。

所以Canvas下的drawOval、drawCircle、drawRoundRect都可以设置圆。

Canvas绘制圆弧

Compose中Canvas绘制_第15张图片

 

/**
 * Canvas绘制圆弧
 */
@Composable
fun DrawAcrTest() {
    val ovalSize = Size(600f, 600f)
    Canvas(modifier = Modifier.size(360.dp)) {
        drawArc(
            color = Color.Blue,
            size = ovalSize,
            //起始角度(3点钟方向开始)
            startAngle = 0f,
            //扫描角度
            sweepAngle = 100f,
            //中心对齐
            useCenter = true,
            //空心设置
            style = Stroke(
                width = 20f
            )
        )
    }
}

设置圆弧用drawArc,只需要设置下startAngle和sweepAngle起始角度就可以画出一个扇形或者弧形。

当useCenter属性设置为false时画出就是弧形。

Compose中Canvas绘制_第16张图片

Canvas绘制图片

Compose中Canvas绘制_第17张图片

/**
 * Canvas绘制图片
 */
@Composable
fun DrawImageTest() {
    val context = LocalContext.current
    val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.img)
    val image = bitmap.asImageBitmap()
    Canvas(modifier = Modifier.size(360.dp)) {
        //image -要绘制的源图像
        //srcOffset -可选偏移量,表示要绘制的源图像的左上角偏移量,默认为图像的原点
        //srcSize -相对于srcOffset绘制的源图像的可选尺寸,默认为图像的宽度和高度
        //dstOffset -可选偏移量,表示绘制给定图像的目的地的左上角偏移量,默认为当前平移的原点,开始于绘制图像的目的地的左上角偏移量
        //dstSize -绘制目标的可选尺寸,默认为srcSize
        //alpha -应用于图像的不透明度从0.0f到1.0f,分别表示完全透明到完全不透明
        //样式-指定图像是填充还是矩形描边绘制
        //colorFilter -当绘制到目的地时,将colorFilter应用于图像
        //blendMode -应用于目标的混合算法
        //filterQuality -当图像被缩放并绘制到目的地时,应用于图像的采样算法。默认为FilterQuality。使用双线性采样算法进行缩放
        drawImage(
            image = image,
            srcOffset = IntOffset(0, 0),
            srcSize = IntSize(400, 400),
            dstOffset = IntOffset(100, 100),
            dstSize = IntSize(800, 800)
        )
    }
}

 Canvas下绘制图片用drawImage。

Canvas绘制路径

Compose中Canvas绘制_第18张图片

/**
 * Canvas绘制路径
 */
@Composable
fun DrawPathTest() {
    val path = Path()
    path.moveTo(100f, 100f)
    path.lineTo(100f, 300f)
    path.lineTo(400f, 600f)
    path.lineTo(700f, 300f)
    path.lineTo(700f, 100f)
    path.lineTo(650f, 50f)
    path.lineTo(600f, 50f)
    path.lineTo(400f, 200f)
    path.lineTo(200f, 50f)
    path.lineTo(150f, 50f)
//    path.quadraticBezierTo(800f, 700f, 600f, 100f) // 二阶贝塞尔曲线
//    path.cubicTo(700f, 200f, 800f, 400f, 100f, 100f) // 三阶贝塞尔曲线
    path.close()
    Canvas(modifier = Modifier.size(360.dp)) {
        drawPath(
            //路径设置
            path = path,
            //颜色设置
            color = Color.Red,
            //空心设置
            style = Stroke(
                width = 10f
            )
        )
    }
}

 Canvas下使用drawPath绘制路径,drawPath下path属性路径坐标,路径可用quadraticBezierTo属性添加二阶贝塞尔曲线,cubicTo属性添加三阶贝塞尔曲线。

Canvas混合模式

Compose中Canvas绘制_第19张图片

/**
 * 使用混合模式
 */
@Composable
fun DrawBlendModeTest() {
    Canvas(modifier = Modifier.fillMaxSize()) {
        //左胳膊
        drawRoundRect(
            color = Color(0xFFA5CA39),
            topLeft = Offset(100f, 400f),
            size = Size(120f, 400f),
            //圆角设置
            cornerRadius = CornerRadius(100f)
        )
        //右胳膊
        drawRoundRect(
            color = Color(0xFFA5CA39),
            topLeft = Offset(780f, 400f),
            size = Size(120f, 400f),
            //圆角设置
            cornerRadius = CornerRadius(100f)
        )
        //左触角
        drawLine(
            //线的颜色
            color = Color(0xFFA5CA39),
            //起始点
            start = Offset(350f, 100f),
            //末尾点
            end = Offset(400f, 200f),
            //线宽
            strokeWidth = 20f,
            //线末端圆角
            cap = StrokeCap.Round
        )
        //右触角
        drawLine(
            //线的颜色
            color = Color(0xFFA5CA39),
            //起始点
            start = Offset(650f, 100f),
            //末尾点
            end = Offset(600f, 200f),
            //线宽
            strokeWidth = 20f,
            //线末端圆角
            cap = StrokeCap.Round
        )
        //头
        drawArc(
            color = Color(0xFFA5CA39),
            size = Size(500f, 500f),
            topLeft = Offset(250f, 150f),
            //起始角度
            startAngle = 180f,
            //扫描角度
            sweepAngle = 180f,
            //中心对齐
            useCenter = true
        )
        //左眼
        drawPoints(
            points = arrayListOf(
                Offset(380f, 280f)
            ),
            pointMode = PointMode.Points,
            color = Color(0xFFFFFFFF),
            strokeWidth = 50f,
            cap = StrokeCap.Round
        )
        //右眼
        drawPoints(
            points = arrayListOf(
                Offset(620f, 280f)
            ),
            pointMode = PointMode.Points,
            color = Color(0xFFFFFFFF),
            strokeWidth = 50f,
            cap = StrokeCap.Round
        )
        //身体
        drawPath(
            path = Path().apply {
                addRoundRect(
                    RoundRect(
                        rect = Rect(
                            offset = Offset(250f, 420f),
                            size = Size(500f, 480f),
                        ),
                        bottomLeft = CornerRadius(100f, 100f),
                        bottomRight = CornerRadius(100f, 100f),
                    )
                )
            },
            color = Color(0xFFA5CA39)
        )
        //左腿
        drawPath(
            path = Path().apply {
                addRoundRect(
                    RoundRect(
                        rect = Rect(
                            offset = Offset(350f, 880f),
                            size = Size(120f, 240f),
                        ),
                        bottomLeft = CornerRadius(100f, 100f),
                        bottomRight = CornerRadius(100f, 100f),
                    )
                )
            },
            color = Color(0xFFA5CA39)
        )
        //右腿
        drawPath(
            path = Path().apply {
                addRoundRect(
                    RoundRect(
                        rect = Rect(
                            offset = Offset(550f, 880f),
                            size = Size(120f, 240f),
                        ),
                        bottomLeft = CornerRadius(100f, 100f),
                        bottomRight = CornerRadius(100f, 100f),
                    )
                )
            },
            color = Color(0xFFA5CA39)
        )
    }
}

 我这里使用的是drawRoundRect绘制圆角矩形的方式绘制的胳膊,使用drawLine绘制线的方式绘制的触角,使用drawArc绘制圆弧的方式绘制的头,使用drawPoints绘制点的方式绘制的眼睛,使用drawPath绘制路径的方式绘制的身体和腿。

当然绘制各种形状方法不是唯一性的,欢迎探讨更多更简单实用的Compose绘制方法。

你可能感兴趣的:(Compose,Compose,Canvas,自定义View)