欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Jetpack?Compose?Canvas繪制超詳細(xì)介紹

 更新時(shí)間:2022年10月28日 09:14:07   作者:唯鹿  
Canvas?是允許您在屏幕上指定區(qū)域并在此區(qū)域上執(zhí)行繪制的組件。您必須使用修飾符指定尺寸,無(wú)論是通過(guò)Modifier.size修飾符指定確切尺寸,還是通過(guò)Modifier.fillMaxSize,ColumnScope.weight等相對(duì)于父級(jí)指定精確尺寸。如果父級(jí)包裝了此子級(jí),則僅必須指定確切尺寸

1. Canvas

@Composable
fun Canvas(
	modifier: Modifier,
	onDraw: DrawScope.() -> Unit
) = Spacer(modifier.drawBehind(onDraw))
  • modifier:這里主要作用是指定畫(huà)布的大小。
  • onDraw就是執(zhí)行具體的繪制??梢钥吹剿峁┝艘粋€(gè)繪圖環(huán)境的作用域 DrawScope,這里提供有我們經(jīng)常使用的繪圖api和屬性,比如drawLine、size等。

先來(lái)一個(gè)簡(jiǎn)單的例子看看如何使用:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasWidth = size.width
    val canvasHeight = size.height
    drawLine(
        start = Offset(x = canvasWidth, y = 0f),
        end = Offset(x = 0f, y = canvasHeight),
        color = Color.Blue
    )
}

畫(huà)一條線,開(kāi)始和結(jié)束位置分別是畫(huà)布的右上角和左下角。效果如下:

2. 繪制方法

1. drawLine

drawLine在上面的例子中簡(jiǎn)單說(shuō)明了,當(dāng)然它不止這些功能。

	fun drawLine(
        color: Color, //或 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
    )
  • 指定線的顏色用color
  • 漸變色可以使用brush,本系列第三篇有說(shuō)明。
  • strokeWidth 是線的寬度,默認(rèn)是1px。
  • cap是線頭的形狀,默認(rèn)是StrokeCap.Butt平頭。還有StrokeCap.Round圓頭,StrokeCap.Square方頭。這部分和Android中的Paint是一樣的。平頭和方頭的不同在于是否延伸出來(lái)的部分。

pathEffect是線段的效果,比如虛線這種就是使用PathEffect.dashPathEffect(intervals: FloatArray, phase: Float = 0f) ,舉一個(gè)例子:

PathEffect.dashPathEffect(floatArrayOf(20f, 10f), 10f)

intervals中的20f表示虛線的寬度,10f是間隔寬度。phase的10f表示初始的偏移距離。所以一開(kāi)始偏移10f,就會(huì)導(dǎo)致第一段的線段被"裁剪"10f,具體效果如下圖:

  • alpha 是線段的透明度。
  • colorFilter是顏色過(guò)濾器,本系列第四篇有說(shuō)明,這里就不重復(fù)介紹了。
  • blendMode:混合模式。這個(gè)不在本篇的范圍內(nèi),后面有機(jī)會(huì)我會(huì)詳細(xì)說(shuō)一下。有興趣可以先看看文末的參考文章。

2. drawRect

繪制矩形方法,屬性與drawLine大同小異,下面說(shuō)一些不同點(diǎn)。

	fun drawRect(
        color: Color,
        topLeft: Offset = Offset.Zero,
        size: Size = this.size.offsetSize(topLeft),
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        style: DrawStyle = Fill,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )
  • topLeft是用來(lái)指定左上角的偏移量,如果沒(méi)有指定那么默認(rèn)從當(dāng)前畫(huà)布左上角開(kāi)始。
  • size用來(lái)指定矩形大小,如果沒(méi)有指定那么默認(rèn)就是當(dāng)前畫(huà)布的大小。
  • style是指實(shí)心還是空心。默認(rèn)Fill實(shí)心,Stroke空心。

3. drawRoundRect

繪制圓角矩形基本與矩形一致,只是多了一個(gè)設(shè)置圓角大小的參數(shù)drawRoundRect,這里就不多說(shuō)明了。

