龙年到来,愿您的事业如龙腾飞,家庭幸福美满。
在本文中,我们将使用HarmonyOS 的Canvas 绘制龙年对联,话不多说,先看效果!
1.绘制背景
1.1画矩形
在Canvas组件 中,我们可以配合使用fillStyle 属性和fillRect()方法来画一个填充矩形。代码如下所示。
arduino
this.context.fillStyle = bgColor
this.context.fillRect(x, y, width, height)
fillStyle是context对象的一个属性,指定绘制的填充色。
fillRect ()是context对象的一个方法,填充一个矩形。其中,(x,y)为矩形左上角 点的坐标,width 表示矩形的宽度,height表示矩形的高度。如下图所示。

注意:fillStyle属性必须在使用fillRect()方法之前定义,否则fillStyle属性无效。
1.2画线
在Canvas组件 中,我们可以将moveTo ()和lineTo ()这两个方法配合使用来画直线。利用这两个方法,我们可以画一条直线,也可以同时画多条直线。代码如下所示。
kotlin
this.context.moveTo(x1, y1)
this.context.lineTo(x2, y2)
this.context.lineWidth = 2
this.context.strokeStyle = frameColor
this.context.stroke()
其中,(x1,y1)表示直线起点 的坐标,(x2,y2)表示直线终点 的坐标。moveTo (x1,y1)的含义是将画笔移到点(x1,y1)位置,然后开始绘图。lineTo(x2,y2)的含义是使用画笔从起点(x1,y1)开始画直线,一直画到终点(x2,y2)。
lineWidth 是context对象的一个属性,定义线条的宽度。
strokeStyle 是context对象的一个属性,设置描边的颜色。
stroke()是context对象的一个方法,进行边框绘制操作。如下图所示。

注意:只有调用stroke()方法后,起点坐标和终点坐标才会连线,否则无效。
1.3路径和状态
在Canvas组件 中,路径 是一个非常重要的概念。直线、多边形、圆形、弧线、贝塞尔曲线,都是以路径为基础的。
在Canvas组件 中,我们可以使用beginPath ()方法和closePath ()方法来操作路径。
其中,beginPath ()方法用来创建一个新的绘制路径,closePath()方法用来结束当前路径形成一个封闭路径。
下面通过一个例子向您介绍路径是怎么一回事。
kotlin
//第一条直线
this.context.lineWidth = 1
this.context.moveTo(100, 100)
this.context.lineTo(150, 100)
this.context.strokeStyle = '#ff0000'
this.context.stroke()
//第二条直线
this.context.lineWidth = 2
this.context.moveTo(100, 100)
this.context.lineTo(100, 200)
this.context.strokeStyle = '#ff00ff'
this.context.stroke()
//第三条直线
this.context.lineWidth = 3
this.context.moveTo(100, 200)
this.context.lineTo(150, 200)
this.context.strokeStyle = '#ffff00'
this.context.stroke()
上述代码中,我们绘制了3条直线,如下图所示。

您可能发现了,3条直线都有相对应的lineWidth 属性和strokeStyle属性,但是最终的效果都是按照第三条直线的效果绘制的。这是为什么?
和HTML5 的Canvas 一样。在HarmonyOS 中,Canvas组件 也是基于状态 来绘制图形的。Canvas组件 会检测整个程序定义的所有状态 。这些状态包括strokeStyle 、fillStyle 和lineWidth等。
当状态 值没有被改变时,Canvas组件 就一直使用最初的值。当状态 值被改变时,后面的值会覆盖 前面的值。也就是strokeStyle = '#ff00ff'会覆盖strokeStyle = '#ff0000',然后strokeStyle = '#ffff00'会覆盖strokeStyle = '#ff00ff'。
lineWidth 属性的值也一样会被覆盖。所以strokeStyle 属性的值最终取值为#ffff00,lineWidth属性的值最终取值为3。
我们使用beginPath()方法开始一个新的路径,效果又是怎么样呢?代码如下所示。
kotlin
//第一条直线
this.context.lineWidth = 2
this.context.beginPath()
this.context.moveTo(100, 100)
this.context.lineTo(150, 100)
this.context.strokeStyle = '#ff0000'
this.context.stroke()
//第二条直线
this.context.beginPath()
this.context.moveTo(100, 100)
this.context.lineTo(100, 200)
this.context.strokeStyle = '#ff00ff'
this.context.stroke()
//第三条直线
this.context.beginPath()
this.context.moveTo(100, 200)
this.context.lineTo(150, 200)
this.context.strokeStyle = '#ffff00'
this.context.stroke()
由于使用了beginPath ()方法,所以此时3条直线位于不同的路径 中。因此,不同路径 中定义的状态 不会像上面的例子那样发生覆盖 。而lineWidth 属性的值在3条路径中都没有被改变,所以Canvas组件就一直使用最初的属性值。如下图所示。

