效果图
不要误会效果图不是上图。。。上图太复杂了,我画的老虎没那么好看。
哈哈哈,不太好看。。不要在意那些细节,没关系!欢迎很重要 2022 年虎年那颗炽热而纯洁的心,还加了一些动画,点击老虎头时会动。
这里祝大家虎年虎虎生威,每天虎虎大睡!
思路
本来想画只漂亮的老虎,但当我真的开始的时候,我有点不知所措。我想一层一层地放图片,有点 PS 那就是意思,那样的效果确实比这个好,但是真诚和这个一笔一笔不一样。
后来决定通过 Path 因为 Compose 中的 Path 在以前的项目中使用较少,那就来吧,跟着我一步一步画这只丑老虎吧。
开始撸码
画脑袋
先画老虎头,说好听点叫老虎头,说不好听点就是圆。
val size = this.size val path = Path() path.moveTo(size.width / 2, bigSize) val start = size.width / 6 // 画圆 path.addOval(Rect(start, 300f, start * 5, 300 start * 5 - start)) path.close() drawPath(path = path, color = Color.Yellow, style = Stroke(width = 10f))
Path 直接通过 addOval 你可以画一个圆,然后计算圆的位置。让我们来看看效果:
画头上的王字
画完脑袋,然后画老虎头上的王字,这是老虎的标志啊!
// 头上写王字 path.addRect(Rect(start * 3 - 40f, 300f 60f, start * 3 40f, 300f 65f)) path.addRect(Rect(start * 3 - 50f, 300f 85f, start * 3 50f, 300f 90f)) path.addRect(Rect(start * 3 - 35f, 300f 110f, start * 3 35f, 300f 115f)) path.addRect(Rect(start * 3 - 2.5f, 300f 60f, start * 3 2.5f, 300f 115f))
addRect 是为 Path 添加矩形时,直接通过 drawLine 也可以实现,但既然使用了 Path 就用吧,再来看看效果:
怎么样?有趣吗?
画眉毛和眼睛
头和王字都画好了,下面画眉毛和眼睛,眉毛也可以用矩形代替,眼睛也可以用圆形代替:
// 画眉毛 path.addRect(Rect(start * 1.5f 50, bigSize 200f, start * 1.5f 130f, bigSize 205f)) path.addRect(Rect(start * 3.5f 50, bigSize 200f, start * 3.5f 130f, bigSize 205f)) // 画眼睛 path.addOval( Rect( start * 1.5f 50, 550f, start * 1.5f 130f, 550 start * 1.5f 130f - (start * 1.5f 50) ) ) path.addOval( Rect( start * 3.5f 50, 550f, start * 3.5f 130f, 550 start * 3.5f 130f - (start * 3.5f 50) ) )
各位,请上眼:
画鼻子和嘴
眼睛也有,鼻子和嘴还没画,简单点,鼻子也用矩形代替,嘴用椭圆代替:
// 画鼻子 path.addRect( Rect( start * 3 - 40f, 680f, start * 3 40f, 680f start * 3 40f - (start * 3 - 40f) ) ) // 画嘴 path.addOval( Rect( start * 3 - 100f, 850f, start * 3 100f, 850f start * 3 40f - (start * 3 - 40f) ) )
再来看看效果吧:
画胡须
上图有眼睛、鼻子和嘴巴。连头上的王字都画了。怎么会觉得不像老虎??对了,老虎有胡子,可以用矩形代替:
// 画胡须 path.addRect( Rect(start - 70f, 680f, start 70f, 685f) ) path.addRect( Rect(start - 100f, 725f, start 100f, 730f) ) path.addRect( Rect(start - 80f, 770f, start 80f, 775f) ) path.addRect( Rect(start * 5 - 70f, 680f, start * 5 70f, 685f) ) path.addRect( Rect(start * 5 - 100f, 725f, start * 5 100f, 730f) ) path.addRect( Rect(start * 5 - 80f, 770f, start * 5 80f, 775f) )
呃,是的,左右两边有三根,各位,请上眼:
画耳朵
为什么还是觉得不对???少了什么?
是的!耳朵呢?五官还没凑齐!
// 画耳朵 path.addOval( Rect( start * 1.2f, bigSize - 50f, start * 2.2f, bigSize - 50f start ) ) path.addOval( Rect( start * 3.8f, bigSize - 50f, start * 4.8f, bigSize - 50f start ) )
耳朵也可以用圆来代替,很简单,现在再来看看:
哈哈哈,有那种味道!
写祝福语
老虎画完了,该加祝福了!
Column( modifier = Modifier .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { Text(text = "恭喜", fontSize = 150.sp, color = Color.Yellow, fontFamily = FontFamily.Serif) Text(text = "发财", fontSize = 150.sp, color = Color.Yellow, fontFamily = FontFamily.Serif) }
再加上老虎,再考虑下横竖屏的切换:
@Composable fun NewYearWidget() { val isLand = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE if (!isLand) { Column( modifier = Modifier .fillMaxSize() .background(color = Color.Red), horizontalAlignment = Alignment.CenterHorizontally, ) { TigerWidget() TextWidget() }
} else {
Row(
modifier = Modifier
.fillMaxSize()
.background(color = Color.Red),
verticalAlignment = Alignment.CenterVertically,
) {
TigerWidget()
TextWidget()
}
}
}
让老虎动起来
只画个老虎头吧,身子就先不画了,现在想想办法让它动起来。那就当点击老虎头的时候动一下吧。
var isBig by remember { mutableStateOf(true) }
val bigSize by animateFloatAsState(
if (isBig) 300f else 150f,
animationSpec = spring(Spring.StiffnessVeryLow)
)
Canvas(
modifier = Modifier
.size(360.dp)
.background(color = Color.Red)
.clickable {
isBig = !isBig
}
)
很简单,将刚才设置高度的值修改下,转为动画的 State,大家都知道,Compose 中的 UI 是数据驱动刷新的,直接设置上就可以了。
到这里就画完了,是不是很简单,哈哈哈,当点击老虎头的时候就会像上面的效果图那样伸缩。
总结
因为今年是虎年,所以想画个小老虎,但是最后把自己都给丑哭了。。。但是意思就是那么个意思。细心的大家可能都发现了,本文中基本没有直接运行项目,而是通过 Compose 的 Preview 进行预览的,效果也非常好,大家都可以试试。
本文所有代码都在 Github 中,下面是 Github 地址:
https://github.com/zhujiang521/PlayWeather/blob/master/app/src/main/java/com/zj/weather/ui/view/tiger/NewYaerWidget.kt
最后在这里给大家拜年了!!!
祝大家:新年快乐!虎年万事如意!