Compose Canvas

本文详细介绍了Compose中的Canvas组件,包括如何使用drawPoints、drawLine、drawRect等函数绘制各种图形,以及如何设置颜色、线宽、混合模式等属性。重点讲解了点模式、混合模式的使用和示例。
摘要由CSDN通过智能技术生成

Compose Canvas

概述

在Compose中绘制文字、曲线、矩形、圆、椭圆、圆弧、路径、BlendMode等。

Canvas属性

@Composable
fun Canvas(modifier: Modifier, onDraw: DrawScope.() -> Unit) =  
    Spacer(modifier.drawBehind(onDraw))
@DrawScopeMarker
interface DrawScope : Density {

    // 当前的DrawContext,包含创建绘图环境所需的依赖项
    val drawContext: DrawContext

    // 绘图环境当前边界的中心
    val center: Offset
        get() = drawContext.size.center

    // 当前绘图环境的大小(可以通过size获取当前Canvas的宽和高)
    val size: Size
        get() = drawContext.size

    // 绘制版面的版面方向
    val layoutDirection: LayoutDirection

    companion object {

        // 用于每个绘图操作的默认混合模式。这样可以确保将内容绘制在目标中的像素上方
        val DefaultBlendMode: BlendMode = BlendMode.SrcOver
    }
}

drawPoints 绘制点

drawPoints属性

// 方法一:
fun drawPoints(
    points: List<Offset>, // 点的集合
    // Points:点模式;Lines:两点的线模式;Polygon:连续的线模式
    pointMode: PointMode, // 绘制方式
    color: Color, // 颜色
    strokeWidth: Float = Stroke.HairlineWidth, // 宽度
    // Butt:直角,末端无延伸;Round:圆角,末端有延伸;Square:直角,末端有延伸
    cap: StrokeCap = StrokeCap.Butt, // 末端处理
    pathEffect: PathEffect? = null, // 点的可选效果或图案
    alpha: Float = 1.0f, // 透明度
    colorFilter: ColorFilter? = null,  // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

// 方法二:
fun drawPoints(
    points: List<Offset>,
    pointMode: PointMode,
    brush: Brush, // 渐变色
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = StrokeCap.Butt,
    pathEffect: PathEffect? = null,
    alpha: Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
)

使用

使用pointMode属性:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

var pointMode by remember {
    mutableStateOf(PointMode.Points)
}
val scrollState = rememberScrollState()
val points = arrayListOf(
    Offset(100F, 100F),
    Offset(300F, 300F),
    Offset(500F, 500F),
    Offset(700F, 500F),
    Offset(900F, 900F),
)
var text by remember {
    mutableStateOf("PointMode.Points")
}
Column(modifier = Modifier.fillMaxSize()) {
    Row(modifier = Modifier.horizontalScroll(scrollState)) {
        Button(onClick = {
            pointMode = PointMode.Points
            text = "PointMode.Points"
        }) {
            Text("PointMode.Points")
        }
        Button(onClick = {
            pointMode = PointMode.Lines
            text = "PointMode.Lines"
        }) {
            Text("PointMode.Lines")
        }
        Button(onClick = {
            pointMode = PointMode.Polygon
            text = "PointMode.Polygon"
        }) {
            Text("PointMode.Polygon")
        }
    }
    Text(text)
    Canvas(modifier = Modifier
           .size(360.dp)
           .background(Color.LightGray)) {
        drawPoints(
            points = points,
            pointMode = pointMode,
            color = Color.Red,
            strokeWidth = 15F
        )
    }
}

使用brush属性:

在这里插入图片描述

Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawPoints(
        points = points,
        pointMode = PointMode.Polygon,
        cap = StrokeCap.Square,
        strokeWidth = 30F,
        brush = Brush.linearGradient(
            colors = arrayListOf(Color.Red, Color.Green, Color.Blue)
        )
    )
}

上面的颜色是均匀分布的,也可以精确指定每段的颜色,如下:

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawPoints(
        points = points,
        pointMode = PointMode.Polygon,
        cap = StrokeCap.Square,
        strokeWidth = 30F,
        brush = Brush.linearGradient(
            0.0F to Color.Red, 0.2F to Color.Green, 0.8F to Color.Blue
        )
    )
}

drawLine 绘制线

drawLine属性

