🐲龙年使用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 ,就可以绘制出各种图形

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

相关推荐
秋名山大前端6 小时前
Chrome GPU 加速优化配置(前端 3D 可视化 / 数字孪生专用)
前端·chrome·3d
今天不要写bug6 小时前
antv x6实现封装拖拽流程图配置(适用于工单流程、审批流程应用场景)
前端·typescript·vue·流程图
luquinn6 小时前
实现统一门户登录跳转免登录
开发语言·前端·javascript
被开发耽误的大厨7 小时前
鸿蒙ArkUI 基础篇-06-组件基础语法-Column/Row/Text
华为·harmonyos
用户21411832636027 小时前
dify案例分享-5分钟搭建智能思维导图系统!Dify + MCP工具实战教程
前端
augenstern4167 小时前
HTML(面试)
前端
excel7 小时前
前端常见布局误区:1fr 为什么撑爆了我的容器?
前端
烛阴7 小时前
TypeScript 类型魔法:像遍历对象一样改造你的类型
前端·javascript·typescript
vayy7 小时前
uniapp中 ios端 scroll-view 组件内部子元素z-index失效问题
前端·ios·微信小程序·uni-app
专注API从业者7 小时前
基于 Node.js 的淘宝 API 接口开发:快速构建异步数据采集服务
大数据·前端·数据库·数据挖掘·node.js