4. drawImage

繪制圖片方法

	fun drawImage(
        image: ImageBitmap,
        srcOffset: IntOffset = IntOffset.Zero,
        srcSize: IntSize = IntSize(image.width, image.height),
        dstOffset: IntOffset = IntOffset.Zero,
        dstSize: IntSize = srcSize,
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        style: DrawStyle = Fill,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )
  • image:需要繪制的圖片,具體可以使用ImageBitmap.imageResource(id = R.drawable.xxx)方法獲取。
  • srcOffset:需要繪制圖片的左上角偏移量,默認(rèn)為圖像的原點(diǎn)。
  • srcSize: 圖片相對(duì)于srcOffset的尺寸,默認(rèn)為圖像的寬高。
  • dstOffset: 繪制圖片的相對(duì)左上角的偏移量,這默認(rèn)為圖像的原點(diǎn)。
  • dstSize:繪制圖片的大小,默認(rèn)為srcSize

下面的代碼是繪制一張圖片的右下角區(qū)域,相對(duì)畫(huà)布偏移50 * 50,繪制的大小是200 * 200。

 	val imageBitmap = ImageBitmap.imageResource(id = R.mipmap.ic_launcher)
    Canvas(modifier = Modifier.fillMaxSize()) {
        drawImage(
            image = imageBitmap,
            srcOffset = IntOffset(imageBitmap.width / 2,imageBitmap.height / 2),
            srcSize = IntSize(imageBitmap.width, imageBitmap.height),
            dstOffset = IntOffset(50,50),
            dstSize = IntSize(200,200)
        )
    }

效果如下:

5. drawCircle

繪制圓形方法

	fun drawCircle(
        color: Color,
        radius: Float = size.minDimension / 2.0f,
        center: Offset = this.center,
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        style: DrawStyle = Fill,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )
  • radius:圓的半徑大小。
  • center:圓心位置。

6. drawArc

drawArc可以用來(lái)繪制弧形或是扇形

	fun drawArc(
        color: Color,
        startAngle: Float,
        sweepAngle: Float,
        useCenter: Boolean,
        topLeft: Offset = Offset.Zero,
        size: Size = this.size.offsetSize(topLeft),
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        style: DrawStyle = Fill,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )
  • startAngle: 開(kāi)始角度
  • sweepAngle: 弧線掃過(guò)的角度
  • useCenter: 弧線是否過(guò)圓心

這里就不舉例說(shuō)明了,可以用styleuseCenter屬性自行組合嘗試。

7. drawPath

繪制路徑方法

	fun drawPath(
        path: Path,
        color: Color,
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        style: DrawStyle = Fill,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )

其實(shí)和Android中的path使用一樣,圍繞著moveTo、lineTo、close這些方法,也就不詳細(xì)說(shuō)明了。

8. drawPoints

繪制點(diǎn)的方法

	fun drawPoints(
        points: List<Offset>,
        pointMode: PointMode,
        color: Color,
        strokeWidth: Float = Stroke.HairlineWidth,
        cap: StrokeCap = StrokeCap.Butt,
        pathEffect: PathEffect? = null,
        /*@FloatRange(from = 0.0, to = 1.0)*/
        alpha: Float = 1.0f,
        colorFilter: ColorFilter? = null,
        blendMode: BlendMode = DefaultBlendMode
    )
  • points:點(diǎn)的偏移位置
  • pointMode:點(diǎn)的繪制模式,PointMode.Points分別畫(huà)出每個(gè)點(diǎn)。PointMode.Lines 每?jī)蓚€(gè)點(diǎn)畫(huà)成一條線段。 如果點(diǎn)數(shù)是奇數(shù),則忽略最后一個(gè)點(diǎn)。PointMode.Polygon 連接所有的點(diǎn)。

最后還有一個(gè)繪制橢圓方法drawOval,用法大同小異,就不說(shuō)明了。

3. DrawScope拓展方法

1. inset

