Jetpack Compose自定义view 画月亮

1,191 阅读2分钟

首先利用drawArc函数画扇形

月亮由有个圆个一个小圆组成

设置大圆心角为120° 360-120 = 240

   startAngle = 40F,
   sweepAngle = 240f,

偏移40°增强画面感 sweepAngle = 240f, 在这里插入图片描述

在这里插入图片描述 获取画布宽高

   val canvasWidth = size.width  // 画布的宽
   val canvasHeight = size.height  // 画布的高

这样画布的宽除2就是大圆的半径了 接着求出小圆的直径,通过直径设置圆的大小,再给小圆设置位置偏移就搞定了

求小圆的直径

现在知道大圆的半径和内角,怎么求小圆的直径呢,思考一下

这个问题相当于已知等腰三角形的腰长(等于大圆的半径R)和顶角(圆心角)的度数n,求等腰三角形的斜边。 可转化成解直角三角形的问题。 等腰三角形的腰(R)、直角边(h)和底边(也就是扇形两端点与圆心之间的垂直距离),腰和底边高的夹角等于圆心角的一半 60°,知道斜边(R),求这个角的对边h,用正弦就OK啦。

  val shadowWidth = outerWidth * kotlin.math.sqrt(3.0) /2
 val shadowHeight =outerHeight * kotlin.math.sqrt(3.0) /2
kotlin.math.sqrt(3.0) == 根号3

sin60° = 2分之根号3 就可以得到小圆的直径 在这里插入图片描述

最后就是小圆的偏移量

根据余弦求出扇形两端点与圆心之间的垂直距离等于R/2 也就是大圆直径的1/4 还要加上Stroke的宽度

(strokeWidth*2)+outerWidth/4

完整代码

@Composable
fun Moon(modifier: Modifier = Modifier) {

    Canvas(modifier) {

        val canvasWidth = size.width  // 画布的宽
        val canvasHeight = size.height  // 画布的高

        val strokeWidth = size.width / 35
        val strokeHeight = size.height / 35

        // draw circle
        //外圆宽
        val outerWidth =canvasWidth-strokeWidth
        val outerHeight =canvasHeight-strokeHeight
        val shadowWidth = outerWidth * kotlin.math.sqrt(3.0) /2
        val shadowHeight =outerHeight * kotlin.math.sqrt(3.0) /2
        drawArc(
            color = Color.Black,
            startAngle = 40F,
            sweepAngle = 240f,
            useCenter = false,
            style = Stroke(
                width = strokeWidth,
                cap = StrokeCap.Round),
            topLeft = Offset(strokeWidth/2, strokeHeight/2),
            size = Size(outerWidth, outerHeight),
            )
        drawArc(
            color = Color.Black,
            startAngle = 70F,
            sweepAngle = 180f,
            useCenter = false,
            style = Stroke(width = strokeWidth,
                cap = StrokeCap.Round),
            topLeft = Offset((strokeWidth*2)+outerWidth/4, 0F),
            size = Size(shadowWidth.toFloat(),shadowHeight.toFloat()),
            )
   }
}

在这里插入图片描述