• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 画布的获取与绘制结果的显示(ArkTS)
2
3<!--Kit: ArkGraphics 2D-->
4<!--Subsystem: Graphics-->
5<!--Owner: @hangmengxin-->
6<!--Designer: @wangyanglan-->
7<!--Tester: @nobuggers-->
8<!--Adviser: @ge-yafang-->
9
10
11## 场景介绍
12
13Canvas即画布,提供绘制基本图形的能力,用于在屏幕上绘制图形和处理图形。开发者可以通过Canvas实现自定义的绘图效果,增强应用的用户体验。
14
15
16Canvas是图形绘制的核心,本章中提到的所有绘制操作(包括基本图形的绘制、文字的绘制、图片的绘制、图形变换等)都是基于Canvas的。
17
18
19目前ArkTS有两种获取Canvas的方式:[获取可直接显示的Canvas画布](#获取可直接显示的canvas画布)、[获取离屏的Canvas](#离屏canvas画布的获取与显示),前者在调用绘制接口之后无需进行额外的操作即可完成绘制结果的上屏显示,而后者需要依靠已有的显示手段来显示绘制结果。
20
21
22## 获取可直接显示的Canvas画布
23
24通过[RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md)获取可直接上屏显示的Canvas画布。
25
261. 添加自定义RenderNode。
27
282. 添加自定义[NodeController](../reference/apis-arkui/js-apis-arkui-nodeController.md)。
29
303. 重写自定义RenderNode的[draw()](../reference//apis-arkui/js-apis-arkui-renderNode.md#draw)函数,获取Canvas进行自定义的绘制操作,即本章下文中的内容。
31
324. 将自定义NodeController进行显示。
33
34```ts
35import { UIContext, NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI';
36import { drawing } from '@kit.ArkGraphics2D';
37
38// 1. 自定义RenderNode
39export class MyRenderNode extends RenderNode {
40  async draw(context: DrawContext) {
41    const canvas = context.canvas;
42    // 3. 自定义的绘制相关操作
43    const brush = new drawing.Brush();
44    brush.setColor({red: 255, blue: 0, green: 0, alpha: 255});
45    canvas.attachBrush(brush);
46    canvas.drawRect({left: 0, right: 300, top: 0, bottom: 300});
47  }
48}
49
50// 2. 自定义NodeController
51export class MyNodeController extends NodeController {
52  private rootNode: FrameNode | null = null;
53  myRenderNode = new MyRenderNode();
54
55  makeNode(uiContext: UIContext): FrameNode {
56    this.rootNode = new FrameNode(uiContext);
57    if (this.rootNode === null) {
58      return this.rootNode;
59    }
60
61    const renderNode = this.rootNode.getRenderNode();
62    if (renderNode !== null) {
63      this.myRenderNode.backgroundColor = 0xffffffff;
64      this.myRenderNode.frame = { x: 0, y: 0, width: 4800, height: 4800 };
65      this.myRenderNode.pivot = { x: 0.2, y: 0.8 };
66      this.myRenderNode.scale = { x: 1, y: 1 };
67      renderNode.appendChild(this.myRenderNode);
68      renderNode.clipToFrame = true;
69    }
70    return this.rootNode;
71  }
72}
73
74@Entry
75@Component
76struct RenderTest {
77  @State message: string = 'hello'
78  build() {
79    Row() {
80      Column() {
81        // 4. 将自定义NodeController进行显示
82        NodeContainer(new MyNodeController())
83          .width('100%')
84      }
85      .width('100%')
86      .height('80%')
87    }
88    .height('100%')
89  }
90}
91```
92
93
94## 离屏Canvas画布的获取与显示
95
961. 添加自定义RenderNode。
97
982. 添加自定义[NodeController](../reference/apis-arkui/js-apis-arkui-nodeController.md)。
99
1003. 在MyNodeController的aboutToAppear()函数中创建PixelMap。
101
1024. 重写自定义RenderNode的[draw()](../reference//apis-arkui/js-apis-arkui-renderNode.md#draw)函数,在其中获取离屏Canvas进行绘制:
103
104   1. 利用3中创建的PixelMap构造离屏Canvas。
105   2. 对离屏Canvas进行自定义的绘制操作。
106   3. 将离屏Canvas的绘制结果交给RenderNode。
107
1085. 将自定义NodeController进行显示。
109
110```ts
111import { UIContext, NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI';
112import { image } from '@kit.ImageKit';
113import { taskpool } from '@kit.ArkTS';
114import { drawing } from '@kit.ArkGraphics2D';
115
116// 1. 自定义RenderNode
117export class MyRenderNode extends RenderNode {
118  pixelMap: image.PixelMap | null = null;
119  setPixelMap(pixelMap: image.PixelMap) {
120    this.pixelMap = pixelMap;
121  }
122
123  async draw(context: DrawContext) {
124    const canvas = context.canvas;
125    if (this.pixelMap != null) {
126      // 4.1 利用3中创建的PixelMap构造离屏Canvas
127      const canvas_ = new drawing.Canvas(this.pixelMap);
128
129      // 4.2 离屏绘制
130      const brush = new drawing.Brush();
131      brush.setColor({ alpha: 255, red: 255, green: 0, blue: 0 });
132      canvas_.attachBrush(brush);
133      canvas_.drawRect({left:0,right:100,top:0,bottom:100});
134
135      // 4.3 将离屏Canvas的绘制结果交给RenderNode
136      canvas.drawImage(this.pixelMap, 0, 0);
137    }
138  }
139}
140
141@Concurrent
142async function CreatePixelMapAsync() {
143  const color : ArrayBuffer = new ArrayBuffer(4000000);  // 4000000为需要创建的像素buffer大小,取值为:height * width *4
144  let opts : image.InitializationOptions = { editable: true, pixelFormat: 3, size: { height: 1000, width: 1000 } };
145  const pixel = await image.createPixelMap(color, opts);
146  return pixel;
147}
148
149// 2. 自定义NodeController
150export class MyNodeController extends NodeController {
151  private rootNode: FrameNode | null = null;
152  myRenderNode = new MyRenderNode();
153
154  // 3. 在MyNodeController的aboutToAppear中创建PixelMap
155  aboutToAppear(): void {
156    let task = new taskpool.Task(CreatePixelMapAsync);
157    taskpool.execute(task).then((pixel:Object)=>{
158      this.myRenderNode.setPixelMap(pixel as image.PixelMap);
159      this.myRenderNode.invalidate();
160    })
161  }
162
163  makeNode(uiContext: UIContext): FrameNode {
164    this.rootNode = new FrameNode(uiContext);
165    if (this.rootNode === null) {
166      return this.rootNode;
167    }
168
169    const renderNode = this.rootNode.getRenderNode();
170    if (renderNode !== null) {
171      this.myRenderNode.backgroundColor = 0xffffffff;
172      this.myRenderNode.frame = { x: 0, y: 0, width: 4800, height: 4800 };
173      this.myRenderNode.pivot = { x: 0.2, y: 0.8 };
174      this.myRenderNode.scale = { x: 1, y: 1 };
175      renderNode.appendChild(this.myRenderNode);
176      renderNode.clipToFrame = true;
177    }
178    return this.rootNode;
179  }
180}
181
182
183@Entry
184@Component
185struct RenderTest {
186  @State message: string = 'hello'
187  nodeController = new MyNodeController()
188
189  build() {
190    Row() {
191      Column() {
192        // 5. 将自定义NodeController进行显示
193        NodeContainer(this.nodeController)
194          .width('100%')
195      }
196      .width('100%')
197      .height('80%')
198    }
199    .height('100%')
200  }
201}
202```
203
204<!--RP1-->
205## 相关实例
206
207针对Drawing(ArkTS)的开发,有以下相关实例可供参考:
208
209- [ArkTSGraphicsDraw (API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/ArkTSGraphicsDraw)
210<!--RP1End-->