# 核心原理

## 文字坐标

``````y = radius * cos(Math.toRadians(this.upDegree))

## 文字颜色与大小

`````` factor = minFactor.coerceAtLeast(
when (bottomDegree) {
in 0.0..90.0 -> {
1.0 / Math.PI * Math.toRadians(bottomDegree) + 0.5
}
in 270.0..360.0 -> {
1.0 / Math.PI * Math.toRadians(bottomDegree) - 1.5
}
else -> {
-1.0 / Math.PI * Math.toRadians(bottomDegree) + 1.5
}
}
)``````

## 计算文字坐标

``````class WordItem(
var text: String,
var upDegree: Double = 0.0,
var bottomDegree: Double = 0.0,
var x: Double = 0.0,
var y: Double = 0.0,
var z: Double = 0.0,
var factor: Double = 0.0
) {

fun cal(radius: Double, upDegree: Double, bottomDegree: Double, minFactor: Double) {
this.upDegree = upDegree % 180
this.bottomDegree = bottomDegree % 360
factor = minFactor.coerceAtLeast(
when (bottomDegree) {
in 0.0..90.0 -> {
1.0 / Math.PI * Math.toRadians(bottomDegree) + 0.5
}
in 270.0..360.0 -> {
1.0 / Math.PI * Math.toRadians(bottomDegree) - 1.5
}
else -> {
-1.0 / Math.PI * Math.toRadians(bottomDegree) + 1.5
}
}
)
}

fun move(radius: Double, upOffset: Double, bottomOffset: Double, minFactor: Double) {
cal(radius, upDegree + upOffset, bottomDegree + bottomOffset, minFactor)
}
}``````
``````private fun genWordItemList(): MutableList? {
wordList?.let { list ->
val wordItemList = mutableListOf()
var upDegree = 0.0
for (row in 0 until circleRowNum) {
upDegree += upDegreeGap
upDegree %= 180.0
var bottomDegree = 0.0
for (col in 0 until perNumInCircle) {
val index = row * perNumInCircle + col
if (index < wordList?.size ?: 0) {
bottomDegree += bottomDegreeGap
bottomDegree %= 360.0
val wordItem = WordItem(list[index])
}
}
}
return wordItemList
}
return null
}``````

## 绘制文字

``````canvas?.let { canvas ->
wordItemList?.forEach { wordItem ->
paint.textSize = (wordItem.factor * maxTextSize).toFloat()
paint.alpha = 30.coerceAtLeast((wordItem.factor * 255).toInt())
textRect.setEmpty()
paint.getTextBounds(wordItem.text, 0, wordItem.text.length, textRect)
canvas.drawText(
wordItem.text,
((width - paddingLeft - paddingRight) / 2 + wordItem.x - textRect.width() / 2).toFloat(),
((height - paddingTop - paddingBottom) / 2 + wordItem.y - textRect.height() / 2).toFloat(),
paint
)
}
postInvalidate()
}``````

Android高级开发系统进阶笔记、最新面试复习笔记PDF，我的GitHub