当前位置:网站首页>Cool 3D sphere text cloud effect!
Cool 3D sphere text cloud effect!
2022-06-23 21:15:00 【User 9239674】
cause
I saw one on the Internet a few days ago h5 It's more dazzling 3D Sphere text effect , I think it's interesting , Just ready to Android Side to side reproduction , Don't talk nonsense , Let's take a look at the effect (gif Looks like some cards , Actually not )
The core principle
Text coordinates
The first thing to do is to determine a coordinate for each text ,Android It's a left-handed coordinate system , And our effect is a sphere , So I use the spherical coordinate system to calculate the coordinates of each text .
y = radius * cos(Math.toRadians(this.upDegree)) z = -radius * sin(Math.toRadians(this.upDegree)) * sin(Math.toRadians(this.bottomDegree)) x = radius * sin(Math.toRadians(this.upDegree)) * cos(Math.toRadians(this.bottomDegree))
among radius Is the length of the line from the center of the circle to the sphere , That's the radius of the sphere ,upDegree For connecting with y The angle in the positive direction of the axis , The scope is [0,180],bottomDegree For connection at xz The projection on the plane determined by the axis and x The angle in the positive direction of the axis , The scope is [0,360].
Text color and size
When the text goes to and x The included angle in the positive direction of the shaft is 90 When , At this time, the text is the largest , The darkest color ,270 Minimum in degrees , Lightest color ,270 C to 360 Degree is the inverse of the above process . To do this, we define a variable factor Used to describe the change degree of text color and size , The scope is 【minFactor,1】minFactor Can be passed in through external variables .
According to the previous description , We can be sure factor The function of is
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
}
}
)By constructing three piecewise linear functions from different angles .
Calculate the text coordinates
Defining classes WordItem Used to represent each text , Coordinates and their corresponding factor, stay onMeasure Calculate the corresponding coordinates for all text when , And stored in wordItemList In the member variable .
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
y = radius * cos(Math.toRadians(this.upDegree))
z = -radius * sin(Math.toRadians(this.upDegree)) * sin(Math.toRadians(this.bottomDegree))
x = radius * sin(Math.toRadians(this.upDegree)) * cos(Math.toRadians(this.bottomDegree))
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<WordItem>? {
wordList?.let { list ->
val wordItemList = mutableListOf<WordItem>()
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])
wordItem.cal(radius, upDegree, bottomDegree, minFactor)
wordItemList.add(wordItem)
}
}
}
return wordItemList
}
return null
}Draw text
First of all, according to the factor Set the size of the brush text and the corresponding alpha value , Then calculate the corresponding position according to the text size , Drawing , And it's growing bottomDegreeOffset, Modify the coordinates of each text , Achieve rotation .
canvas?.let { canvas ->
wordItemList?.forEach { wordItem ->
wordItem.move(radius, 0.0, 1.0, minFactor)
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 Advanced development system notes 、 The latest interview review notes PDF, my GitHub
At the end of the article What's your opinion on the article , Or any technical problems , Welcome to leave a message and discuss in the comment area !
边栏推荐
- RI Gai series: push of STD container_ Why is back slower than []
- JS namespace
- Setinterval stop
- Disaster recovery series (VII) -- hybrid cloud public network export disaster recovery construction
- SAP retail uses transaction code wb03 to display a factory configured in the background
- What if there are too few jetpack compose theme colors? Design your own color system
- Script tag attributes and & lt; noscript&gt; label
- Can Tencent cloud disk service share data? What are the advantages of cloud disk service?
- The element of display:none cannot get offsetwidth and offsetHeight
- . NET Framework . Net core and Net standard
猜你喜欢
Application of JDBC in performance test

How to gradually improve PMO's own ability and management level

What are the main dimensions of PMO performance appraisal?

How PMO uses two dimensions for performance appraisal

How to view the role of PMO in agile organizations?

New SQL syntax quick manual!

Four aspects of PMO Department value assessment

How does PMO select and train project managers?

3000 frame animation illustrating why MySQL needs binlog, redo log and undo log

I am 30 years old, no longer young, and have nothing
随机推荐
ntpupdate. tencentyun. Com has been eliminated
How to evaluate performance optimization? Covering too much knowledge?
CPS 22 January additional incentive rules
Global and Chinese markets of natural starch 2022-2028: Research Report on technology, participants, trends, market size and share
Machine learning related
打新债到底是用什么软件比较安全?打新债平台有哪些
网上证券开户安全还是去营业部安全
Is it safe for Huatai Securities to open an account online for securities companies with low handling fees and commissions
I am 30 years old, no longer young, and have nothing
More than 1200 phishing kits that can intercept 2fa detected in the field
Use of pathinfo/pathname in nodejs
Whether the offsetwidth includes scroll bars
Implementation of flashback query for PostgreSQL database compatible with Oracle Database
JS to get the screen size, current web page and browser window
Using asp Net core MVC framework for building web applications
Retrofit magic, reject duplicate code!
同花顺网上开户安全吗,佣金高不高
Newbeecoder. UI new open source control library DataGrid instructions
上线项目之局域网上线软件使用-----phpStudy
Application of JDBC in performance test