在Canvas的一系列讲解中,使用到很多次的渐变效果,本章节来具体看下渐变的详细使用
一.渐变的种类
1.源码
@Immutable
sealed class Brush {
/**
* Return the intrinsic size of the [Brush].
* If the there is no intrinsic size (i.e. filling bounds with an arbitrary color) return
* [Size.Unspecified].
* If there is no intrinsic size in a single dimension, return [Size] with
* [Float.NaN] in the desired dimension.
*/
open val intrinsicSize: Size = Size.Unspecified
abstract fun applyTo(size: Size, p: Paint, alpha: Float)
companion object {
/**
* Creates a linear gradient with the provided colors along the given start and end
* coordinates. The colors are dispersed at the provided offset defined in the
* colorstop pair.
*
* ```
* Brush.linearGradient(
* 0.0f to Color.Red,
* 0.3f to Color.Green,
* 1.0f to Color.Blue,
* start = Offset(0.0f, 50.0f),
* end = Offset(0.0f, 100.0f)
* )
* ```
*
* @see androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colorStops Colors and their offset in the gradient area
* @param start Starting position of the linear gradient. This can be set to
* [Offset.Zero] to position at the far left and top of the drawing area
* @param end Ending position of the linear gradient. This can be set to
* [Offset.Infinite] to position at the far right and bottom of the drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun linearGradient(
vararg colorStops: Pair<Float, Color>,
start: Offset = Offset.Zero,
end: Offset = Offset.Infinite,
tileMode: TileMode = TileMode.Clamp
): Brush = LinearGradient(
colors = List<Color>(colorStops.size) { i -> colorStops[i].second },
stops = List<Float>(colorStops.size) { i -> colorStops[i].first },
start = start,
end = end,
tileMode = tileMode
)
/**
* Creates a linear gradient with the provided colors along the given start and end coordinates.
* The colors are
*
* ```
* Brush.linearGradient(
* listOf(Color.Red, Color.Green, Color.Blue),
* start = Offset(0.0f, 50.0f)
* end = Offset(0.0f, 100.0f)
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colors Colors to be rendered as part of the gradient
* @param start Starting position of the linear gradient. This can be set to
* [Offset.Zero] to position at the far left and top of the drawing area
* @param end Ending position of the linear gradient. This can be set to
* [Offset.Infinite] to position at the far right and bottom of the drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun linearGradient(
colors: List<Color>,
start: Offset = Offset.Zero,
end: Offset = Offset.Infinite,
tileMode: TileMode = TileMode.Clamp
): Brush = LinearGradient(
colors = colors,
stops = null,
start = start,
end = end,
tileMode = tileMode
)
/**
* Creates a horizontal gradient with the given colors evenly dispersed within the gradient
*
* Ex:
* ```
* Brush.horizontalGradient(
* listOf(Color.Red, Color.Green, Color.Blue),
* startX = 10.0f,
* endX = 20.0f
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colors colors Colors to be rendered as part of the gradient
* @param startX Starting x position of the horizontal gradient. Defaults to 0 which
* represents the left of the drawing area
* @param endX Ending x position of the horizontal gradient.
* Defaults to [Float.POSITIVE_INFINITY] which indicates the right of the specified
* drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun horizontalGradient(
colors: List<Color>,
startX: Float = 0.0f,
endX: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = linearGradient(colors, Offset(startX, 0.0f), Offset(endX, 0.0f), tileMode)
/**
* Creates a horizontal gradient with the given colors dispersed at the provided offset
* defined in the colorstop pair.
*
* Ex:
* ```
* Brush.horizontalGradient(
* 0.0f to Color.Red,
* 0.3f to Color.Green,
* 1.0f to Color.Blue,
* startX = 0.0f,
* endX = 100.0f
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colorStops Colors and offsets to determine how the colors are dispersed throughout
* the vertical gradient
* @param startX Starting x position of the horizontal gradient. Defaults to 0 which
* represents the left of the drawing area
* @param endX Ending x position of the horizontal gradient.
* Defaults to [Float.POSITIVE_INFINITY] which indicates the right of the specified
* drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun horizontalGradient(
vararg colorStops: Pair<Float, Color>,
startX: Float = 0.0f,
endX: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = linearGradient(
*colorStops,
start = Offset(startX, 0.0f),
end = Offset(endX, 0.0f),
tileMode = tileMode
)
/**
* Creates a vertical gradient with the given colors evenly dispersed within the gradient
* Ex:
* ```
* Brush.verticalGradient(
* listOf(Color.Red, Color.Green, Color.Blue),
* startY = 0.0f,
* endY = 100.0f
* )
*
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colors colors Colors to be rendered as part of the gradient
* @param startY Starting y position of the vertical gradient. Defaults to 0 which
* represents the top of the drawing area
* @param endY Ending y position of the vertical gradient.
* Defaults to [Float.POSITIVE_INFINITY] which indicates the bottom of the specified
* drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun verticalGradient(
colors: List<Color>,
startY: Float = 0.0f,
endY: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = linearGradient(colors, Offset(0.0f, startY), Offset(0.0f, endY), tileMode)
/**
* Creates a vertical gradient with the given colors at the provided offset defined
* in the [Pair<Float, Color>]
*
* Ex:
* ```
* Brush.verticalGradient(
* 0.1f to Color.Red,
* 0.3f to Color.Green,
* 0.5f to Color.Blue,
* startY = 0.0f,
* endY = 100.0f
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colorStops Colors and offsets to determine how the colors are dispersed throughout
* the vertical gradient
* @param startY Starting y position of the vertical gradient. Defaults to 0 which
* represents the top of the drawing area
* @param endY Ending y position of the vertical gradient.
* Defaults to [Float.POSITIVE_INFINITY] which indicates the bottom of the specified
* drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun verticalGradient(
vararg colorStops: Pair<Float, Color>,
startY: Float = 0f,
endY: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = linearGradient(
*colorStops,
start = Offset(0.0f, startY),
end = Offset(0.0f, endY),
tileMode = tileMode
)
/**
* Creates a radial gradient with the given colors at the provided offset
* defined in the colorstop pair.
* ```
* Brush.radialGradient(
* 0.0f to Color.Red,
* 0.3f to Color.Green,
* 1.0f to Color.Blue,
* center = Offset(side1 / 2.0f, side2 / 2.0f),
* radius = side1 / 2.0f,
* tileMode = TileMode.Repeated
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colorStops Colors and offsets to determine how the colors are dispersed throughout
* the radial gradient
* @param center Center position of the radial gradient circle. If this is set to
* [Offset.Unspecified] then the center of the drawing area is used as the center for
* the radial gradient. [Float.POSITIVE_INFINITY] can be used for either [Offset.x] or
* [Offset.y] to indicate the far right or far bottom of the drawing area respectively.
* @param radius Radius for the radial gradient. Defaults to positive infinity to indicate
* the largest radius that can fit within the bounds of the drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun radialGradient(
vararg colorStops: Pair<Float, Color>,
center: Offset = Offset.Unspecified,
radius: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = RadialGradient(
colors = List<Color>(colorStops.size) { i -> colorStops[i].second },
stops = List<Float>(colorStops.size) { i -> colorStops[i].first },
center = center,
radius = radius,
tileMode = tileMode
)
/**
* Creates a radial gradient with the given colors evenly dispersed within the gradient
* ```
* Brush.radialGradient(
* listOf(Color.Red, Color.Green, Color.Blue),
* centerX = side1 / 2.0f,
* centerY = side2 / 2.0f,
* radius = side1 / 2.0f,
* tileMode = TileMode.Repeated
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colors Colors to be rendered as part of the gradient
* @param center Center position of the radial gradient circle. If this is set to
* [Offset.Unspecified] then the center of the drawing area is used as the center for
* the radial gradient. [Float.POSITIVE_INFINITY] can be used for either [Offset.x] or
* [Offset.y] to indicate the far right or far bottom of the drawing area respectively.
* @param radius Radius for the radial gradient. Defaults to positive infinity to indicate
* the largest radius that can fit within the bounds of the drawing area
* @param tileMode Determines the behavior for how the shader is to fill a region outside
* its bounds. Defaults to [TileMode.Clamp] to repeat the edge pixels
*/
@Stable
fun radialGradient(
colors: List<Color>,
center: Offset = Offset.Unspecified,
radius: Float = Float.POSITIVE_INFINITY,
tileMode: TileMode = TileMode.Clamp
): Brush = RadialGradient(
colors = colors,
stops = null,
center = center,
radius = radius,
tileMode = tileMode
)
/**
* Creates a sweep gradient with the given colors dispersed around the center with
* offsets defined in each colorstop pair. The sweep begins relative to 3 o'clock and continues
* clockwise until it reaches the starting position again.
*
* Ex:
* ```
* Brush.sweepGradient(
* 0.0f to Color.Red,
* 0.3f to Color.Green,
* 1.0f to Color.Blue,
* center = Offset(0.0f, 100.0f)
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colorStops Colors and offsets to determine how the colors are dispersed throughout
* the sweep gradient
* @param center Center position of the sweep gradient circle. If this is set to
* [Offset.Unspecified] then the center of the drawing area is used as the center for
* the sweep gradient
*/
@Stable
fun sweepGradient(
vararg colorStops: Pair<Float, Color>,
center: Offset = Offset.Unspecified
): Brush = SweepGradient(
colors = List<Color>(colorStops.size) { i -> colorStops[i].second },
stops = List<Float>(colorStops.size) { i -> colorStops[i].first },
center = center
)
/**
* Creates a sweep gradient with the given colors dispersed evenly around the center.
* The sweep begins relative to 3 o'clock and continues clockwise until it reaches the
* starting position again.
*
* Ex:
* ```
* Brush.sweepGradient(
* listOf(Color.Red, Color.Green, Color.Blue),
* center = Offset(10.0f, 20.0f)
* )
* ```
*
* @sample androidx.compose.ui.graphics.samples.GradientBrushSample
*
* @param colors List of colors to fill the sweep gradient
* @param center Center position of the sweep gradient circle. If this is set to
* [Offset.Unspecified] then the center of the drawing area is used as the center for
* the sweep gradient
*/
@Stable
fun sweepGradient(
colors: List<Color>,
center: Offset = Offset.Unspecified
): Brush = SweepGradient(
colors = colors,
stops = null,
center = center
)
}
}
2.种类
上述源码可知,渐变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
)
属性详解
1.colorStops&colors 都是渐变颜色
2.start 开始的位置
3.end 结束的位置
4.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
)
属性详解
1.colors&colorStops都是渐变的颜色
2.startX 开始的x轴坐标
3.endX 结束的x轴坐标
4.tileMode 有三种 TileMode.Clamp(默认就是这种,最接近该区域的点的颜色),TileMode.Repeated(边从第一种颜色重复到最后一种颜色),TileMode.Mirror (边从最后一种颜色镜像到第一种颜色)
***************************************************************************************
三.竖直方向的渐变
@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
)
属性详解
1.colors&colorStops 都是渐变的颜色
2.startY 开始的y坐标
3.endY 结束的y坐标
4.tileMode 有三种 TileMode.Clamp(默认就是这种,最接近该区域的点的颜色),TileMode.Repeated(边从第一种颜色重复到最后一种颜色),TileMode.Mirror (边从最后一种颜色镜像到第一种颜色)
*****************************************************************************************
四.径向的渐变
@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
)
属性详解
1.colorStops&colors 都是渐变的颜色
2.center 圆形的坐标
3.radius 半径
4.tileMode 有三种 TileMode.Clamp(默认就是这种,最接近该区域的点的颜色),TileMode.Repeated(边从第一种颜色重复到最后一种颜色),TileMode.Mirror (边从最后一种颜色镜像到第一种颜色)
****************************************************************************************
五.扫描的渐变
@Stable
fun sweepGradient(
vararg colorStops: Pair<Float, Color>,
center: Offset = Offset.Unspecified
)
@Stable
fun sweepGradient(
colors: List<Color>,
center: Offset = Offset.Unspecified
)
属性详解
1.colorStops&colors 都是渐变的颜色
2.center 扫描的中心点
二.详细使用
1.线性的渐变:linearGradient
代码
@Composable
fun InitCanvasComposeView11() {
//线性的渐变 linearGradient 举例
Column(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = "线性的渐变 linearGradient 举例"
)
//绘制线 brush设置渐变 水平渐变 线段末端的形状-正方形
Canvas(modifier = Modifier
.padding(20.dp)
.fillMaxWidth()) {
val w = size.width//Canvas的宽度
val h = size.height//Canvas的高度
drawLine(
brush = Brush.linearGradient(
0.0f to Color.Red,
0.4f to Color.Green,
1.0f to Color.Blue,
start = Offset(h / 2, h / 2),
end = Offset(w - 100f, h / 2),
tileMode = TileMode.Mirror
),
start = Offset(h / 2, h / 2),//开始位置
end = Offset(w - 100f, h / 2),//结束位置
strokeWidth = 30f,//线粗
cap = StrokeCap.Round,//线段末端的形状-圆形形
)
}
}
}
结果
2.水平方向的渐变:horizontalGradient
代码
@Composable
fun InitCanvasComposeView12() {
//水平方向的渐变 horizontalGradient 举例
Column(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = "水平方向的渐变 horizontalGradient 举例"
)
//绘制线 brush设置渐变 水平渐变 线段末端的形状-正方形
Canvas(modifier = Modifier
.padding(20.dp)
.fillMaxWidth()) {
val w = size.width//Canvas的宽度
val h = size.height//Canvas的高度
drawLine(
brush = Brush.horizontalGradient(
0.0f to Color.Red,
0.4f to Color.Green,
1.0f to Color.Blue,
startX = 0f,
endX = w,
tileMode = TileMode.Mirror
),
start = Offset(h / 2, h / 2),//开始位置
end = Offset(w - 100f, h / 2),//结束位置
strokeWidth = 30f,//线粗
cap = StrokeCap.Round,//线段末端的形状-圆形形
)
}
}
}
结果
3.竖直方向的渐变:verticalGradient
代码
@Composable
fun InitCanvasComposeView13() {
//竖直方向的渐变 verticalGradient 举例
Column(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = "竖直方向的渐变 verticalGradient 举例"
)
//绘制线 brush设置渐变 竖直渐变 线段末端的形状-正方形
Canvas(modifier = Modifier
.padding(20.dp)
.fillMaxWidth()
.height(300.dp)) {
val w = size.width//Canvas的宽度
val h = size.height//Canvas的高度
drawLine(
brush = Brush.verticalGradient(
0.0f to Color.Red,
0.4f to Color.Green,
1.0f to Color.Blue,
startY = 0f,
endY = h,
tileMode = TileMode.Mirror
),
start = Offset(w / 2, 0f),//开始位置
end = Offset(w/2, h ),//结束位置
strokeWidth = 30f,//线粗
cap = StrokeCap.Round,//线段末端的形状-圆形形
)
}
}
}
结果
4.径向的渐变:radialGradient
代码
@Composable
fun InitCanvasComposeView014() {
Column(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = "竖直方向的渐变 verticalGradient 举例"
)
//绘制圆 brush设置渐变 径向渐变
Canvas(
modifier = Modifier
.padding(10.dp)
.size(200.dp)
.background(Color.Gray)
) {
val w = size.width//Canvas的宽度
val h = size.height//Canvas的高度
drawCircle(
brush = Brush.radialGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
center = Offset(w / 2, h / 2),
radius = w / 2,
tileMode = TileMode.Clamp
),
radius = w / 2,
center = Offset(w / 2, h / 2),
style = Fill
)
}
}
}
结果
5.扫描的渐变:sweepGradient
代码
@Composable
fun InitCanvasComposeView015() {
Column(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = "扫描的渐变:sweepGradient"
)
//绘制圆 brush设置渐变 扫描
Canvas(
modifier = Modifier
.padding(10.dp)
.size(200.dp)
.background(Color.Gray)
) {
val w = size.width//Canvas的宽度
val h = size.height//Canvas的高度
drawCircle(
brush = Brush.sweepGradient(
0.0f to Color.Red,
0.5f to Color.Green,
1.0f to Color.Blue,
center = Offset(w / 2, h / 2),
),
radius = w / 2,
center = Offset(w / 2, h / 2),
style = Fill
)
}
}
}
结果