# RenderNode The **RenderNode** module provides APIs for creating a RenderNode in custom drawing settings with C APIs. > **NOTE** > > The initial APIs of this module are supported since API version 11. Newly added APIs will be marked with a superscript to indicate their earliest API version. > > **RenderNode** is not available in DevEco Studio Previewer. ## Modules to Import ```ts import { RenderNode } from "@ohos.arkui.node"; ``` ## RenderNode ### constructor constructor() Constructor used to create a RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node"; const renderNode = new RenderNode(); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### appendChild appendChild(node: RenderNode): void Appends a child node to this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------------------- | ---- | ---------------------- | | node | [RenderNode](#rendernode) | Yes | Child node to append.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const child = new RenderNode(); renderNode.appendChild(child); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### insertChildAfter insertChildAfter(child: RenderNode, sibling: RenderNode | null): void Inserts a child node after the specified child node of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | ------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | | child | [RenderNode](#rendernode) | Yes | Child node to add. | | sibling | [RenderNode](#rendernode) \| null | Yes | Node after which the new child node will be inserted. If this parameter is left empty, the new node is inserted before the first subnode.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { renderNode.appendChild(new RenderNode()); } const child = new RenderNode(); const sibling = renderNode.getChild(1); renderNode.insertChildAfter(child, sibling); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### removeChild removeChild(node: RenderNode): void Deletes the specified child node from this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------------------- | ---- | ------------------ | | node | [RenderNode](#rendernode) | Yes | Child node to delete.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { renderNode.appendChild(new RenderNode()); } const node = renderNode.getChild(1); renderNode.removeChild(node); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### clearChildren clearChildren(): void Clears all child nodes of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { let childNode = new RenderNode(); childNode.size = {width: i*10 ,height : i*10}; childNode.position = {x: i*10 ,y : i*10}; childNode.backgroundColor = 0xFF0000FF - 0X11 * i; renderNode.appendChild(childNode); } class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Column() { NodeContainer(this.myNodeController) .borderWidth(1) .width(200) .height(300) Button("clearChildren") .onClick(()=>{ renderNode.clearChildren(); }) }.width("100%") } } ``` ### getChild getChild(index: number): RenderNode | null Obtains the child node in the specified position of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | ------- | ------- | ---- | ------------------ | | index | number | Yes | Index of the child node to obtain.| **Return value** | Type | Description | | --------------------------------- | ---------------------------------------------------------- | | [RenderNode](#rendernode) \| null | Child node obtained. If the RenderNode does not contain the specified child node, null is returned.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { let childNode = new RenderNode(); childNode.size = {width: i*10 ,height : i*10}; childNode.position = {x: i*10 ,y : i*10}; childNode.backgroundColor = 0xFF0000FF - 0X11 * i; renderNode.appendChild(childNode); } class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Column() { NodeContainer(this.myNodeController) .borderWidth(1) .width(200) .height(300) Button("getChild") .onClick(()=>{ for (let i = 0; i < 11; i++) { let childNode : RenderNode | null = renderNode.getChild(i); if(childNode == null){ console.log(`the ${i} of renderNode's childNode is null`); } else { console.log(`the ${i} of renderNode's childNode has a size of {${childNode.size.width},${childNode.size.height}}`); } } }) }.width("100%") } } ``` ### getFirstChild getFirstChild(): RenderNode | null Obtains the first child node of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | --------------------------------- | ---------------------------------------------------------- | | [RenderNode](#rendernode) \| null | First child node. If the RenderNode does not contain any child node, null is returned.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { renderNode.appendChild(new RenderNode()); } const firstChild = renderNode.getFirstChild(); class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### getNextSibling getNextSibling(): RenderNode | null Obtains the next sibling node of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | --------------------------------- | -------------------------------------------------------------------------------------- | | [RenderNode](#rendernode) \| null | Next sibling node of the current RenderNode. If the RenderNode does not have the next sibling node, null is returned.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { renderNode.appendChild(new RenderNode()); } const child = renderNode.getChild(1); if (child !== null) { const nextSibling = child.getNextSibling(); } class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### getPreviousSibling getPreviousSibling(): RenderNode | null Obtains the previous sibling node of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | --------------------------------- | -------------------------------------------------------------------------------------- | | [RenderNode](#rendernode) \| null | Previous sibling node of the current RenderNode. If the RenderNode does not have the previous sibling node, null is returned.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); for (let i = 0; i < 10; i++) { renderNode.appendChild(new RenderNode()); } const child = renderNode.getChild(1); if (child !== null) { const nextSibling = child.getPreviousSibling(); } class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### backgroundColor set backgroundColor(color: number) Sets the background color for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ---------------------- | | color | number | Yes | Background color value, in ARGB format.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.backgroundColor = 0XFF00FF00; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get backgroundColor(): number Obtains the background color of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | ---------------------------------------------- | | number | Background color of the current RenderNode. The default value is **0X00000000**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const backgroundColor = renderNode.backgroundColor; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### clipToFrame set clipToFrame(useClip: boolean) Sets whether to clip this RenderNode. The value **true** means to clip the RenderNode to its set size. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | ------- | ------- | ---- | ------------------ | | useClip | boolean | Yes | Whether to clip the RenderNode.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.clipToFrame = true; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get clipToFrame(): boolean Obtains whether this RenderNode needs to be clipped. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------- | --------------------------------------------------- | | boolean | Whether the current RenderNode needs to be clipped. The default value is **false**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const clipToFrame = renderNode.clipToFrame; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### opacity set opacity(value: number) Sets the opacity for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | -------------------------------------- | | value | number | Yes | Opacity to set.\
Value range: [0, 1]| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.opacity = 0.5; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get opacity(): number Obtains the opacity of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | ----------------------------------------- | | number | Opacity of the current RenderNode. The default value is **1**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const opacity = renderNode.opacity; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### size set size(size: Size) Sets the size for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ---------------------------------------- | ---- | ---------------------------- | | size | [Size](./js-apis-arkui-graphics.md#size) | Yes | Size to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.size = { width: 100, height: 100 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get size(): Size Obtains the size of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Name | Description | | ---------------------------------------- | ----------------------------------------------- | | [Size](./js-apis-arkui-graphics.md#size) | Size of the current RenderNode. The default width and height are **0**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const size = renderNode.size; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### position set position(position: Position) Sets the position for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------ | ---- | ---------------------------- | | position | [Position](./js-apis-arkui-graphics.md#position) | Yes | Position to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.position = { x: 100, y: 100 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get position(): Position Obtains the position of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------------------------------------------------ | ---------------------------------------------------- | | [Position](./js-apis-arkui-graphics.md#position) | Position of the current RenderNode. The default value is **{ x: 0, y: 0 }**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const position = renderNode.position; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### frame set frame(frame: Frame) Sets the size and position for this RenderNode. When this parameter is used together with [position](#position) and [size](#size), the one that is set later in time prevails. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------------------------------------ | ---- | -------------------------------- | | frame | [Frame](./js-apis-arkui-graphics.md#frame) | Yes | Size and position to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.frame = { x: 50, y: 50, width: 100, height: 100 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get frame(): Frame Obtains the size and position of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | --------------- | ------------------------------------------------------------ | | [Frame](#frame) | Size and position of the current RenderNode. The default value is **{ x: 0, y: 0, width: 0, height: 0 }**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const frame = renderNode.frame; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### pivot set pivot(pivot: Pivot) Sets the pivot for this RenderNode, which affects the scaling and rotation effects of the RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------------------------------------ | ---- | ---------------------------- | | pivot | [Pivot](./js-apis-arkui-graphics.md#pivot) | Yes | Pivot to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.pivot = { x: 0.5, y: 0.6 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get pivot(): Pivot Obtains the pivot of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------------------------------------------ | --------------------------------------------------------- | | [Pivot](./js-apis-arkui-graphics.md#pivot) | Pivot of the current RenderNode. The default value is **{ x: 0.5, y: 0.5}**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const pivot = renderNode.pivot; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### scale set scale(scale: Scale) Sets the scale factor for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------------------------------------------ | ---- | -------------------------------- | | scale | [Scale](./js-apis-arkui-graphics.md#scale) | Yes | Scale factor to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.scale = { x: 0.5, y: 1 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get scale(): Scale Obtains the scale factor of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------------------------------------------ | -------------------------------------------------- | | [Scale](./js-apis-arkui-graphics.md#scale) | Scale factor of the current RenderNode. The default value is **{ x: 1, y: 1 }**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const scale = renderNode.scale; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### translation set translation(translation: Translation) Sets the translation amount for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | ----------- | ------------------------------------------------------ | ---- | ------------------------------ | | translation | [Translation](./js-apis-arkui-graphics.md#translation) | Yes | Translation amount to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.translation = { x: 0, y: 1 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get translation(): Translation Obtains the translation amount of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------------------------------------------------------ | ---------------------------------------------------- | | [Translation](./js-apis-arkui-graphics.md#translation) | Translation amount of the current RenderNode. The default value is **{ x: 0, y: 0 }**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const translation = renderNode.translation; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### rotation set rotation(rotation: Rotation) Sets the rotation angle for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------ | ---- | -------------------------------- | | rotation | [Rotation](./js-apis-arkui-graphics.md#rotation) | Yes | Rotation angle to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.rotation = { x: 10, y: 45, z: 0 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get rotation(): Rotation Obtains the rotation angle of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------------------------------------------------ | ------------------------------------------------------- | | [Rotation](./js-apis-arkui-graphics.md#rotation) | Rotation angle of the current RenderNode. The default value is **{ x: 0, y: 0, z: 0}**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const rotation = renderNode.rotation; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### transform set transform(transform: Matrix4) Sets the transformation information for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | --------- | ---------------------------------------------- | ---- | -------------------------------- | | transform | [Matrix4](./js-apis-arkui-graphics.md#matrix4) | Yes | Transformation information to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.transform = [ 1, 0, 45, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get transform(): Matrix4 Obtains the transformation information of this RenderNode. The default value is as follows: ```ts [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ``` **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ---------------------------------------------- | -------------------------- | | [Matrix4](./js-apis-arkui-graphics.md#matrix4) | Transformation information of the current RenderNode.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const transform = renderNode.transform; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### shadowColor set shadowColor(color: number) Sets the shadow color for this RenderNode, in ARGB format. If [shadowAlpha](#shadowalpha) is set, the opacity is subject to **shadowAlpha**. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ------------------------------------------ | | color | number | Yes | Shadow color to set, in ARGB format.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.shadowColor = 0XFF00FF00; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get shadowColor(): number Obtains the shadow color of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | -------------------------------------------------------- | | number | Shadow color of the current RenderNode, in ARGB format. The default value is **0X00000000**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const shadowColor = renderNode.shadowColor; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### shadowOffset set shadowOffset(offset: Offset) Sets the shadow offset for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | -------------------------------------------- | ---- | -------------------------------- | | offset | [Offset](./js-apis-arkui-graphics.md#offset) | Yes | Shadow offset to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.shadowOffset = { x: 10, y: 10 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get shadowOffset(): Offset Obtains the shadow offset of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | -------------------------------------------- | -------------------------------------------------- | | [Offset](./js-apis-arkui-graphics.md#offset) | Shadow offset of the current RenderNode. The default value is **{ x: 0, y: 0 }**.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const shadowOffset = renderNode.shadowOffset; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### shadowAlpha set shadowAlpha(alpha: number) Sets the alpha value of the shadow color for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ----------------------------------------- | | alpha | number | Yes | Alpha value of the shadow color to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.shadowAlpha = 0.5; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` get shadowAlpha(): number Obtains the alpha value of the shadow color of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | ---------------------------------------------- | | number | Alpha value of the shadow color of the current RenderNode. The default value is **0**.| ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const shadowAlpha = renderNode.shadowAlpha; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### shadowElevation set shadowElevation(elevation: number) Sets the shadow elevation for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | --------- | ------ | ---- | -------------------------------- | | elevation | number | Yes | Shadow elevation to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.frame = { x: 0, y: 0, width: 100, height: 100 }; renderNode.shadowOffset = { x: 10, y: 10 }; renderNode.shadowAlpha = 0.7; renderNode.shadowElevation = 30; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ![shadowElevation](./figures/ShadowElevation.jpg) get shadowElevation(): number Obtains the shadow elevation of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | ------------------------------------- | | number | Shadow elevation of the current RenderNode. The default value is **0**.| ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const shadowElevation = renderNode.shadowElevation; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### shadowRadius set shadowRadius(radius: number) Sets the shadow blur radius for this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name| Type | Mandatory| Description | | ------ | ------ | ---- | ------------------------------------ | | radius | number | Yes | Shadow blur radius to set.| **Example** ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); renderNode.frame = { x: 0, y: 0, width: 100, height: 100 }; renderNode.shadowOffset = { x: 10, y: 10 }; renderNode.shadowAlpha = 0.7; renderNode.shadowRadius = 30; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ![shadowRadius](./figures/ShadowRadius.jpg) get shadowRadius(): number Obtains the shadow blur radius of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Return value** | Type | Description | | ------ | ----------------------------------------- | | number | Shadow blur radius of the current RenderNode. The default value is **0**.| ```ts import { RenderNode, FrameNode, NodeController } from "@ohos.arkui.node" const renderNode = new RenderNode(); const shadowRadius = renderNode.shadowRadius; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` ### draw draw(context: DrawContext): void Performs drawing. You need to implement this API. It is called when the RenderNode performs drawing. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** | Name | Type | Mandatory| Description | | ------- | ------------------------------------------------------ | ---- | ---------------- | | context | [DrawContext](./js-apis-arkui-graphics.md#drawcontext) | Yes | Graphics drawing context.| **Example** Code in ArkTS: ```ts // Index.ets import bridge from "libentry.so" // This .so file is compiled and generated by you using the N-API. import { RenderNode, DrawContext, NodeController, FrameNode } from "@ohos.arkui.node" class MyRenderNode extends RenderNode { draw(context: DrawContext) { // The width and height in the context need to be converted from vp to px. bridge.nativeOnDraw(0, context, vp2px(context.size.height), vp2px(context.size.width)); } } class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const rootRenderNode = this.rootNode.getRenderNode(); if (rootRenderNode !== null) { const renderNode = new MyRenderNode(); renderNode.size = { width: 100, height: 100 } rootRenderNode.appendChild(renderNode); } return this.rootNode; } } @Entry @Component struct Index { private myNodeController: MyNodeController = new MyNodeController(); build() { Row() { NodeContainer(this.myNodeController) } } } ``` The C++ side can obtain the canvas through the N-API and perform subsequent custom drawing operations. ```c++ // native_bridge.cpp #include "napi/native_api.h" #include #include #include #include static napi_value OnDraw(napi_env env, napi_callback_info info) { size_t argc = 4; napi_value args[4] = { nullptr }; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); int32_t id; napi_get_value_int32(env, args[0], &id); // Obtain the pointer to the canvas. void* temp = nullptr; napi_unwrap(env, args[1], &temp); OH_Drawing_Canvas *canvas = reinterpret_cast(temp); // Obtain the canvas width. int32_t width; napi_get_value_int32(env, args[2], &width); // Obtain the canvas height. int32_t height; napi_get_value_int32(env, args[3], &height); // Pass in information such as the canvas, height, and width to the drawing API for customized drawing. auto path = OH_Drawing_PathCreate(); OH_Drawing_PathMoveTo(path, width / 4, height / 4); OH_Drawing_PathLineTo(path, width * 3 / 4, height / 4); OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4); OH_Drawing_PathLineTo(path, width / 4, height * 3 / 4); OH_Drawing_PathLineTo(path, width / 4, height / 4); OH_Drawing_PathClose(path); auto pen = OH_Drawing_PenCreate(); OH_Drawing_PenSetWidth(pen, 10); OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); OH_Drawing_CanvasAttachPen(canvas, pen); OH_Drawing_CanvasDrawPath(canvas, path); return nullptr; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { { "nativeOnDraw", nullptr, OnDraw, nullptr, nullptr, nullptr, napi_default, nullptr } }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } EXTERN_C_END static napi_module demoModule = { .nm_version =1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "entry", .nm_priv = ((void*)0), .reserved = { 0 }, }; extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } ``` Add the following content to the **src/main/cpp/CMakeLists.txt** file of the project: ```cmake # the minimum version of CMake. cmake_minimum_required(VERSION 3.4.1) project(NapiTest) set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) add_library(entry SHARED native_bridge.cpp) target_link_libraries(entry PUBLIC libace_napi.z.so) target_link_libraries(entry PUBLIC libace_ndk.z.so) target_link_libraries(entry PUBLIC libnative_drawing.so) ``` In addition, add the definition of the custom drawing API on the ArkTs side to the **src/main/cpp/types/libentry/index.d.ts** file of the project. The following is an example: ```ts import { DrawContext } from "@ohos.arkui.node" export const nativeOnDraw: (id: number, context: DrawContext, width: number, height: number) => number; ``` ### invalidate invalidate(): void Triggers the re-rendering of this RenderNode. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Example** ```ts import bridge from "libentry.so" // This .so file is compiled and generated by you using the N-API. import { RenderNode, DrawContext, FrameNode, NodeController } from "@ohos.arkui.node" class MyRenderNode extends RenderNode { draw(context: DrawContext) { // The width and height in the context need to be converted from vp to px. bridge.nativeOnDraw(0, context, vp2px(context.size.height), vp2px(context.size.width)); } } const newNode = new MyRenderNode(); newNode.size = { width: 100, height: 100 }; class MyNodeController extends NodeController { private rootNode: FrameNode | null = null; makeNode(uiContext: UIContext): FrameNode | null { this.rootNode = new FrameNode(uiContext); const renderNode = this.rootNode.getRenderNode(); if (renderNode === null) { return this.rootNode; } renderNode.appendChild(newNode); return this.rootNode; } } @Entry @Component struct Index { build() { Column() { Column() { NodeContainer(new MyNodeController()) .width('100%') Button('Invalidate') .onClick(() => { newNode.invalidate() }) } .width('100%') .height('100%') } .height('100%') } } ``` For details about how to build **libentry.so**, see the example of the **draw** API.