首先利用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()),
)
}
}