🐲龙年使用HarmonyOS Canvas绘制龙年对联

龙年到来,愿您的事业如龙腾飞,家庭幸福美满。

在本文中,我们将使用HarmonyOSCanvas 绘制龙年对联,话不多说,先看效果!

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属性,但是最终的效果都是按照第三条直线的效果绘制的。这是为什么?

HTML5Canvas 一样。在HarmonyOS 中,Canvas组件 也是基于状态 来绘制图形的。Canvas组件 会检测整个程序定义的所有状态 。这些状态包括strokeStylefillStylelineWidth等。

状态 值没有被改变时,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 ,就可以绘制出各种图形

祝大家财源滚滚、身体健康、家庭幸福、工作顺利,新年快乐!🎉🎉🎉

相关推荐
月未央14 分钟前
HarmonyOS Next 开发系列:Local 状态管理实践
harmonyos
浪九天1 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ2 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
椰果uu2 小时前
前端八股万文总结——JS+ES6
前端·javascript·es6
微wx笑2 小时前
chrome扩展程序如何实现国际化
前端·chrome
~废弃回忆 �༄2 小时前
CSS中伪类选择器
前端·javascript·css·css中伪类选择器
CUIYD_19892 小时前
Chrome 浏览器(版本号49之后)‌解决跨域问题
前端·chrome
IT、木易2 小时前
跟着AI学vue第五章
前端·javascript·vue.js
薛定谔的猫-菜鸟程序员3 小时前
Vue 2全屏滚动动画实战:结合fullpage-vue与animate.css打造炫酷H5页面
前端·css·vue.js
春天姐姐3 小时前
vue3项目开发总结
前端·vue.js·git