# 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)
}
}
}
```

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)
}
}
}
```

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.