在Compose中,作用域的概念随处可见,自定义图形也相同。下面一段代码,创立一个Canvas的作用域,并讲其规模指定为父元素中的一切可用空间:
Canvas(modifier = Modifier.fillMaxSize()) {
}
一、制造图形
- drawLine:制造直线
- drawCircle:制造圆形
- drawRect:制造矩形
1. drawLine(制造直线)
参数 | 类型 | 描绘 | 其他说明 |
---|---|---|---|
brush | Brush | 线条颜色组合 | 可用于制造骤变色,与color 特色二选一 |
color | Color | 线条颜色 | |
start | Offset | 线条开端坐标 | |
end | Offset | 线条中止坐标 | |
strokeWidth | Float | 线条宽度 | |
cap | StrokeCap | 线两头的样式 | Butt:无头 Round:圆头 Square:方头 |
pathEffect | PathEffect? | 设置线的闪现作用 | cornerPathEffect:衔接线段之间的夹角用一种更平滑的办法衔接 dashPathEffect:将线段虚线化 chainPathEffect:可分别设置外部效应和内部效应的途径 stampedPathEffect:运用特定的形状来制造途径 |
alpha | Float | 通明度 | 取值:[0.0, 1.0] |
colorFilter | ColorFilter? | 颜色过滤器 | |
blendMode | BlendMode | 混合方式 | 这个后面再说 |
@Composable
fun CanvasLine() {
val pathList: List<Pair<PathEffect, String>> = listOf(
Pair(PathEffect.cornerPathEffect(6f), "cornerPathEffect"),
Pair(PathEffect.dashPathEffect(intervals = floatArrayOf(25f, 25f, 5f, 10f)), "dashPathEffect")
)
val strokeWidth = remember { mutableStateOf(20) }
val color = remember { mutableStateOf(Color.Blue) }
val cap = remember { mutableStateOf(StrokeCap.Butt) }
val alpha = remember { mutableStateOf(1f) }
val pathEffect = remember { mutableStateOf(pathList[0].first) }
Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
......
Canvas(
modifier = Modifier
.width(200.dp)
.height(400.dp),
onDraw = {
val canvasWidth = size.width
val canvasHeight = size.height
drawLine(
color = color.value,
start = Offset(x = canvasWidth * 3 / 4, y = canvasHeight / 4),
end = Offset(x = canvasWidth / 4, y = canvasHeight * 3 / 4),
strokeWidth = strokeWidth.value.toFloat(),
cap = cap.value,
pathEffect = pathEffect.value,
alpha = alpha.value
)
})
}
}
2. drawCircle(制造圆形)
参数 | 类型 | 描绘 | 其他说明 |
---|---|---|---|
brush | Brush | 线条颜色组合 | 可用于制造骤变色,与color 特色二选一 |
color | Color | 线条颜色 | |
radius | Float | 半径 | 默认为Canvas的宽与高之中较小的值 |
center | Offset | 圆心偏移量 | 默认值在Canvas区域的中心点 |
alpha | Float | 通明度 | 取值:[0.0, 1.0] |
style | DrawStyle | 图形的制造风格 | Fill:实心 Stroke:空心 |
@Composable
fun CanvasCircle() {
Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
val color = remember { mutableStateOf(Color.Blue) }
val radiusParent = remember { mutableStateOf(1f) }
val centerXOffset = remember { mutableStateOf(0) }
val centerYOffset = remember { mutableStateOf(0) }
val alpha = remember { mutableStateOf(1f) }
val drawStyle: MutableState<DrawStyle> = remember { mutableStateOf(Fill) }
......
Canvas(
modifier = Modifier.size(200.dp),
onDraw = {
drawCircle(
color = color.value,
radius = size.minDimension * radiusParent.value / 2.0f,
center = Offset(this.center.x + centerXOffset.value, this.center.y + centerYOffset.value),
alpha = alpha.value,
style = drawStyle.value
)
})
}
}
3. drawRect(制造矩形)
参数 | 类型 | 描绘 | 其他说明 |
---|---|---|---|
brush | Brush | 线条颜色组合 | 可用于制造骤变色,与color 特色二选一 |
color | Color | 线条颜色 | |
topLeft | Offset | 左上角的偏移量 | 默认为(0, 0) |
size | Size | 矩形的标准 | 默认为Canvas的标准 |
alpha | Float | 通明度 | 取值:[0.0, 1.0] |
style | DrawStyle | 图形的制造风格 | Fill:实心 Stroke:空心 |
@Composable
fun CanvasRect() {
Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
val color = remember { mutableStateOf(Color.Blue) }
val topLeftXOffset = remember { mutableStateOf(0) }
val topLeftYOffset = remember { mutableStateOf(0) }
val width = remember { mutableStateOf(200) }
val height = remember { mutableStateOf(200) }
val alpha = remember { mutableStateOf(1f) }
val drawStyle: MutableState<DrawStyle> = remember { mutableStateOf(Fill) }
......
Canvas(
modifier = Modifier.size(200.dp),
onDraw = {
drawRect(
color = color.value,
topLeft = Offset(topLeftXOffset.value.toFloat(), topLeftYOffset.value.toFloat()),
size = Size(width = width.value.toFloat(), height = height.value.toFloat()),
alpha = alpha.value,
style = drawStyle.value
)
})
}
}
4. drawArc(制造弧线)
参数 | 类型 | 描绘 | 其他说明 |
---|---|---|---|
brush | Brush | 线条颜色组合 | 可用于制造骤变色,与color 特色二选一 |
color | Color | 线条颜色 | |
startAngle | Float | 开端角度 | 当取值为0时,开端角度为时钟3点钟方向的方位; 当取值为a时,开端角度为时钟3点钟方向按顺时针方向a度的方位。 |
sweepAngle | Float | 持续角度 | 弧线持续的角度(顺时针方向为正值) |
useCenter | Boolean | 是否制造弦 | |
topLeft | Offset | 左上角的偏移量 | 默认为(0, 0) |
size | Size | 标准 | 默认为Canvas的标准 |
alpha | Float | 通明度 | 取值:[0.0, 1.0] |
style | DrawStyle | 图形的制造风格 | Fill:实心 Stroke:空心 |
@Composable
fun CanvasArc() {
val color = remember { mutableStateOf(Color.Blue) }
val startAngle = remember { mutableStateOf(0f) }
val sweepAngle = remember { mutableStateOf(180f) }
val useCenter = remember { mutableStateOf(false) }
val topLeftXOffset = remember { mutableStateOf(0) }
val topLeftYOffset = remember { mutableStateOf(0) }
val width = remember { mutableStateOf(200) }
val height = remember { mutableStateOf(200) }
val alpha = remember { mutableStateOf(1f) }
val drawStyle: MutableState<DrawStyle> = remember { mutableStateOf(Stroke(width = 8f)) }
Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
......
Canvas(
modifier = Modifier
.background(Color.LightGray)
.width(200.dp)
.height(200.dp),
onDraw = {
drawArc(
color = color.value,
startAngle = startAngle.value,
sweepAngle = sweepAngle.value,
useCenter = useCenter.value,
topLeft = Offset(topLeftXOffset.value.toFloat(), topLeftYOffset.value.toFloat()),
size = Size(width.value.dp.toPx(), height.value.dp.toPx()),
alpha = alpha.value,
style = drawStyle.value
)
})
}
}
5. drawPath(制造途径)
参数 | 类型 | 描绘 | 其他说明 |
---|---|---|---|
path | Path | 途径 | 制造的途径 |
brush | Brush | 线条颜色组合 | 可用于制造骤变色,与color 特色二选一 |
color | Color | 线条颜色 | |
alpha | Float | 通明度 | 取值:[0.0, 1.0] |
style | DrawStyle | 图形的制造风格 | Fill:实心 Stroke:空心 |
@Composable
fun CanvasCustom() {
Column(modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
val color = remember { mutableStateOf(Color.Blue) }
val alpha = remember { mutableStateOf(1f) }
val drawStyle: MutableState<DrawStyle> = remember { mutableStateOf(Stroke(width = 8f)) }
......
Canvas(
modifier = Modifier
.background(Color.LightGray)
.size(200.dp),
onDraw = {
//制造一个五角星
//指定五角星的5个极点坐标
val point1 = Offset(100.dp.toPx(), 0.dp.toPx())
val point2 = Offset(38.dp.toPx(), 200.dp.toPx())
val point3 = Offset(200.dp.toPx(), 78.dp.toPx())
val point4 = Offset(0.dp.toPx(), 78.dp.toPx())
val point5 = Offset(162.dp.toPx(), 200.dp.toPx())
drawPath(
path = Path().apply {
//移动到开端点
moveTo(point1.x, point1.y)
//制造直线
lineTo(point2.x, point2.y)
lineTo(point3.x, point3.y)
lineTo(point4.x, point4.y)
lineTo(point5.x, point5.y)
//封闭图形(回到开端点)
close()
},
color = color.value,
alpha = alpha.value,
style = drawStyle.value
)
})
}
}
二、图形转换
特色 | 描绘 | 其他说明 |
---|---|---|
scale | 缩放 | 参数中的scale、scaleX、scaleY均标明缩放的倍数 |
translate | 平移 | 参数中的left、top分别标明向左/向上平移的像素 |
rotate | 旋转 | 参数中degrees标明按顺时针选转的角度,pivot表的旋转的中心点 |
inset | 边衬区 | 可更改制造距离和平移制造,为制造的图形增加内边距 |
withTransform | 组合多个转换 |
Canvas(
modifier = Modifier.size(200.dp)
) {
withTransform({
scale(scale = scale.value, pivot = center)
translate(left = translateX.value, top = translateY.value)
rotate(degrees = degrees.value, pivot = center)
}) {
drawImage(image = imageBitmap)
}
}
只需要单独运用其间一种转换办法的话,可以这样:
scale(scale = scale.value, pivot = center) {
drawImage(image = imageBitmap)
}
translate(left = translateX.value, top = translateY.value) {
drawImage(image = imageBitmap)
}
rotate(degrees = degrees.value, pivot = center) {
drawImage(image = imageBitmap)
}
三、骤变Brush
颜色骤变的办法有很多种,比如线性骤变,发散骤变等。各种办法都有着对应的api,但总结起来所需要的参数无非就是如下三种:颜色集结、开端方位、平铺方式。
fun xxxGradient(颜色集结, 颜色集结作用的开端规模, tileMode(平铺方式))
-
颜色集结:在开端规模内的颜色骤变次第。其传参类型有两种挑选,
Pair<Float, Color>
和List<Color>
,前者可根据Float
的数值对每个颜色的占比进行分配,后者标明每个颜色骤变中地点的方位是以开端方位(0)到中止方位(1)进行均分的方位。//开端方位为黄色,到20%的方位骤变为赤色,再到完毕的方位骤变为蓝色 val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) //如下两种办法等价: //开端方位为黄色,到20%的方位骤变为赤色,再到完毕的方位骤变为蓝色 val colors = listOf(Color.Yellow, Color.Red, Color.Blue) val colors = arrayOf( 0.0f to Color.Yellow, 0.5f to Color.Red, 1f to Color.Blue )
-
tileMode:可选值有
Clamp
、Repeated
、Mirror
、Decal
。- Clamp:边沿固定为毕竟的颜色。然后,它会将区域的剩下空间制造为间隔最近的颜色。
- Repeated:边沿按从终究一种颜色到第一种颜色的次第镜像。
- Mirror:边沿按从终究一种颜色到第一种颜色的次第镜像。
- Decal:仅在距离大小的规模内烘托。
TileMode.Decal
使用通明的黑色对原始距离以外的内容进行采样,而TileMode.Clamp
对边沿颜色进行采样。
-
方向
- linearGradient:线性
- horizontalGradient:横向
- verticalGradient:纵向
- radialGradient:径向
- sweepGradient:发散