偶然看到了CSDN关于世界杯的征文活动:
用代码画一个足球? 哈哈很有意思!
想了想,画一个自定义View(足球),当然是使用Canvas了,但除了Canvas还有没有其它方法呢?那是必须的了,那就是使用SVG的Path去画!正好最近在开发harmneyOS应用,那就用鸿蒙的ArkTs去实现吧!
下面是使用ArkTs实现的世界杯海报效果图:
是不是有那么点意思了?哈哈…
关于鸿蒙项目开发流程及注意事项,可以参考本人的前两篇文章!
本项目结构:
实现逻辑:
首先自定义一个FootBall的组件:
@Entry
@Component
export struct FootBall {
build() {
Shape() {
Path()
.commands('M0 250 L0 250,500 250')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M250 0 L250 0,250 180')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M220 320 L220 320,150 423')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M280 320 L280 320,350 423')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M250 180 L250 180,180 250,220 320,280 320,320 250 Z')
.fill('#000')
Path()
.commands('M250 50 L250 50,190 18 A120 120 0 0 1 310 18')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M50 250 L50 250,18 310 A120 120 0 0 1 18 190')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M450 250 L450 250,482 190 A120 120 0 0 1 482 310')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M150 423 L150 423,180 480 A120 120 0 0 1 80 423')
.strokeWidth(1)
.stroke("#000")
Path()
.commands('M350 423 L350 423,420 423 A120 120 0 0 1 320 480')
.strokeWidth(1)
.stroke("#000")
}
.height('500px')
.width('500px')
.backgroundColor("#FFFFFF")
.borderRadius('250px')
}
}
使用Shape画出一个背景为白色的圆,然后内部以圆心为中心画一个五边形,再在五边形的角所对方向的圆边缘画5个小扇形:
Path()
.commands('M0 250 L0 250,500 250')
.strokeWidth(1)
.stroke("#000")
M0 250即将“画笔”定位到坐标(0,250)的位置,L0 250即“画笔”从坐标(0,250)开始画线,到坐标(500, 250)位置结束!下面同理!
strokeWidth:画笔线宽;stroke画笔颜色;fill填充颜色;这几个属性,可以决定你画的图形是空心/线条,还是实心!
最关键的点,就是角度和坐标的计算,上面的效果图其实可以看出,我画出来的五边形,并非是正五边形,是因为我为了计算方便,取了个巧,如果有充足的时间以及数学只是掌握的很牢固的画,画出来一个正五边形,那效果会更上一层楼!当然,如果再厉害一点,可以使用贝塞尔曲线,画出一个具有立体感的足球,也是很赞的!
接下来,再自定义一个阴影的组件,这个就很简单了:
@Entry
@Component
export struct FootBallShadow {
build() {
Shape() {
Ellipse()
.width('100%')
.height('100%')
}
.height('100px')
.width('400px')
}
}
最后就是主页引入两个组件的布局:
import { FootBallShadow } from './FootBallShadow';
import { FootBall } from './FootBall';
@Entry
@Component
struct Index {
build() {
Column() {
Text("FIFA World Cup").fontSize(30)
.linearGradient({
direction: GradientDirection.Left, // 渐变方向
colors: [[0xff0000, 0.0], [0xffff00, 0.5]] // 数组末尾元素占比小于1时满足重复着色效果
})
.fontWeight(600)
.margin({ top: 100 })
Text("Qatar 2022").fontColor(Color.Green).fontSize(20).margin({ top: 20 })
Stack() {
Row() {
FootBallShadow()
}
.position({ x: "300px", y: "430px" })
FootBall()
}
.alignContent(Alignment.TopStart)
.width('600px')
.height('500px')
.margin({ top: '40%' })
}
.width('100%')
.height('100%')
.linearGradient(
{
angle: 180,
colors: [['#BDE895', 0.1], ["#95DE7F", 0.6], ["#7AB967", 1]]
})
}
}
足球和阴影部分使用层叠布局Stack,这样,一个简单的世界杯海报就实现了!