用 Compose 画个小老虎恭贺新春

2,904 阅读5分钟

PK创意闹新春,我正在参加「春节创意投稿大赛」

效果图

大家不要误会,效果图不是上面的图。。。上面的图太复杂了,我画的老虎可没有这么好看😂。。

image.pngimage.png

哈哈哈,是不太好看哈。。不要在意那些细节,这不重要!重要的是迎接 2022 年虎年的那颗炙热且纯真的心,还加了点动画,当点击老虎的头的时候会动。。。

老虎.gif

在这里先祝大家在虎年虎虎生威,每天都能虎虎大睡!

思路

本来想画一个好看的老虎,但真的动手的时候就有点不知所措了,本来想的一层一层放图片,就有点 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 就可以画一个圆,然后计算出圆的位置就行,下面来看下效果吧:

image.png

画头上的王字

脑袋画完了,接下来画一下老虎头上的王字,这是老虎的标志啊!

// 写头上的王字
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 了,就都用它吧,再来看下效果:

image.png

怎么样,是不是有点意思了😂!

画眉毛和眼睛

脑袋和王字都画好了,下面来画眉毛和眼睛吧,眉毛也可以用矩形代替,眼睛还用圆来代替就行:

// 画眉毛
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)
    )
)

各位,请上眼:

image.png

画鼻子和嘴

眼睛也有了,鼻子和嘴还没画,简单点,鼻子也用矩形代替,嘴用椭圆代替吧:

// 画鼻子
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)
    )
)

接下来再来看看效果吧:

image.png

画胡须

上面的图眼睛、鼻子、嘴都有了,连脑袋上的王字都画了,怎么感觉不像老虎呢???对了,老虎有胡须啊,也可以通过矩形来代替:

// 画胡须
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)
)

诶,没错,左右一边三根,各位,请上眼:

image.png

画耳朵

怎么还是感觉不对呢???少了什么东西???

对啊!耳朵呢?五官还没有凑齐呢!

// 画耳朵
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
    )
)

耳朵也可以用圆来代替嘛,很简单,现在再来看下:

image.png

哈哈哈,有那味了吧!!!

写祝福语

老虎画完了,该加上祝福语了!

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)
}

image.png

下面再加上老虎,再考虑下横竖屏的切换:

@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()
        }
    }
}

image.png

让老虎动起来

只画个老虎头吧,身子就先不画了,现在想想办法让它动起来。那就当点击老虎头的时候动一下吧。

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 地址:

github.com/zhujiang521…

最后在这里给大家拜年了!!!

祝大家:新年快乐!虎年万事如意!