// 方法一:
fun drawLine(
    color: Color, // 线的颜色
    start: Offset, // 开始坐标
    end: Offset, // 结束坐标
    strokeWidth: Float = Stroke.HairlineWidth, // 线的宽度
    cap: StrokeCap = Stroke.DefaultCap, // 末端处理
    pathEffect: PathEffect? = null, // 线的可选效果或图案
    alpha: Float = 1.0f, // 透明度
    colorFilter: ColorFilter? = null, // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

// 方法二:
fun drawLine(
    brush: Brush, // 渐变色
    start: Offset,
    end: Offset,
    strokeWidth: Float = Stroke.HairlineWidth,
    cap: StrokeCap = Stroke.DefaultCap,
    pathEffect: PathEffect? = null,
    alpha: Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
)

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawLine(
        color = Color.Red,
        start = Offset(100F, 100F),
        end = Offset(900F, 900F),
        strokeWidth = 30F,
        cap = StrokeCap.Round
    )
}

drawRect 绘制矩形

drawRect属性

fun drawRect(
    color: Color, // 颜色
    topLeft: Offset = Offset.Zero, // 顶点
    size: Size = this.size.offsetSize(topLeft), // 尺寸
    alpha: Float = 1.0f, // 透明度
    // Fill:填充;Stroke:边框;
    style: DrawStyle = Fill, // 样式
    colorFilter: ColorFilter? = null, // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

class Stroke(
    val width: Float = 0.0f, // 边的宽度
    val miter: Float = DefaultMiter, // 连接角度
    val cap: StrokeCap = StrokeCap.Butt, // 末端处理
    val join: StrokeJoin = StrokeJoin.Miter, // 边的连接处理
    val pathEffect: PathEffect? = null
) : DrawStyle()

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawRect(
        color = Color.Red,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 400F)
    )
}

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawRect(
        color = Color.Red,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 400F),
        style = Stroke(width = 30F, cap = StrokeCap.Round)
    )
}

drawRoundRect 绘制圆角矩形

drawRoundRect属性

fun drawRoundRect(
    color: Color,
    topLeft: Offset = Offset.Zero,
    size: Size = this.size.offsetSize(topLeft),
    cornerRadius: CornerRadius = CornerRadius.Zero, // 圆角
    style: DrawStyle = Fill,
    alpha: Float = 1.0f,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode
)

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawRoundRect(
        color = Color.Red,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 600F),
        cornerRadius = CornerRadius(50F),
        style = Stroke(width = 30F)
    )
}

drawCircle 绘制圆

drawCircle属性

fun drawCircle(
    color: Color, // 颜色
    radius: Float = size.minDimension / 2.0f, // 半径
    center: Offset = this.center, // 圆形坐标
    alpha: Float = 1.0f, // 透明度
    style: DrawStyle = Fill, // 样式
    colorFilter: ColorFilter? = null, // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawCircle(
        color = Color.Red,
        radius = 300F,
        center = center
    )
}

在这里插入图片描述

Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawCircle(
        color = Color.Red,
        radius = 300F,
        center = center,
        style = Stroke(width = 30F)
    )
}

drawOval 绘制椭圆

drawOval属性

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

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawOval(
        color = Color.Red,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 600F),
        style = Stroke(width = 30F)
    )
}

drawArc 绘制圆弧

drawArc属性

fun drawArc(
    color: Color, // 颜色
    startAngle: Float, // 开始角度
    sweepAngle: Float, // 弧度
    useCenter: Boolean, // 是否使用中心
    topLeft: Offset = Offset.Zero, // 顶点
    size: Size = this.size.offsetSize(topLeft), // 尺寸
    alpha: Float = 1.0f, // 透明度
    style: DrawStyle = Fill, // 样式
    colorFilter: ColorFilter? = null, // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

使用

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawArc(
        color = Color.Red,
        startAngle = 0F,
        sweepAngle = 270F,
        useCenter = true,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 400F)
    )
}

在这里插入图片描述

Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawArc(
        color = Color.Red,
        startAngle = 0F,
        sweepAngle = 270F,
        useCenter = false,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 400F)
    )
}

在这里插入图片描述

Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawArc(
        color = Color.Red,
        startAngle = 0F,
        sweepAngle = 270F,
        useCenter = false,
        topLeft = Offset(100F, 100F),
        size = Size(400F, 400F),
        style = Stroke(width = 5F)
    )
}

drawImage 绘制图片

drawImage属性

