1e41f4b71Sopenharmony_ci# RenderNode
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciFor third-party frameworks that do not have their own rendering environment, although they have implemented frontend parsing and processing for layout and events, they rely on the system's basic rendering and animation capabilities. The universal attributes and events on [FrameNode](./arkts-user-defined-arktsNode-frameNode.md) are superfluous for such frameworks, leading to redundant operations, including handling logic for layout and events.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThis is where [RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md) comes into the picture. **RenderNode** is a more lightweight rendering node that includes only rendering-related capabilities. It exposes the capability to set basic rendering attributes and provides capabilities for dynamically adding or removing nodes, as well as custom drawing. This can supply third-party frameworks with basic rendering and animation functionalities.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci## Creating and Removing Nodes
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciYou can create and remove nodes with **RenderNode**. You can create a custom instance of **RenderNode** using its constructor, and the instance thereby created corresponds to an entity node. You can use the **dispose** API in **RenderNode** to break the binding with the entity node.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci## Operating the Node Tree
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciWith **RenderNode**, you can add, delete, query, and modify nodes, thereby changing the subtree structure of nodes; you can also query the parent-child relationships to obtain the results.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci> **NOTE**
18e41f4b71Sopenharmony_ci>
19e41f4b71Sopenharmony_ci> - The subtree structure obtained through queries in **RenderNode** is constructed based on the parameters passed through the APIs of **RenderNode**.
20e41f4b71Sopenharmony_ci>
21e41f4b71Sopenharmony_ci> - To display a RenderNode in conjunction with built-in components, you need to mount the RenderNode obtained from a FrameNode onto the component tree.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci## Setting and Obtaining Rendering-related Properties
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ciIn **RenderNode**, you can set rendering-related properties, such as **backgroundColor**, **clipToFrame**, and **opacity**. For details about the supported attributes, see [RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md#rendernode).
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci> **NOTE**
28e41f4b71Sopenharmony_ci> 
29e41f4b71Sopenharmony_ci> - The properties obtained from a query in **RenderNode** are the values that have been explicitly set.
30e41f4b71Sopenharmony_ci> 
31e41f4b71Sopenharmony_ci> - If no parameters are provided or if the provided parameters are invalid, the query will return the default values.
32e41f4b71Sopenharmony_ci>
33e41f4b71Sopenharmony_ci> - Avoid modifying RenderNodes in a BuilderNode.
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci```ts
36e41f4b71Sopenharmony_ciimport { FrameNode, NodeController, RenderNode } from '@kit.ArkUI';
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciconst renderNode = new RenderNode();
39e41f4b71Sopenharmony_cirenderNode.frame = { x: 0, y: 0, width: 200, height: 350 };
40e41f4b71Sopenharmony_cirenderNode.backgroundColor = 0xffff0000;
41e41f4b71Sopenharmony_cifor (let i = 0; i < 5; i++) {
42e41f4b71Sopenharmony_ci  const node = new RenderNode();
43e41f4b71Sopenharmony_ci  // Set the frame size of the node.
44e41f4b71Sopenharmony_ci  node.frame = { x: 10, y: 10 + 60 * i, width: 50, height: 50 };
45e41f4b71Sopenharmony_ci  // Set the background color of the node.
46e41f4b71Sopenharmony_ci  node.backgroundColor = 0xff00ff00;
47e41f4b71Sopenharmony_ci  // Mount the new node to the RenderNode.
48e41f4b71Sopenharmony_ci  renderNode.appendChild(node);
49e41f4b71Sopenharmony_ci}
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ciclass MyNodeController extends NodeController {
52e41f4b71Sopenharmony_ci  private rootNode: FrameNode | null = null;
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci  makeNode(uiContext: UIContext): FrameNode | null {
55e41f4b71Sopenharmony_ci    this.rootNode = new FrameNode(uiContext);
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci    const rootRenderNode = this.rootNode?.getRenderNode();
58e41f4b71Sopenharmony_ci    if (rootRenderNode) {
59e41f4b71Sopenharmony_ci      rootRenderNode.appendChild(renderNode);
60e41f4b71Sopenharmony_ci    }
61e41f4b71Sopenharmony_ci    return this.rootNode;
62e41f4b71Sopenharmony_ci  }
63e41f4b71Sopenharmony_ci}
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci@Entry
66e41f4b71Sopenharmony_ci@Component
67e41f4b71Sopenharmony_cistruct Index {
68e41f4b71Sopenharmony_ci  private myNodeController: MyNodeController = new MyNodeController();
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci  build() {
71e41f4b71Sopenharmony_ci    Row() {
72e41f4b71Sopenharmony_ci      NodeContainer(this.myNodeController)
73e41f4b71Sopenharmony_ci        .width(200)
74e41f4b71Sopenharmony_ci        .height(350)
75e41f4b71Sopenharmony_ci      Button('getNextSibling')
76e41f4b71Sopenharmony_ci        .onClick(() => {
77e41f4b71Sopenharmony_ci          const child = renderNode.getChild(1);
78e41f4b71Sopenharmony_ci          const nextSibling = child!.getNextSibling()
79e41f4b71Sopenharmony_ci          if (child === null || nextSibling === null) {
80e41f4b71Sopenharmony_ci            console.log('the child or nextChild is null');
81e41f4b71Sopenharmony_ci          } else {
82e41f4b71Sopenharmony_ci            // Obtain the position of the child node.
83e41f4b71Sopenharmony_ci            console.log(`the position of child is x: ${child.position.x}, y: ${child.position.y}, ` +
84e41f4b71Sopenharmony_ci            `the position of nextSibling is x: ${nextSibling.position.x}, y: ${nextSibling.position.y}`);
85e41f4b71Sopenharmony_ci          }
86e41f4b71Sopenharmony_ci        })
87e41f4b71Sopenharmony_ci    }
88e41f4b71Sopenharmony_ci  }
89e41f4b71Sopenharmony_ci}
90e41f4b71Sopenharmony_ci```
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci## Using Custom Drawing
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ciOverride the [draw](../reference/apis-arkui/js-apis-arkui-renderNode.md#draw) API in **RenderNode** to customize the drawing content and use the [invalidate](../reference/apis-arkui/js-apis-arkui-renderNode.md#invalidate) API to manually trigger a redraw of the node.
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci> **NOTE**
97e41f4b71Sopenharmony_ci> 
98e41f4b71Sopenharmony_ci> - Triggering multiple **invalidate** calls at once will only result in a single redraw.
99e41f4b71Sopenharmony_ci> 
100e41f4b71Sopenharmony_ci> - Custom drawing can be implemented by calling ArkTS APIs or Node-APIs.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci**ArkTS API sample code**
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci```ts
105e41f4b71Sopenharmony_ciimport { FrameNode, NodeController, RenderNode } from '@kit.ArkUI';
106e41f4b71Sopenharmony_ciimport { drawing } from '@kit.ArkGraphics2D';
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ciclass MyRenderNode extends RenderNode {
109e41f4b71Sopenharmony_ci  draw(context: DrawContext) {
110e41f4b71Sopenharmony_ci    // Obtain the canvas object.
111e41f4b71Sopenharmony_ci    const canvas = context.canvas;
112e41f4b71Sopenharmony_ci    // Create a brush.
113e41f4b71Sopenharmony_ci    const brush = new drawing.Brush();
114e41f4b71Sopenharmony_ci    // Set the brush color.
115e41f4b71Sopenharmony_ci    brush.setColor({ alpha: 255, red: 255, green: 0, blue: 0 });
116e41f4b71Sopenharmony_ci    canvas.attachBrush(brush);
117e41f4b71Sopenharmony_ci    // Draw a rectangle.
118e41f4b71Sopenharmony_ci    canvas.drawRect({ left: 0, right: 200, top: 0, bottom: 200 });
119e41f4b71Sopenharmony_ci    canvas.detachBrush();
120e41f4b71Sopenharmony_ci  }
121e41f4b71Sopenharmony_ci}
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ciconst renderNode = new MyRenderNode();
124e41f4b71Sopenharmony_cirenderNode.frame = { x: 0, y: 0, width: 300, height: 300 };
125e41f4b71Sopenharmony_cirenderNode.backgroundColor = 0xff0000ff;
126e41f4b71Sopenharmony_cirenderNode.opacity = 0.5;
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ciclass MyNodeController extends NodeController {
129e41f4b71Sopenharmony_ci  private rootNode: FrameNode | null = null;
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci  makeNode(uiContext: UIContext): FrameNode | null {
132e41f4b71Sopenharmony_ci    this.rootNode = new FrameNode(uiContext);
133e41f4b71Sopenharmony_ci
134e41f4b71Sopenharmony_ci    const rootRenderNode = this.rootNode?.getRenderNode();
135e41f4b71Sopenharmony_ci    if (rootRenderNode !== null) {
136e41f4b71Sopenharmony_ci      rootRenderNode.frame = { x: 0, y: 0, width: 500, height: 500 }
137e41f4b71Sopenharmony_ci      rootRenderNode.appendChild(renderNode);
138e41f4b71Sopenharmony_ci    }
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ci    return this.rootNode;
141e41f4b71Sopenharmony_ci  }
142e41f4b71Sopenharmony_ci}
143e41f4b71Sopenharmony_ci
144e41f4b71Sopenharmony_ci@Entry
145e41f4b71Sopenharmony_ci@Component
146e41f4b71Sopenharmony_cistruct Index {
147e41f4b71Sopenharmony_ci  private myNodeController: MyNodeController = new MyNodeController();
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci  build() {
150e41f4b71Sopenharmony_ci    Column() {
151e41f4b71Sopenharmony_ci      NodeContainer(this.myNodeController)
152e41f4b71Sopenharmony_ci        .width('100%')
153e41f4b71Sopenharmony_ci      Button('Invalidate')
154e41f4b71Sopenharmony_ci        .onClick(() => {
155e41f4b71Sopenharmony_ci          // Triggering multiple invalidate calls at once will only result in a single redraw.
156e41f4b71Sopenharmony_ci          renderNode.invalidate();
157e41f4b71Sopenharmony_ci          renderNode.invalidate();
158e41f4b71Sopenharmony_ci        })
159e41f4b71Sopenharmony_ci    }
160e41f4b71Sopenharmony_ci  }
161e41f4b71Sopenharmony_ci}
162e41f4b71Sopenharmony_ci```
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci**Node-API sample code**
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ciThe C++ side can obtain the canvas through the Node-API and perform subsequent custom drawing operations.
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci```c++
169e41f4b71Sopenharmony_ci// native_bridge.cpp
170e41f4b71Sopenharmony_ci#include "napi/native_api.h"
171e41f4b71Sopenharmony_ci#include <native_drawing/drawing_canvas.h>
172e41f4b71Sopenharmony_ci#include <native_drawing/drawing_color.h>
173e41f4b71Sopenharmony_ci#include <native_drawing/drawing_path.h>
174e41f4b71Sopenharmony_ci#include <native_drawing/drawing_pen.h>
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_cistatic napi_value OnDraw(napi_env env, napi_callback_info info)
177e41f4b71Sopenharmony_ci{
178e41f4b71Sopenharmony_ci    size_t argc = 4;
179e41f4b71Sopenharmony_ci    napi_value args[4] = { nullptr };
180e41f4b71Sopenharmony_ci    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci    int32_t id;
183e41f4b71Sopenharmony_ci    napi_get_value_int32(env, args[0], &id);
184e41f4b71Sopenharmony_ci    
185e41f4b71Sopenharmony_ci    // Obtain the pointer to the canvas.
186e41f4b71Sopenharmony_ci    void* temp = nullptr;
187e41f4b71Sopenharmony_ci    napi_unwrap(env, args[1], &temp);
188e41f4b71Sopenharmony_ci    OH_Drawing_Canvas *canvas = reinterpret_cast<OH_Drawing_Canvas*>(temp);
189e41f4b71Sopenharmony_ci    
190e41f4b71Sopenharmony_ci    // Obtain the canvas width.
191e41f4b71Sopenharmony_ci    int32_t width;
192e41f4b71Sopenharmony_ci    napi_get_value_int32(env, args[2], &width);
193e41f4b71Sopenharmony_ci    
194e41f4b71Sopenharmony_ci    // Obtain the canvas height.
195e41f4b71Sopenharmony_ci    int32_t height;
196e41f4b71Sopenharmony_ci    napi_get_value_int32(env, args[3], &height);
197e41f4b71Sopenharmony_ci    
198e41f4b71Sopenharmony_ci    // Pass in information such as the canvas, height, and width to the drawing API for custom drawing.
199e41f4b71Sopenharmony_ci    auto path = OH_Drawing_PathCreate();
200e41f4b71Sopenharmony_ci    OH_Drawing_PathMoveTo(path, width / 4, height / 4);
201e41f4b71Sopenharmony_ci    OH_Drawing_PathLineTo(path, width * 3 / 4, height / 4);
202e41f4b71Sopenharmony_ci    OH_Drawing_PathLineTo(path, width * 3 / 4, height * 3 / 4);
203e41f4b71Sopenharmony_ci    OH_Drawing_PathLineTo(path, width / 4, height * 3 / 4);
204e41f4b71Sopenharmony_ci    OH_Drawing_PathLineTo(path, width / 4, height / 4);
205e41f4b71Sopenharmony_ci    OH_Drawing_PathClose(path);
206e41f4b71Sopenharmony_ci    
207e41f4b71Sopenharmony_ci    auto pen = OH_Drawing_PenCreate();
208e41f4b71Sopenharmony_ci    OH_Drawing_PenSetWidth(pen, 10);
209e41f4b71Sopenharmony_ci    OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
210e41f4b71Sopenharmony_ci    OH_Drawing_CanvasAttachPen(canvas, pen);
211e41f4b71Sopenharmony_ci    
212e41f4b71Sopenharmony_ci    OH_Drawing_CanvasDrawPath(canvas, path);
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci    return nullptr;
215e41f4b71Sopenharmony_ci}
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ciEXTERN_C_START
218e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports)
219e41f4b71Sopenharmony_ci{
220e41f4b71Sopenharmony_ci    napi_property_descriptor desc[] = {
221e41f4b71Sopenharmony_ci        { "nativeOnDraw", nullptr, OnDraw, nullptr, nullptr, nullptr, napi_default, nullptr }
222e41f4b71Sopenharmony_ci    };
223e41f4b71Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
224e41f4b71Sopenharmony_ci    return exports;
225e41f4b71Sopenharmony_ci}
226e41f4b71Sopenharmony_ciEXTERN_C_END
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_cistatic napi_module demoModule = {
229e41f4b71Sopenharmony_ci    .nm_version =1,
230e41f4b71Sopenharmony_ci    .nm_flags = 0,
231e41f4b71Sopenharmony_ci    .nm_filename = nullptr,
232e41f4b71Sopenharmony_ci    .nm_register_func = Init,
233e41f4b71Sopenharmony_ci    .nm_modname = "entry",
234e41f4b71Sopenharmony_ci    .nm_priv = ((void*)0),
235e41f4b71Sopenharmony_ci    .reserved = { 0 },
236e41f4b71Sopenharmony_ci};
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void)
239e41f4b71Sopenharmony_ci{
240e41f4b71Sopenharmony_ci    napi_module_register(&demoModule);
241e41f4b71Sopenharmony_ci}
242e41f4b71Sopenharmony_ci```
243e41f4b71Sopenharmony_ci
244e41f4b71Sopenharmony_ciAdd the following content to the **src/main/cpp/CMakeLists.txt** file of the project:
245e41f4b71Sopenharmony_ci```cmake
246e41f4b71Sopenharmony_ci# the minimum version of CMake.
247e41f4b71Sopenharmony_cicmake_minimum_required(VERSION 3.4.1)
248e41f4b71Sopenharmony_ciproject(NapiTest)
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ciset(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
251e41f4b71Sopenharmony_ci
252e41f4b71Sopenharmony_ciinclude_directories(${NATIVERENDER_ROOT_PATH}
253e41f4b71Sopenharmony_ci                    ${NATIVERENDER_ROOT_PATH}/include)
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ciadd_library(entry SHARED native_bridge.cpp)
256e41f4b71Sopenharmony_citarget_link_libraries(entry PUBLIC libace_napi.z.so)
257e41f4b71Sopenharmony_citarget_link_libraries(entry PUBLIC libace_ndk.z.so)
258e41f4b71Sopenharmony_citarget_link_libraries(entry PUBLIC libnative_drawing.so)
259e41f4b71Sopenharmony_ci```
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ciAdd 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:
262e41f4b71Sopenharmony_ci```ts
263e41f4b71Sopenharmony_ciimport { DrawContext } from '@kit.ArkUI'
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ciexport const nativeOnDraw: (id: number, context: DrawContext, width: number, height: number) => number;
266e41f4b71Sopenharmony_ci```
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ciCode in ArkTS:
269e41f4b71Sopenharmony_ci
270e41f4b71Sopenharmony_ci```ts
271e41f4b71Sopenharmony_ci// Index.ets
272e41f4b71Sopenharmony_ciimport bridge from "libentry.so" // This .so file is written and generated by Node-API.
273e41f4b71Sopenharmony_ciimport { DrawContext, FrameNode, NodeController, RenderNode } from '@kit.ArkUI'
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ciclass MyRenderNode extends RenderNode {
276e41f4b71Sopenharmony_ci  draw(context: DrawContext) {
277e41f4b71Sopenharmony_ci    // The width and height in the context need to be converted from vp to px.
278e41f4b71Sopenharmony_ci    bridge.nativeOnDraw(0, context, vp2px(context.size.height), vp2px(context.size.width));
279e41f4b71Sopenharmony_ci  }
280e41f4b71Sopenharmony_ci}
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ciclass MyNodeController extends NodeController {
283e41f4b71Sopenharmony_ci  private rootNode: FrameNode | null = null;
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci  makeNode(uiContext: UIContext): FrameNode | null {
286e41f4b71Sopenharmony_ci    this.rootNode = new FrameNode(uiContext);
287e41f4b71Sopenharmony_ci
288e41f4b71Sopenharmony_ci    const rootRenderNode = this.rootNode.getRenderNode();
289e41f4b71Sopenharmony_ci    if (rootRenderNode !== null) {
290e41f4b71Sopenharmony_ci      const renderNode = new MyRenderNode();
291e41f4b71Sopenharmony_ci      renderNode.size = { width: 100, height: 100 }
292e41f4b71Sopenharmony_ci      rootRenderNode.appendChild(renderNode);
293e41f4b71Sopenharmony_ci    }
294e41f4b71Sopenharmony_ci    return this.rootNode;
295e41f4b71Sopenharmony_ci  }
296e41f4b71Sopenharmony_ci}
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci@Entry
299e41f4b71Sopenharmony_ci@Component
300e41f4b71Sopenharmony_cistruct Index {
301e41f4b71Sopenharmony_ci  private myNodeController: MyNodeController = new MyNodeController();
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ci  build() {
304e41f4b71Sopenharmony_ci    Row() {
305e41f4b71Sopenharmony_ci      NodeContainer(this.myNodeController)
306e41f4b71Sopenharmony_ci    }
307e41f4b71Sopenharmony_ci  }
308e41f4b71Sopenharmony_ci}
309e41f4b71Sopenharmony_ci```
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci## Setting the Label
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ciYou can use the [label](../reference/apis-arkui/js-apis-arkui-renderNode.md#label12) API to set label information for **FrameNode**, which makes it easier to identify nodes in the node Inspector.
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci```ts
316e41f4b71Sopenharmony_ciimport {  RenderNode, FrameNode, NodeController, UIContext } from '@kit.ArkUI';
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ciclass MyNodeController extends NodeController {
319e41f4b71Sopenharmony_ci  private rootNode: FrameNode | null = null;
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ci  makeNode(uiContext: UIContext): FrameNode | null {
322e41f4b71Sopenharmony_ci    this.rootNode = new FrameNode(uiContext);
323e41f4b71Sopenharmony_ci    const renderNode: RenderNode | null = this.rootNode.getRenderNode();
324e41f4b71Sopenharmony_ci    if (renderNode !== null) {
325e41f4b71Sopenharmony_ci      const renderChildNode: RenderNode = new RenderNode();
326e41f4b71Sopenharmony_ci      renderChildNode.frame = { x: 0, y: 0, width: 100, height: 100 };
327e41f4b71Sopenharmony_ci      renderChildNode.backgroundColor = 0xffff0000;
328e41f4b71Sopenharmony_ci      renderChildNode.label = 'customRenderChildNode';
329e41f4b71Sopenharmony_ci      console.log('label:', renderChildNode.label);
330e41f4b71Sopenharmony_ci      renderNode.appendChild(renderChildNode);
331e41f4b71Sopenharmony_ci    }
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ci    return this.rootNode;
334e41f4b71Sopenharmony_ci  }
335e41f4b71Sopenharmony_ci}
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ci@Entry
338e41f4b71Sopenharmony_ci@Component
339e41f4b71Sopenharmony_cistruct Index {
340e41f4b71Sopenharmony_ci  private myNodeController: MyNodeController = new MyNodeController();
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ci  build() {
343e41f4b71Sopenharmony_ci    Column() {
344e41f4b71Sopenharmony_ci      NodeContainer(this.myNodeController)
345e41f4b71Sopenharmony_ci        .width(300)
346e41f4b71Sopenharmony_ci        .height(700)
347e41f4b71Sopenharmony_ci        .backgroundColor(Color.Gray)
348e41f4b71Sopenharmony_ci    }
349e41f4b71Sopenharmony_ci  }
350e41f4b71Sopenharmony_ci}
351e41f4b71Sopenharmony_ci```
352