同時(shí)從左到上轉(zhuǎn)換DrawScope坐標(biāo)空間,并修改當(dāng)前繪制區(qū)域的尺寸。

inline fun DrawScope.inset(
    left: Float,
    top: Float,
    right: Float,
    bottom: Float,
    block: DrawScope.() -> Unit
) {...}

inset有點(diǎn)像是在原有的畫(huà)布上,嵌入了一個(gè)"新"的畫(huà)布,設(shè)置的left,top就是相應(yīng)的padding。

	Canvas(modifier = Modifier.fillMaxSize()){
        drawRect(
            color = Color.Blue,
        )
        inset(100f, 100f, 100f, 100f) {
            drawRect(
                color = Color.Red,
            )
        }
    }

2. translate

平移繪制區(qū)域

inline fun DrawScope.translate(
    left: Float = 0.0f,
    top: Float = 0.0f,
    block: DrawScope.() -> Unit
) {...}

只需要設(shè)置left、top方向移動(dòng)的距離即可。

3. rotate與rotateRad

旋轉(zhuǎn)繪制區(qū)域

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是旋轉(zhuǎn)了多少角度。
  • radians是旋轉(zhuǎn)了多少弧度。
  • pivot 是旋轉(zhuǎn)的中心點(diǎn),默認(rèn)是中心。

4. scale

縮放繪制區(qū)域。

inline fun DrawScope.scale(
    scaleX: Float,
    scaleY: Float,
    pivot: Offset = center,
    block: DrawScope.() -> Unit
) {...}

指定x、y方向上的縮放倍數(shù)即可。

5. clipRect

裁剪給定的矩形區(qū)域

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
) {...}
  • clipOpClipOp.Intersect是裁剪矩形的里面,ClipOp.Difference是裁剪矩形的外面。

看個(gè)簡(jiǎn)單的例子,便于你的理解:

	Canvas(modifier = Modifier.fillMaxSize()){
        drawRect(
            color = Color.Blue,
        )
        clipRect(200f, 200f, clipOp = ClipOp.Intersect) {
            drawRect(
                color = Color.Yellow,
            )
        }
    }

左邊是ClipOp.Intersect,右邊是ClipOp.Difference

clipPath同理。

6. drawIntoCanvas

可以直接調(diào)用底層Canvas繪制的方法。我們用它實(shí)現(xiàn)一開(kāi)始的drawLine例子,畫(huà)一條對(duì)角線:

	Canvas(modifier = Modifier.fillMaxSize()) {
        val canvasWidth = size.width
        val canvasHeight = size.height
        drawIntoCanvas {
            val paint = Paint()
            paint.color = Color.Blue
            paint.strokeWidth = 1f
            it.drawLine(
                p1 = Offset(canvasWidth,0f),
                p2 = Offset(0f,canvasHeight),
                paint = paint
            )
        }
    }

其中drawLine方法,并不是一開(kāi)始DrawScope中的drawLine:

actual typealias NativeCanvas = android.graphics.Canvas
private val EmptyCanvas = android.graphics.Canvas()
@PublishedApi internal class AndroidCanvas() : Canvas {
    @PublishedApi internal var internalCanvas: NativeCanvas = EmptyCanvas
	override fun drawLine(p1: Offset, p2: Offset, paint: Paint) {
        internalCanvas.drawLine(
            p1.x,
            p1.y,
            p2.x,
            p2.y,
            paint.asFrameworkPaint()
        )
    }
}

可以看到最終調(diào)用了Android的Canvas api。

7. withTransform

執(zhí)行1個(gè)或多個(gè)轉(zhuǎn)換。也就是上面平移旋轉(zhuǎn)這些可以一塊執(zhí)行。

inline fun DrawScope.withTransform(
    transformBlock: DrawTransform.() -> Unit,
    drawBlock: DrawScope.() -> Unit
) {...}

4.參考

Compose 中的圖形

Jetpack Compose 繪制 Canvas

到此這篇關(guān)于Jetpack Compose Canvas繪制超詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Jetpack Compose Canvas內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論