注意:要判断是否属于同一路径的标准是是否使用了beginPath()方法,而使用了beginPath()方法会开始一个新的路径。
最后我们使用closePath()方法来关闭当前路径。代码如下所示。
kotlin
this.context.lineWidth = 2
this.context.strokeStyle = '#ff0000'
this.context.beginPath()
this.context.moveTo(150, 100)
this.context.lineTo(100, 100)
this.context.lineTo(100, 200)
this.context.lineTo(150, 200)
this.context.stroke()
上述代码中,我们使用moveTo ()和lineTo()这两个方法绘制了多条直线。如下图所示。

现在,我们想要一个闭合 的矩形,有2种 方法可以实现:lineTo ()方法和closePath()方法。
用lineTo ()方法需要我们连接最后一个点,而使用closePath ()方法最后一个lineTo ()方法是可以省略 的,Canvas组件 会自动帮我们连接起点 和终点。如下图所示。

我们将lineWidth 的属性设置为12,如下图所示。

此时可以看出,如果使用lineTo ()方法来封闭图形,会有一个如上图所示的缺口 。 要想解决这个问题,需要将lineCap 属性的值设置为square ,默认值为butt。代码如下所示。
ini
this.context.lineCap = 'square'
1.4绘制背景
接下来,我们就来绘制对联的背景,代码如下所示。
kotlin
drawBgView(x: number, y: number, width: number, height: number) {
const intervalWidth: number = 5 //边框间隙
const elementWidth: number = 10 //描边的宽度
const bgColor: string = '#e50014' //背景颜色
const frameColor: string = '#f3dfa8' //边框的颜色
//绘制背景
this.context.fillStyle = bgColor
this.context.fillRect(x, y, width, height)
//边框修饰
this.context.beginPath()
this.context.lineWidth = 2
this.context.strokeStyle = frameColor
this.context.moveTo(x + elementWidth, y + elementWidth)
this.context.lineTo(x + elementWidth * 2, y + elementWidth)
this.context.lineTo(x + elementWidth * 2, y + elementWidth * 2 + intervalWidth)
this.context.lineTo(x + elementWidth, y + elementWidth * 2 + intervalWidth)
this.context.lineTo(x + elementWidth, y + height - elementWidth * 2 - intervalWidth)
this.context.lineTo(x + elementWidth * 2, y + height - elementWidth * 2 - intervalWidth)
this.context.lineTo(x + elementWidth * 2, y + height - elementWidth)
this.context.lineTo(x + elementWidth, y + height - elementWidth)
this.context.lineTo(x + elementWidth, y + height - elementWidth * 2)
this.context.lineTo(x + elementWidth * 2 + intervalWidth, y + height - elementWidth * 2)
this.context.lineTo(x + elementWidth * 2 + intervalWidth, y + height - elementWidth)
this.context.lineTo(x + width - elementWidth * 2 - intervalWidth, y + height - elementWidth)
this.context.lineTo(x + width - elementWidth * 2 - intervalWidth, y + height - elementWidth * 2)
this.context.lineTo(x + width - elementWidth, y + height - elementWidth * 2)
this.context.lineTo(x + width - elementWidth, y + height - elementWidth)
this.context.lineTo(x + width - elementWidth * 2, y + height - elementWidth)
this.context.lineTo(x + width - elementWidth * 2, y + height - elementWidth * 2 - intervalWidth)
this.context.lineTo(x + width - elementWidth, y + height - elementWidth * 2 - intervalWidth)
this.context.lineTo(x + width - elementWidth, y + elementWidth * 2 + intervalWidth)
this.context.lineTo(x + width - elementWidth * 2, y + elementWidth * 2 + intervalWidth)
this.context.lineTo(x + width - elementWidth * 2, y + elementWidth)
this.context.lineTo(x + width - elementWidth, y + elementWidth)
this.context.lineTo(x + width - elementWidth, y + elementWidth * 2)
this.context.lineTo(x + width - elementWidth * 2 - intervalWidth, y + elementWidth * 2)
this.context.lineTo(x + width - elementWidth * 2 - intervalWidth, y + elementWidth)
this.context.lineTo(x + elementWidth * 2 + intervalWidth, y + elementWidth)
this.context.lineTo(x + elementWidth * 2 + intervalWidth, y + elementWidth * 2)
this.context.lineTo(x + elementWidth, y + elementWidth * 2)
this.context.stroke()
this.context.closePath()
}
在onReady ()回调事件中,设置背景的坐标 和宽高,代码如下所示。
kotlin
this.drawBgView(50, 50, 300, 120)
this.drawBgView(50, 200, 100, 500)
this.drawBgView(250, 200, 100, 500)
此时我们就绘制好横批 ,上联 和下联的背景。如下图所示。

