Using Drawing to Draw and Display Graphics
When to Use
The @ohos.graphics.drawing module provides basic drawing capabilities, such as drawing rectangles, circles, points, line segments, custom paths, and fonts.
Available APIs
The table below lists the common APIs provided by the @ohos.graphics.drawing module. For details about all the APIs, see @ohos.graphics.drawing.
API | Description |
---|---|
drawPath(path: Path) : void | Draws a custom path. |
drawRect(rect: common2D.Rect): void | Draws a rectangle. By default, black is used for filling. |
drawTextBlob(blob: TextBlob, x: number, y: number): void | Draws a text blob. |
moveTo(x: number, y: number) : void | Sets the start point of a path. |
lineTo(x: number, y: number) : void | Draws a line segment from the last point of a path to the target point. |
close(): void | Draws a line segment from the current point to the start point of a path. |
setAntiAlias(aa: boolean) : void | Enables anti-aliasing for this pen or brush. Anti-aliasing makes the edges of the content smoother. |
setColor(color: common2D.Color) : void | Sets a color for this pen or brush. |
setStrokeWidth(width: number) : void | Sets a stroke width for this pen. |
attachPen(pen: Pen): void | Attaches a pen to a canvas so that the canvas can use the style and color of the pen to outline a shape. |
attachBrush(brush: Brush): void | Attaches a brush to a canvas so that the canvas can use the style and color of the brush to fill in a shape. |
How to Develop
Use the canvas and pen of the @ohos.graphics.drawing module to draw basic 2D graphics and text blobs, and call the drawing and display logic to display them on the screen.
The following walks you through on how to draw and display 2D graphics and text blobs.
Adding Dependencies
Adding Dynamic Link Libraries
Add the following libraries to CMakeLists.txt.
libace_ndk.z.so
libnative_window.so
libnative_drawing.so
Importing Dependency Files
import { NodeController, FrameNode, RenderNode, DrawContext } from "@ohos.arkui.node"
import { UIContext } from '@ohos.arkui.UIContext'
import drawing from "@ohos.graphics.drawing"
import image from '@ohos.multimedia.image'
import common2D from '@ohos.graphics.common2D'
Now you can use the APIs for drawing.
Drawing 2D Graphics
Follow the steps below to draw 2D graphics and text blobs by using the canvas and pen of the @ohos.graphics.drawing module.
-
Create a child class of RenderNode. Create the child class MyRenderNode and define drawing functions in it. RenderNode contains operations on the tree structure and drawing attributes.
// Create the MyRenderNode class. class MyRenderNode extends RenderNode { async draw(context: DrawContext) { // ... } }
-
Construct a path shape.
Use moveTo, lineTo, and close of the path to construct a pentagram.
const canvas = context.canvas let height_ = 1200 let width_ = 600 let len = height_ / 4 let aX = width_ / 2 let aY = height_ / 4 let dX = aX - len * Math.sin(18.0) let dY = aY + len * Math.cos(18.0) let cX = aX + len * Math.sin(18.0) let cY = dY let bX = aX + (len / 2.0) let bY = aY + Math.sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0)) let eX = aX - (len / 2.0) let eY = bY; // Create a path object and use the APIs to construct a pentagram. let path = new drawing.Path() // Specify the start point of the path. path.moveTo(aX, aY) // Draw a line segment from the last point of a path to the target point. path.lineTo(bX, bY) path.lineTo(cX, cY) path.lineTo(dX, dY) path.lineTo(eX, eY) // Close the path. Now the path is drawn. path.close()
-
Set the pen and brush styles.
Use Pen to create a pen object, and set the attributes such as anti-aliasing, color, and thickness. The pen is used to outline a shape.
Use Brush to create a brush object, and set the brush color. The brush is used to fill in a shape.
Use attachPen and attachBrush in canvas to attach the pen and brush to the canvas.
// Create a pen object and set the anti-aliasing, color, and thickness attributes. let pen = new drawing.Pen() pen.setAntiAlias(true) let pen_color : common2D.Color = { alpha: 0xFF, red: 0xFF, green: 0x00, blue: 0x00 } pen.setColor(pen_color) pen.setStrokeWidth(10.0) // Attach the pen to the canvas. canvas.attachPen(pen) // Create a brush object and set the color. let brush = new drawing.Brush() let brush_color : common2D.Color = { alpha: 0xFF, red: 0x00, green: 0xFF, blue: 0x00 } brush.setColor(brush_color) // Attach the brush to the canvas. canvas.attachBrush(brush)
-
Draw the pentagram.
Use drawPath in canvas to draw the pentagram on the canvas.
// Draw the path. canvas.drawPath(path)
-
Create a MyRenderNode object.
Steps 1 to 4 build the MyRenderNode class and define the main drawing functions in it. Next, create a MyRenderNode object and set its pixel format.
// Create a MyRenderNode object. const newNode = new MyRenderNode() // Define the pixel format of MyRenderNode. newNode.frame = { x: 100, y: 100, width: 200, height: 800 } newNode.pivot = { x: 0.2, y: 0.8 } newNode.scale = { x: 1, y: 1 }
-
Draw a rectangle.
Use drawRect in canvas to draw a rectangle.
class RectRenderNode extends RenderNode { async draw(context: DrawContext) { const canvas = context.canvas const pen = new drawing.Pen() pen.setStrokeWidth(5) pen.setColor({alpha: 255, red: 255, green: 0, blue: 0}) canvas.attachPen(pen) canvas.drawRect({ left : 200, right : 500, top : 300, bottom : 900}) } } // Create a RectRenderNode object. const rectNode = new RectRenderNode() // Define the pixel format of RectRenderNode. rectNode.frame = { x: 90, y: 100, width: 200, height: 800 } rectNode.pivot = { x: 0.2, y: 0.8 } rectNode.scale = { x: 1, y: 1 }
-
Draw a text blob.
Use drawTextBlob in canvas to draw a text blob.
class TextRenderNode extends RenderNode { async draw(context: DrawContext) { const canvas = context.canvas const brush = new drawing.Brush() brush.setColor({alpha: 255, red: 255, green: 0, blue: 0}) const font = new drawing.Font() font.setSize(100) const textBlob = drawing.TextBlob.makeFromString("Hello World", font, drawing.TextEncoding.TEXT_ENCODING_UTF8) canvas.attachBrush(brush) canvas.drawTextBlob(textBlob, 90, 500) } } // Create a TextRenderNode object. const textNode = new TextRenderNode() // Define the pixel format of TextRenderNode. textNode.frame = { x: 90, y: 100, width: 200, height: 800 } textNode.pivot = { x: 0.2, y: 0.8 } textNode.scale = { x: 1, y: 1 }
-
Create a child class of NodeController.
Create the child class MyNodeController, and define the functions for creating FrameNode in it. NodeController defines the controller of a node container and controls the nodes in the lifecycle of the container. FrameNode defines the basic type of a node and contains a RenderNode.
class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode { this.rootNode = new FrameNode(uiContext) if (this.rootNode == null) { return this.rootNode } const renderNode = this.rootNode.getRenderNode() if (renderNode != null) { renderNode.frame = { x: 0, y: 0, width: 10, height: 500 } renderNode.pivot = { x: 50, y: 50 } } return this.rootNode } }
-
Define an interface for adding a node.
Define an interface for adding a RenderNode in the MyNodeController class created in step 8.
addNode(node: RenderNode): void { if (this.rootNode == null) { return } const renderNode = this.rootNode.getRenderNode() if (renderNode != null) { renderNode.appendChild(node) } }
-
Define an interface for deleting a node.
Define an interface for deleting a RenderNode in the MyNodeController class created in step 8.
clearNodes(): void { if (this.rootNode == null) { return } const renderNode = this.rootNode.getRenderNode() if (renderNode != null) { renderNode.clearChildren() } }
-
Draw the graphics and text blob.
Create a MyNodeController instance and save it to the NodeContainer, add a <\Button> component, and call the defined interfaces.
@Entry @Component struct RenderTest { private myNodeController: MyNodeController = new MyNodeController() build() { Column() { Row() { NodeContainer(this.myNodeController) .height('100%') Button("Draw Path") .margin({ bottom: 200, right: 12 }) .onClick(() => { this.myNodeController.clearNodes() this.myNodeController.addNode(newNode) }) Button("Draw Rect") .margin({ bottom: 200, right: 12 }) .onClick(() => { this.myNodeController.clearNodes() this.myNodeController.addNode(rectNode) }) Button("Draw Text") .margin({ bottom: 200, right: 12 }) .onClick(() => { this.myNodeController.clearNodes() this.myNodeController.addNode(textNode) }) } .width('100%') .justifyContent(FlexAlign.Center) .shadow(ShadowStyle.OUTER_DEFAULT_SM) .alignItems(VerticalAlign.Bottom) .layoutWeight(1) } } }
The following figure shows the drawing and display effect.
Home page | Pentagram drawn | Rectangle drawn | Text blob drawn |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |