Jetpack Compose Drawing Canvas、DrawScope 和 Modifier.drawWithContent、BlendMode 解释
这篇文章我们会介绍Compose中如何去自定义绘制一些图形,会介绍Canvas,DrawScope,以及Modifier.drawWithContent的用法。
一 :Canvas,DrawScope
先来看看代码:
@Composable
fun Canvas(modifier: Modifier, onDraw: DrawScope.() -> Unit) =
Spacer(modifier.drawBehind(onDraw))
- modifier 修饰符以前的文章讲过Modifier用法详解
- onDraw 其实就是DrawScope。DrawScope点进去查看代码,主要有如下几个方法
- drawLine 画线
- drawRect 画矩形
- drawRoundRect 画圆角矩形
- drawImage 绘制图片
- drawCircle 画圆形
- drawOval 画椭圆形
- drawArc 画弧度跟扇形
- drawPath 画路径
- drawPoints 画点 还有如下几个扩展方法
- inset 将DrawScope坐标空间平移
- translate 平移坐标
- rotate(旋转坐标)讲的是旋转了多少角度,rotateRad(旋转坐标)讲的是旋转了多少弧度
- scale 缩放坐标
- clipRect 裁剪矩形区域,绘制在裁剪好的矩形区域内。ClipOp.Difference从当前剪辑中减去提供的矩形。
- clipPath 裁剪路径
- drawIntoCanvas 直接提供底层画布
- withTransform 组合转换 我们看到会有很多的绘制的方法,一个个来看,一个个来试
1.1 DrawScope的drawLine 方法
fun drawLine(
brush: Brush,
start: Offset,
end: Offset,
strokeWidth: Float = Stroke.HairlineWidth,
cap: StrokeCap = Stroke.DefaultCap,
pathEffect: PathEffect? = null,
/*FloatRange(from = 0.0, to = 1.0)*/
alpha: Float = 1.0f,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
fun drawLine(
color: Color,
start: Offset,
end: Offset,
strokeWidth: Float = Stroke.HairlineWidth,
cap: StrokeCap = Stroke.DefaultCap,
pathEffect: PathEffect? = null,
/*FloatRange(from = 0.0, to = 1.0)*/
alpha: Float = 1.0f,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
- brush 是刷子,就填充线的颜色的刷子,主要是处理渐变的。有几种实现如下:\
- 线性的渐变
@Stable fun linearGradient( vararg colorStops: Pair<Float, Color>, start: Offset = Offset.Zero, end: Offset = Offset.Infinite, tileMode: TileMode = TileMode.Clamp ){...} @Stable fun linearGradient( colors: List<Color>, start: Offset = Offset.Zero, end: Offset = Offset.Infinite, tileMode: TileMode = TileMode.Clamp ){...}
-
colorStops跟colors 都是渐变颜色
-
start 开始的位置
-
end 结束的位置
-
tileMode 有三种 TileMode.Clamp(默认就是这种,最接近该区域的点的颜色),TileMode.Repeated(边从第一种颜色重复到最后一种颜色),TileMode.Mirror (边从最后一种颜色镜像到第一种颜色)
- 水平方向的渐变
@Stable fun horizontalGradient( colors: List<Color>, startX: Float = 0.0f, endX: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp ){...} @Stable fun horizontalGradient( vararg colorStops: Pair<Float, Color>, startX: Float = 0.0f, endX: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp ){...}
-
colors,colorStops都是渐变的颜色
-
startX 开始的x轴坐标
-
endX 结束的x轴坐标
-
tileMode 跟上面一样
- 竖直方向的渐变
@Stable fun verticalGradient( colors: List<Color>, startY: Float = 0.0f, endY: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp ) @Stable fun verticalGradient( vararg colorStops: Pair<Float, Color>, startY: Float = 0f, endY: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp )
- colors,colorStops都是渐变的颜色
- startY 开始的y坐标
- endY 结束的y坐标
- tileMode 跟上面一致 4.径向的渐变
@Stable fun radialGradient( vararg colorStops: Pair<Float, Color>, center: Offset = Offset.Unspecified, radius: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp ){...} @Stable fun radialGradient( colors: List<Color>, center: Offset = Offset.Unspecified, radius: Float = Float.POSITIVE_INFINITY, tileMode: TileMode = TileMode.Clamp ){...}
- colorStops,colors 都是渐变的颜色
- center 圆形的坐标
- radius 半径
- tileMode 跟上面一致
- 扫描的渐变
@Stable fun sweepGradient( vararg colorStops: Pair<Float, Color>, center: Offset = Offset.Unspecified ) @Stable fun sweepGradient( colors: List<Color>, center: Offset = Offset.Unspecified )
- colorStops 跟colors 都是渐变的颜色
- center 扫描的中心点
- color 是线的颜色
- start 是线的起始点位置
- end 是线的终点位置
- strokeWidth 线的宽度
- cap 线段末端的形状。 三种取值
- StrokeCap.Butt平的效果(以平边开始和结束轮廓,没有延伸。)
- StrokeCap.Round 圆形效果(以半圆延伸开始和结束轮廓)
- StrokeCap.Square 平的效果(以半正方形延伸开始和结束轮廓)
- pathEffect 设置显示效果(比如虚线)。实现有如下几种
- PathEffect.cornerPathEffect(radius: Float) 将线段之间的锐角替换为指定半径的圆角 radius是半径
- PathEffect.dashPathEffect(intervals: FloatArray, phase: Float = 0f) 将形状绘制为具有给定间隔的一系列破折号。比如虚线 例如interval={20,5},第一个参数表示虚线的长度是20,5是虚线之间的间隔是5. phase 偏移
- PathEffect.chainPathEffect(outer: PathEffect, inner: PathEffect) 创建一个PathEffect,将内部效果应用于路径,然后应用外部效果
- PathEffect.stampedPathEffect(shape: Path, advance: Float, phase: Float,style: StampedPathEffectStyle) 用path表示的指定形状冲压绘制的路径. shape要踩踏的路径,advance 每个冲压形状之间的前进间距, phase 在压印第一个形状之前要偏移的相位量, style如何在每个位置转换形状,因为它是冲压. style有三种取值 StampedPathEffectStyle.Translate 平移 ,StampedPathEffectStyle.Rotate 旋转,StampedPathEffectStyle.Morph 变形
- alpha 透明度
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式。这个后面单独讲 举例划线的例子如下:
@Preview
@Composable
fun customDrawView(){
Canvas(modifier = Modifier.fillMaxSize(),onDraw = {
val w = size.width
val h = size.height
// 蓝色的线
drawLine(
start = Offset(100f,100f),
end = Offset(w-100f,100f),
color = Color.Blue,
strokeWidth = 10f,
cap = StrokeCap.Square,
alpha = 1f
)
// 渐变的线
drawLine(
brush = Brush.linearGradient(
0.0f to Color.Red,
0.3f to Color.Green,
1.0f to Color.Blue,
start = Offset(100f, 150f),
end = Offset(w-100f, 150f),
tileMode = TileMode.Repeated),
start = Offset(100f,150f),
end = Offset(w-100f,150f),
strokeWidth = 10f,
cap = StrokeCap.Round,
alpha = 1f
)
// 横向渐变的线
drawLine(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.3f to Color.Green,
1.0f to Color.Blue,
startX = 100f,
endX = w-100f,
tileMode = TileMode.Mirror),
start = Offset(100f,200f),
end = Offset(w-100f,200f),
strokeWidth = 10f,
cap = StrokeCap.Butt,
alpha = 1f
)
// 竖直渐变的线
drawLine(
brush = Brush.verticalGradient(
0.0f to Color.Red,
0.3f to Color.Green,
1.0f to Color.Blue,
startY = 250f,
endY = 350f,
tileMode = TileMode.Clamp),
start = Offset(100f,250f),
end = Offset(100f,350f),
strokeWidth = 10f,
cap = StrokeCap.Round,
alpha = 1f
)
// 横向渐变的有 pathEffect.dashPathEffect的虚线
drawLine(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.5f to Color.Yellow,
1.0f to Color.Blue,
startX = 100f,
endX = w-100f,
tileMode = TileMode.Clamp),
start = Offset(100f,450f),
end = Offset(w-100f,450f),
strokeWidth = 10f,
cap = StrokeCap.Butt,
alpha = 1f,
pathEffect = PathEffect.dashPathEffect(floatArrayOf(100f,20f),10f)
)
})
}
效果如下:
1.2 drawRect 和 drawRoundRect 绘制矩形跟圆角矩形
DrawScope里drawRect跟drawRoundRect的代码如下:
fun drawRect(
brush: Brush,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
fun drawRect(
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
)
fun drawRoundRect(
brush: Brush,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
cornerRadius: CornerRadius = CornerRadius.Zero,
/*@FloatRange(from = 0.0, to = 1.0)*/
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
fun drawRoundRect(
color: Color,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
cornerRadius: CornerRadius = CornerRadius.Zero,
style: DrawStyle = Fill,
/*@FloatRange(from = 0.0, to = 1.0)*/
alpha: Float = 1.0f,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
- brush 刷子跟上面讲解drawline的一样
- color 颜色
- topLeft 左上角点的坐标
- size 大小,比如Size(w,h) w是宽度,h是高度
- cornerRadius 是具体的圆角
- alpha 透明度
- style DrawStyle 可以是Fill填充,也可以是Stroke,线条
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 后面讲 举例:
@Preview
@Composable
fun drawRectTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val w= size.width
val h = size.height
// 蓝底的矩形
drawRect(
color = Color.Blue,
topLeft = Offset(100f,100f),
size = Size(100f,100f),
alpha = 1f,
style = Fill
)
// 渐变的矩形
drawRect(
brush = Brush.linearGradient(
0.0f to Color.Red,
0.3f to Color.Green,
1.0f to Color.Blue,
start = Offset(300f, 100f),
end = Offset(300f, 200f),
tileMode = TileMode.Repeated),
topLeft = Offset(300f,100f),
size = Size(100f,100f),
alpha = 1f,
style = Fill
)
// 线框的矩形
drawRect(
color = Color.Blue,
topLeft = Offset(100f,300f),
size = Size(100f,100f),
alpha = 1f,
style = Stroke(width=1f,cap = StrokeCap.Butt)
)
// 线框的矩形
drawRoundRect(
color = Color.Blue,
topLeft = Offset(300f,300f),
size = Size(300f,100f),
alpha = 1f,
style = Fill,
cornerRadius = CornerRadius(10f,10f)
)
// 渐变的矩形
drawRoundRect(
brush = Brush.linearGradient(
0.0f to Color.Red,
0.3f to Color.Green,
1.0f to Color.Blue,
start = Offset(300f, 450f),
end = Offset(600f, 550f),
tileMode = TileMode.Repeated),
topLeft = Offset(300f,450f),
size = Size(300f,100f),
alpha = 1f,
style = Fill,
cornerRadius = CornerRadius(10f,10f)
)
}
}
效果图:
1.3 drawImage 绘制图片
DrawScope里绘制图片的代码如下:
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
)
- image 图片
- topLeft 左上角
- alpha 透明度
- style 绘制类型是Fill还是Stoke
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式后面讲
- srcOffset IntOffset类型原图像的偏移
- srcSize IntSize类型 原图像的大小
- dstOffset IntOffset 类型目标图像的左上角的位置
- dstSize IntSize大小 目标图像的大小 举例:
@Preview
@Composable
fun drawImageTest(){
val imageBitmap = ImageBitmap.imageResource(id = R.drawable.icon_head)
Canvas(modifier = Modifier.fillMaxSize()) {
val w= size.width
val h = size.height
drawImage(
image = imageBitmap,
topLeft = Offset(50f,50f),
alpha = 1f,
style = Fill
)
drawImage(
image = imageBitmap,
srcOffset = IntOffset(0,0),
srcSize = IntSize(imageBitmap.width,imageBitmap.height),
dstOffset = IntOffset(50,imageBitmap.height+100),
dstSize = IntSize(200,200),
blendMode = BlendMode.SrcOver
)
}
}
效果图:
1.4 drawCircle绘制圆形
DrawScope里drawCircle的代码如下:
fun drawCircle(
brush: Brush,
radius: Float = size.minDimension / 2.0f,
center: Offset = this.center,
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
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
)
- brush 刷子跟上面一致
- color 颜色
- radius 半径
- center 圆形
- alpha 透明度
- style 填充方式 Fill跟Stroke
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 后面讲
举例:
@Preview
@Composable
fun drawCircleTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val w= size.width
val h = size.height
drawCircle(
color = Color.Red,
radius = 100f,
center = Offset(150f,150f),
alpha = 1f,
style = Fill
)
drawCircle(
color = Color.Red,
radius = 100f,
center = Offset(400f,150f),
alpha = 1f,
style = Stroke(width = 5f)
)
drawCircle(
brush = Brush.radialGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
center = Offset(150f,360f),
radius = 100f,
tileMode = TileMode.Clamp
),
radius = 100f,
center = Offset(150f,360f),
alpha = 1f,
style = Fill
)
}
}
效果图:
1.5 drawOval绘制椭圆形
DrawScope中drawOval的代码:
fun drawOval(
brush: Brush,
topLeft: Offset = Offset.Zero,
size: Size = this.size.offsetSize(topLeft),
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
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
)
- brush 刷子跟上面一致
- color 颜色
- topLeft 左上角的坐标
- size 大小
- alpha 透明度
- style 填充类型
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 后面讲 举例:
@Preview
@Composable
fun drawOvalTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val w= size.width
val h = size.height
drawOval(
color = Color.Red,
topLeft = Offset(50f,50f),
size = Size(200f,100f),
alpha = 1f,
style = Stroke(width = 5f)
)
drawOval(
color = Color.Red,
topLeft = Offset(300f,50f),
size = Size(200f,100f),
alpha = 1f,
style = Fill
)
drawOval(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
startX = 50f,
endX = 250f,
),
topLeft = Offset(50f,180f),
size = Size(200f,100f),
alpha = 1f,
style = Fill
)
}
}
效果图:
1.6 drawArc 绘制弧跟扇形
DrawScope中drawArc代码如下:
fun drawArc(
brush: Brush,
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
)
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
)
- brush 刷子
- color 颜色
- startAngle 开始的角度
- sweepAngle 划过的角度
- useCenter 是否连接圆心
- topLeft 左上角的位置
- size 大小
- alpha 透明度
- style 填充模式
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 后面讲 举例:
@Preview
@Composable
fun drawArcTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val w= size.width
val h = size.height
drawArc(
color = Color.Red,
startAngle = 90f,
sweepAngle = 100f,
useCenter = false,
alpha = 1f,
style = Fill,
topLeft = Offset(50f,50f),
size = Size(200f,200f)
)
drawArc(
color = Color.Red,
startAngle = 0f,
sweepAngle = 100f,
useCenter = true,
alpha = 1f,
style = Fill,
topLeft = Offset(150f,50f),
size = Size(200f,200f)
)
drawArc(
color = Color.Red,
startAngle = 0f,
sweepAngle = 100f,
useCenter = false,
alpha = 1f,
style = Stroke(width = 5f),
topLeft = Offset(300f,50f),
size = Size(200f,200f)
)
drawArc(
color = Color.Red,
startAngle = 0f,
sweepAngle = 100f,
useCenter = true,
alpha = 1f,
style = Stroke(width = 5f),
topLeft = Offset(500f,50f),
size = Size(200f,200f)
)
drawArc(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
startX = 50f,
endX = 250f,
),
startAngle = 0f,
sweepAngle = 100f,
useCenter = true,
alpha = 1f,
style = Stroke(width = 5f),
topLeft = Offset(50f,350f),
size = Size(200f,200f)
)
drawArc(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
startX = 200f,
endX = 450f,
),
startAngle = 0f,
sweepAngle = 100f,
useCenter = true,
alpha = 1f,
style = Fill,
topLeft = Offset(200f,350f),
size = Size(200f,200f)
)
}
}
效果图如下:
1.7 drawPath 绘制路径
fun drawPath(
path: Path,
color: Color,
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
fun drawPath(
path: Path,
brush: Brush,
alpha: Float = 1.0f,
style: DrawStyle = Fill,
colorFilter: ColorFilter? = null,
blendMode: BlendMode = DefaultBlendMode
)
- path 路径
- brush 刷子
- color 颜色
- alpha 透明度
- style 填充类型
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 举例:
@Preview
@Composable
fun drawPathTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val path = Path()
path.moveTo(50f,50f)
path.lineTo(50f,150f)
path.lineTo(200f,50f)
path.close()
drawPath(
path = path,
color = Color.Red
)
path.moveTo(50f,200f)
path.lineTo(50f,350f)
path.lineTo(200f,200f)
path.close()
drawPath(
path = path,
color = Color.Red,
style = Stroke(width = 4f)
)
}
}
效果图如下:
1.8 drawPoints 绘制点
fun drawPoints(
points: List<Offset>,
pointMode: PointMode,
color: Color,
strokeWidth: Float = Stroke.HairlineWidth,
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
)
- points 点的集合
- pointMode 用于指示如何绘制点。有三种取值PointMode.Points 分别画点,PointMode.Lines 画线(点集合两两组合划线,奇数的话最后一个不管),PointMode.Polygon 画多边形
- color 颜色
- brush 刷子 设置渐变
- strokeWidth 宽度
- pathEffect 跟上面drawLine的一致
- alpha 透明度
- colorFilter 用于修改在其安装的[Paint]上绘制的每个像素的颜色的效果。Image讲解里有讲到
- blendMode 混合模式 举例:
@Preview
@Composable
fun drawPointsTest(){
Canvas(modifier = Modifier.fillMaxSize()) {
val points = ArrayList<Offset>().apply {
add(Offset(50f,50f))
add(Offset(100f,50f))
add(Offset(100f,100f))
add(Offset(80f,100f))
}
val points2 = ArrayList<Offset>().apply {
add(Offset(50f,250f))
add(Offset(100f,250f))
add(Offset(100f,300f))
add(Offset(80f,300f))
add(Offset(300f,300f))
}
val points3 = ArrayList<Offset>().apply {
add(Offset(250f,250f))
add(Offset(300f,250f))
add(Offset(300f,300f))
add(Offset(280f,300f))
add(Offset(250f,250f))
}
drawPoints(
points = points,
pointMode = PointMode.Points,
color = Color.Blue,
strokeWidth = 15f,
alpha = 1f
)
drawPoints(
points = points2,
pointMode = PointMode.Lines,
color = Color.Blue,
strokeWidth = 5f,
alpha = 1f
)
drawPoints(
points = points3,
pointMode = PointMode.Polygon,
color = Color.Blue,
strokeWidth = 5f,
cap = StrokeCap.Round,
alpha = 1f
)
}
}
效果如下:
1.9 inset 平移坐标
inset是将DrawScope坐标空间平移,inset的代码如下:
inline fun DrawScope.inset(
left: Float,
top: Float,
right: Float,
bottom: Float,
block: DrawScope.() -> Unit
){...}
inline fun DrawScope.inset(
horizontal: Float = 0.0f,
vertical: Float = 0.0f,
block: DrawScope.() -> Unit
){...}
inline fun DrawScope.inset(
inset: Float,
block: DrawScope.() -> Unit
){...}
- left左边平移多少
- top 顶部平移多少
- right 右边平移多少
- bottom 底部平移多少
- horizontal 横向平移多少
- vertical 竖向平移多少
- inset 我们通过一个例子:绘制一个矩形,宽高是分别是屏幕宽高的一半,同时绘制一个inset了屏幕一半宽高的矩形。代码如下:
@Preview
@Composable
fun drawInsetTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasQuadrantSize = size / 2F
drawRect(
color = Color.Green,
size = canvasQuadrantSize
)
inset(canvasQuadrantSize.width,canvasQuadrantSize.height){
drawRect(
color = Color.Red,
size = canvasQuadrantSize
)
}
}
}
效果如图:左上角的是正常绘制的矩形,右下角的是通过inset平移了的
2.0 translate 平移坐标
translate平移坐标,代码如下:
inline fun DrawScope.translate(
left: Float = 0.0f,
top: Float = 0.0f,
block: DrawScope.() -> Unit
){...}
- left 左边平移多少
- top顶部平移多少 举例:
@Preview
@Composable
fun drawTranslateTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasQuadrantSize = size / 2F
translate(canvasQuadrantSize.width,0f){
drawRect(
color = Color.Blue,
size = canvasQuadrantSize
)
}
}
}
效果如下:
2.1 rotate,rotateRad 旋转坐标
rotate,和rotateRad都是旋转,但是rotate的是旋转了多少角度,rotateRad是旋转了多少弧度。,代码如下:
inline fun DrawScope.rotate(
degrees: Float,
pivot: Offset = center,
block: DrawScope.() -> Unit
){...}
inline fun DrawScope.rotateRad(
radians: Float,
pivot: Offset = center,
block: DrawScope.() -> Unit
){...}
- degrees 顺时针旋转的角度
- pivot 旋转的中心点 (默认是图形的中心)
- radians 顺时针旋转的弧度
- pivot 旋转的中心点(默认是图形的中心) 举例:
@Preview
@Composable
fun drawRotateTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasSize = size
val canvasWidth = size.width
val canvasHeight = size.height
rotate(degrees = 45F){
drawRect(
color = Color.Gray,
topLeft = Offset(x = canvasWidth / 3F , y = canvasHeight / 3F),
size = canvasSize / 3F
)
}
}
}
@Preview
@Composable
fun drawRotateRabTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasSize = size
val canvasWidth = size.width
val canvasHeight = size.height
rotateRad(45F){
drawRect(
color = Color.Red,
topLeft = Offset(x = canvasWidth / 3F , y = canvasHeight / 3F),
size = canvasSize / 3F
)
}
}
}
drawRotateTest的效果如下,drawRotateRabTest的可以自行运行代码查看效果
2.2 scale 缩放坐标
scale 是缩放坐标,代码如下:
inline fun DrawScope.scale(
scale: Float,
pivot: Offset = center,
block: DrawScope.() -> Unit
){...}
inline fun DrawScope.scale(
scaleX: Float,
scaleY: Float,
pivot: Offset = center,
block: DrawScope.() -> Unit
){...}
- scale 缩放的大小
- pivot 缩放的中心点
- scaleX X轴缩放多少
- scaleY Y轴缩放所少
- pivot 缩放的中心点 举例:
@Preview
@Composable
fun scaleTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasSize = size
val canvasWidth = size.width
val canvasHeight = size.height
scale(scale =0.5f){
drawRect(
color = Color.Gray,
topLeft = Offset(x = canvasWidth / 3F , y = canvasHeight / 3F),
size = canvasSize / 3F
)
}
}
}
效果图如下:
2.3 clipRect 裁剪矩形区域
clipRect 是裁剪出一块矩形的区域,代码如下:
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
)
- left 左边的坐标
- top 顶部的坐标
- right 右边的坐标
- bottom 底部的坐标
- clipOp 裁剪的类型ClipOp ClipOp.Intersect是裁剪出来的矩形。ClipOp.Difference从当前剪辑中减去提供的矩形 举例:比如绘制整个屏幕大小的矩形。但是我们设置了裁剪,代码如下:
@Preview
@Composable
fun clipRectTest(){
Canvas(modifier = Modifier.fillMaxSize()){
val canvasSize = size
val canvasWidth = size.width