2.绘制文字
2.1文本操作
在Canvas组件 中,为我们提供了不少方法 和属性 来绘制文本。
方法 | 说明 |
---|---|
fillText() | 绘制填充类文本 |
strokeText() | 绘制描边类文本 |
measureText() | 测算指定文本的宽度和高度值 |
属性 | 说明 |
font | 设置文本绘制中的字体样式 |
fillStyle | 绘制的填充色 |
strokeStyle | 设置描边的颜色 |
在Canvas组件 中,我们可以使用fillText()方法来绘制填充文本。代码如下所示。
kotlin
this.context.font = '80px bold'
this.context.fillStyle = '#e50014'
this.context.fillText('龙',x1,y1)
我们使用fillText ()方法绘制了一个文字,其大小为80px ,粗体 ,文本的颜色 为#e50014,(x1,y1)坐标表示文本左下角的坐标,如下图所示。

font 属性不仅可以设置字体的大小 和粗细 ,还可以设置字体 和样式,如要设置字体为斜体,代码如下所示。
ini
this.context.font = 'italic 80px bold'
在Canvas组件 中,我们使用measureText ()方法来测量绘制文本的宽度 和高度等信息。代码如下所示。
kotlin
let textWidth = this.context.measureText('龙').width
let textHeight = this.context.measureText('龙').height
this.context.fillText('W:' + textWidth, 100, 260)
this.context.fillText('H:' + textHeight, 100, 300)
获取文本的宽度 和高度,对于实现水平居中和垂直居中的文本效果是非常有用的。如下图所示。

2.2绘制对联的文字
接下来,我们就来绘制对联中的文字,代码如下所示。
ini
drawBanner(x: number, y: number, width: number, height: number, stepy: number, text: string) {
const bgColor: string = '#e50014'
const frameColor: string = '#f3dfa8'
const frameWidth: number = 60
const intervalWidth: number = 5
const elementWidth: number = 10
const spaceWidth: number = 2.5 * stepy
//文字
this.context.font = '80px bold'
this.context.fillStyle = bgColor
let widthText = this.context.measureText(text).width
let heightText = this.context.measureText(text).height
this.context.fillText(text, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + (30 - widthText) / 2, y + (height - frameWidth) / 2 + (60 - heightText) / 2 + heightText - 5)
}
drawLink(x: number, y: number, width: number, height: number, stepy: number, text: string) {
const bgColor: string = '#e50014'
const frameColor: string = '#f3dfa8'
const frameWidth: number = 50
const intervalWidth: number = 5
const elementWidth: number = 10
const spaceWidth: number = ((height - (elementWidth * 2 + intervalWidth * 2) * 2) / 7 - frameWidth) * stepy
//文字
this.context.font = '80px bold'
this.context.fillStyle = bgColor
let widthText = this.context.measureText(text).width
let heightText = this.context.measureText(text).height
this.context.fillText(text,x + elementWidth * 2 + intervalWidth + frameWidth/2 - widthText/2,y + frameWidth / 2 + (frameWidth - heightText) / 2 + heightText + frameWidth * stepy + spaceWidth)
}
在onReady()回调事件中,设置对联的文字,代码如下所示。
csharp
const banner: string[] = ['龙', '年', '吉', '祥']
const upperlink: string[] = ['平', '安', '喜', '乐', '福', '星', '照']
const lowerlink: string[] = ['龙', '年', '大', '吉', '好', '运', '来']
for (let index = 0; index < banner.length; index++) {
this.drawBanner(50, 50, 300, 120, index, banner[index])
}
for (let index = 0; index < upperlink.length; index++) {
this.drawLink(50, 200, 100, 500, index, upperlink[index])
}
for (let index = 0; index < lowerlink.length; index++) {
this.drawLink(250, 200, 100, 500, index, lowerlink[index])
}
此时我们就绘制好对联中的文字。如下图所示。