// 方式一:
fun drawImage(
    image: ImageBitmap, // 图片
    topLeft: Offset = Offset.Zero, // 顶点
    alpha: Float = 1.0f, // 透明度
    style: DrawStyle = Fill, // 样式
    colorFilter: ColorFilter? = null, // 颜色效果
    blendMode: BlendMode = DefaultBlendMode // 混合模式
)

// 方式二:
fun drawImage(
    image: ImageBitmap,
    srcOffset: IntOffset = IntOffset.Zero, // 设置原图片
    srcSize: IntSize = IntSize(image.width, image.height), // 设置原图片尺寸
    dstOffset: IntOffset = IntOffset.Zero, // 设置目标图片
    dstSize: IntSize = srcSize, // 设置目标图片尺寸
    alpha: Float = 1.0f,
    style: DrawStyle = Fill,
    colorFilter: ColorFilter? = null,
    blendMode: BlendMode = DefaultBlendMode,
    filterQuality: FilterQuality = DefaultFilterQuality
)

使用

在这里插入图片描述

val context = LocalContext.current
val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.a)
val image = bitmap.asImageBitmap()
Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawImage(
        image = image
    )
}

在这里插入图片描述

val context = LocalContext.current
val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.a)
val image = bitmap.asImageBitmap()
Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawImage(
        image = image,
        srcOffset = IntOffset(0, 0),
        srcSize = IntSize(100, 100),
        dstOffset = IntOffset(100, 100),
        dstSize = IntSize(400, 400)
    )
}

drawPath 绘制路径

drawPath属性

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

使用

在这里插入图片描述

val path = Path()
path.moveTo(100F, 300F)
path.lineTo(100F, 700F)
path.lineTo(800F, 700F)
path.lineTo(900F, 300F)
path.lineTo(600F, 100F)
path.close()
Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawPath(
        path = path,
        color = Color.Red,
        style = Stroke(width = 10F)
    )
}

在这里插入图片描述

val path = Path()
path.moveTo(100F, 300F)
path.lineTo(100F, 700F)
path.quadraticBezierTo(800F,700F,600F,100F)
path.cubicTo(700F,200F,800F,400F,100F,100F)
path.close()
Canvas(
    modifier = Modifier
        .size(360.dp)
        .background(Color.LightGray)
) {
    drawPath(
        path = path,
        color = Color.Red,
        style = Stroke(width = 10F)
    )
}

混合模式

混合模式:

在这里插入图片描述

BlendMode类型说明:

在这里插入图片描述

使用:

在这里插入图片描述

Canvas(
    modifier = Modifier
    .size(360.dp)
    .background(Color.LightGray)
) {
    drawCircle(
        color = Color.Yellow,
        radius = 170F,
        center = Offset(350F, 350F),
        blendMode = BlendMode.Clear
    )
    drawRect(
        color = Color.Red,
        topLeft = Offset(300F, 300F),
        size = Size(350F, 350F),
        blendMode = BlendMode.Clear
    )
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安卓的Compose框架是一种用于构建用户界面的现代UI工具包。它与传统的View系统相比,提供了更加简洁、灵活和高效的方式来创建界面元素。 在Compose中监听手势事件并进行相应的绘制操作,可以通过使用Canvas API来实现。首先,我们需要在Compose中创建一个自定义的绘制组件,例如CanvasView。 在这个组件中,我们可以使用Modifier.pointerInput来为Canvas添加手势监听器。例如,我们可以使用onPointerInput函数来监听手势的移动、按下和抬起等事件。 具体实现时,可以在一个PointerEventPass中使用awaitPointerEvent函数来监听手势事件。可以通过event.action来获取手势的动作类型,例如MotionEvent.ACTION_DOWN表示按下动作,MotionEvent.ACTION_MOVE表示移动动作,MotionEvent.ACTION_UP表示抬起动作。 一旦监听到对应的手势动作,我们可以根据事件的坐标信息来更新Canvas上的绘图内容。比如,可以使用Canvas的drawCircle方法在指定位置绘制一个圆形。 除此之外,我们还可以根据手势事件的特性来实现更加复杂的交互效果,例如根据手指的移动来绘制路径、随手势的放大缩小来改变绘制的形状等等。 综上所述,通过在Compose中使用Canvas API并监听手势事件,我们可以实现对Canvas的交互式绘制。这为我们提供了更多创造性的可能性,使我们能够灵活地响应用户的手势操作,并实时更新界面的绘制效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值