Read the original article:Canvas drawing of rectangles cannot cover text.
Problem Description
When using Canvas to draw rectangles and text, the rectangle fails to cover the text area. A sample code example of the issue is as follows:
@Entry
@Component
struct CanvasTestPage {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
drawText: string = 'Harmony Hello\nnTest the line feed Test the line feed\nTest the tabulation\thaha'
build() {
Column() {
Canvas(this.context)
.width('80%')
.height('80%')
.onReady(() => {
this.context.font = '18vp sans-serif'
let text: TextMetrics = this.context.measureText(this.drawText)
this.context.fillStyle = 'rgba(0,0,0,0.3)'
this.context.fillRect(0, 100, text.width, text.height)
this.context.fillStyle = 'rgb(0,0,255)'
this.context.fillText(this.drawText, 0, 100 + text.height)
})
}.margin(10)
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
}
Background Knowledge
fillRect: Fills a rectangle. The four required parameters are the x-coordinate of the top-left corner of the rectangle, the y-coordinate of the top-left corner of the rectangle, the width of the specified rectangle, and the height of the specified rectangle. These four parameters are sufficient to draw a rectangle.
fillText: Fills text. The three required parameters are the text content, the x-coordinate of the starting point for drawing the text, and the y-coordinate of the starting point for drawing the text. These three parameters determine the coordinates for filling the text.
Troubleshooting Process
From the code execution results, it can be observed that the width of the gray rectangle matches the width of the text, and the x-axis starting point is consistent. However, the y-axis starting point of the blue text does not match the y-axis starting point of the gray rectangle. It can be inferred that the issue lies in the y-axis starting point used in the fillRect function.
Analysis Conclusion
According to the parameters of fillRect and fillText, to ensure that the y-coordinate of the top-left corner of the rectangle matches the y-coordinate of the starting point for drawing the text, the drawing will be consistent at the same y-axis starting point. This is different from the incorrect code mentioned earlier:
this.context.fillText(this.drawText, 0, 100 + text.height)
This error code sets the starting point of the text's y-axis to "100 + text height."
Solution
Change the y-coordinate of the starting point for the fillText text.
The textBaseline property can set the horizontal alignment of the text during drawing. Setting it to 'top' aligns the text baseline at the top of the text block. If not set, it defaults to 'alphabetic' alignment (aligned according to letters).
The code modification is as follows:
@Entry
@Component
struct CanvasTestPage {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
drawText: string = 'Harmony Hello\nnTest the line feed Test the line feed\nTest the tabulation\thaha'
build() {
Column() {
Canvas(this.context)
.width('80%')
.height('80%')
.onReady(() => {
this.context.font = '18vp sans-serif'
this.context.textBaseline = 'top'
let text: TextMetrics = this.context.measureText(this.drawText)
this.context.fillStyle = 'rgba(0,0,0,0.3)'
this.context.fillRect(0, 100, text.width, text.height)
this.context.fillStyle = 'rgb(0,0,255)'
this.context.fillText(this.drawText, 0, 100)
})
}.margin(10)
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
}
Verification Result
This example supports API Version 19 Release and later versions.
This example supports HarmonyOS 5.1.1 Release SDK and later versions.
This example requires DevEco Studio 5.1.1 Release or later for building and running.


Top comments (0)