最后,为文字绘制背景,代码如下所示。
kotlin
drawBanner(x: number, y: number, width: number, height: number, stepy: number, text: string) {
const bgColor: string = '#e50014'
const frameColor: string = '#f3dfa8'
const frameWidth: number = 60
const intervalWidth: number = 5
const elementWidth: number = 10
const spaceWidth: number = 2.5 * stepy
//元素
this.context.beginPath()
this.context.moveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth * 2)
this.context.quadraticCurveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 - 25, y + height / 2, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 3)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 2)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 2)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 3)
this.context.quadraticCurveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2 + 25, y + height / 2, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth * 2)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth)
this.context.closePath()
this.context.fillStyle = frameColor
this.context.fill()
//修饰 上
this.context.beginPath()
this.context.lineWidth = 2
this.context.moveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + intervalWidth, y + (height - frameWidth) / 2 + intervalWidth * 2)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2 - intervalWidth, y + (height - frameWidth) / 2 + intervalWidth * 2)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 下
this.context.beginPath()
this.context.lineWidth = 2
this.context.moveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + intervalWidth, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 3)
this.context.lineTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2 - intervalWidth, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 3)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 左
this.context.beginPath()
this.context.moveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth * 3)
this.context.lineWidth = 2
this.context.quadraticCurveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 - 15, y + height / 2, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 4)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 右
this.context.beginPath()
this.context.lineWidth = 2
this.context.moveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth * 3)
this.context.quadraticCurveTo((x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2 + 15, y + height / 2, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + frameWidth / 2, y + (height - frameWidth) / 2 + intervalWidth + frameWidth - intervalWidth * 4)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//文字
this.context.font = '80px bold'
this.context.fillStyle = bgColor
let widthText = this.context.measureText(text).width
let heightText = this.context.measureText(text).height
this.context.fillText(text, (x + elementWidth * 2 + intervalWidth) + frameWidth * stepy + spaceWidth + frameWidth / 4 + (30 - widthText) / 2, y + (height - frameWidth) / 2 + (60 - heightText) / 2 + heightText - 5)
}
drawLink(x: number, y: number, width: number, height: number, stepy: number, text: string) {
const bgColor: string = '#e50014'
const frameColor: string = '#f3dfa8'
const frameWidth: number = 50
const intervalWidth: number = 5
const elementWidth: number = 10
const spaceWidth: number = ((height - (elementWidth * 2 + intervalWidth * 2) * 2) / 7 - frameWidth) * stepy
//元素
this.context.beginPath()
this.context.moveTo(x + elementWidth * 2 + intervalWidth + 15, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 2)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + 15, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3)
this.context.quadraticCurveTo(x + elementWidth * 2 + intervalWidth - 15, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + (frameWidth - elementWidth * 2) / 2, x + elementWidth * 2 + intervalWidth + 15, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + 15, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2 + intervalWidth)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2 + intervalWidth)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2)
this.context.quadraticCurveTo(x + elementWidth * 2 + intervalWidth + 15 + 20 + 30, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + (frameWidth - elementWidth * 2) / 2, x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 2)
this.context.closePath()
this.context.fillStyle = frameColor
this.context.fill()
//修饰 上
this.context.beginPath()
this.context.lineWidth = 2
this.context.moveTo(x + elementWidth * 2 + intervalWidth + elementWidth * 2, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + elementWidth * 2 + elementWidth, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 下
this.context.beginPath()
this.context.lineWidth = 2
this.context.moveTo(x + elementWidth * 2 + intervalWidth + elementWidth * 2, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2)
this.context.lineTo(x + elementWidth * 2 + intervalWidth + elementWidth * 2 + elementWidth, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 左
this.context.beginPath()
this.context.moveTo(x + elementWidth * 2 + intervalWidth + intervalWidth * 3, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 4)
this.context.lineWidth = 2
this.context.quadraticCurveTo(x + elementWidth * 2 + intervalWidth - intervalWidth, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + (frameWidth - elementWidth * 2) / 2, x + elementWidth * 2 + intervalWidth + intervalWidth * 3, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2 - intervalWidth)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//修饰 右
this.context.beginPath()
this.context.moveTo(x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 4)
this.context.lineWidth = 2
this.context.quadraticCurveTo(x + elementWidth * 2 + intervalWidth + 15 + 20 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + (frameWidth - elementWidth * 2) / 2, x + elementWidth * 2 + intervalWidth + 15 + 20, y + elementWidth * 2 + intervalWidth + frameWidth * stepy + spaceWidth + intervalWidth * 3 + frameWidth - elementWidth * 2 - intervalWidth)
this.context.strokeStyle = bgColor
this.context.stroke()
this.context.closePath()
//文字
this.context.font = '80px bold'
this.context.fillStyle = bgColor
let widthText = this.context.measureText(text).width
let heightText = this.context.measureText(text).height
this.context.fillText(text,x + elementWidth * 2 + intervalWidth + frameWidth/2 - widthText/2,y + frameWidth / 2 + (frameWidth - heightText) / 2 + heightText + frameWidth * stepy + spaceWidth)
}
最终效果

总结
在HarmonyOS 中,Canvas组件 提供画布,用于自定义绘制图形。掌握了Canvas组件 提供的API ,就可以绘制出各种图形。
祝大家财源滚滚、身体健康、家庭幸福、工作顺利,新年快乐!🎉🎉🎉